Страницы

Поиск по вопросам

Показаны сообщения с ярлыком oracle11g. Показать все сообщения
Показаны сообщения с ярлыком oracle11g. Показать все сообщения

вторник, 31 марта 2020 г.

Автодобавление текстовых партиций

#sql #oracle #plsql #oracle11g


Цель: Автоматическое добавление новых партиций при добавлении  нового текстового значения

Ситуация: Поступают записи, в одном поле которых есть повторяющееся текстовое значение.
На это поле в целевой для этих данных таблице создана партиция. В качестве значения
этого поля может прийти новое значение, которого нет в существующих партициях. Возникает
ошибка, связанная с отсутствие соответствующей секции. Списком эти партиции не сделать
так, как заранее не известны значения, которые могут поступать.

Вопрос: Можно ли для этого случая организовать автоматическое добавление необходимых
секций? Без триггера, только средствами организации таблицы.

Что то типа такого (выдуманный пример):

create table char_part
(
    id integer,
    txt varchar2(200)
)
partition by range (txt) interval (1) -- Проблема в автодобавлении нового текст. значения
(
    partition "abc" values less than ('abc'),
    partition "max" values less than (maxvalue) -- Для null - значений
)

    


Ответы

Ответ 1



TL;DR: В версии 11g это невозможно. Лучшее решение - перейти на 12c, так как в этой версии уже введено автоматическое лист секционирование. Можно решить задачу через секционирование по interval появившиеся в 11g. На основе бизнес требований надо продумать, как вычислqть колонку для секционирования. Как например, спроси у Тома. Предложение для задачи как в вопросе: create table char_part ( id integer, txt varchar2(200), txt# generated always as (coalesce (ora_hash (txt, power (2,20)-1), 0)) virtual ) partition by range (txt#) interval (1) ( partition "empty" values less than (0), partition "undef" values less than (1) ); insert into char_part (id, txt) select 1, 'ABC' from dual union all select 2, 'DEF' from dual union all select 3, 'ZZZ' from dual union all select 9, null from dual ; select table_name, partition_name, high_value from user_tab_partitions where table_name=upper('char_part') ; TABLE_NAME PARTITION_NAME HIGH_VALUE ---------- -------------------- ---------- CHAR_PART SYS_P1141 222410 CHAR_PART SYS_P1142 59915 CHAR_PART SYS_P1143 627928 CHAR_PART empty 0 CHAR_PART undef 1

Ответ 2



В версии 12.2 такое стало возможно. Для уже существующей таблицы ALTER TABLE char_part SET PARTITIONING AUTOMATIC;. При создании таблицы: ... PARTITION BY LIST (txt) AUTOMATIC (PARTITION part_abc VALUES ('ABC'), PARTITION part_def VALUES ('DEF')); Обратите внимание: не less than, а values, т.е. в таблице секционирование по списку, а не по диапазону значений, иначе с текстовыми данными смысл теряется. В примере также указано, что можно создать секции сразу, несмотря на автоматическое секционирование.

суббота, 21 марта 2020 г.

Какая максимальная длина идентификаторов и можно ли ее изменить?

#sql #oracle #plsql #oracle11g #oracle12c


Использую версию 11g и хотел бы давать имена длина которых более чем 30 символов.
Мне известно, что макс. длина в 11g только 30 символов:

create table tab (very_very_very_very_very_very_very_very_LongColumnName number)



  ORA-00972: identifier is too long


Возможно ли как-то изменить макс. длину? 

Какая макс. длина идентификаторов в версии 12c?
    


Ответы

Ответ 1



Имена объектов БД 11g, а также в версии 12cR1, ограничены 30 байтами (в single-byte кодировке это эквивалентно 30 символам). Можно ли это изменить? Нет, не существует способа измененить это, чтобы можно было пользоваться именами обьектов БД длиной более чем 30 байтов. Ограничение в 30 байт было впервые снято во втором выпуске 12c ( 12cR2), и если значение параметра инициаллизации COMPATIBLE установленно в 12.2 и выше, то макс. длина идентификаторов может быть до 128 байт. SQL> show parameters compat NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ compatible string 12.2.0 SQL> create table tab (very_very_very_very_very_very_very_very_LongColumnName number); Table TAB created. SQL> declare very_very_very_very_very_very_very_very_LongVariableName number; begin null; end; / PL/SQL procedure successfully completed. Источник ответа: @Nick Krasnov.

пятница, 28 февраля 2020 г.

Ошибка после установки на Ubuntu ORA-27101: shared memory realm does not exist

#база_данных #ubuntu #oracle #установка #oracle11g


SQL*PLUS выдаёт ошибку:


  ERROR:
      ORA-01034: ORACLE not available
      ORA-27101: shared memory realm does not exist
      Linux-x86_64 Error: 2: No such file or directory
      Process ID: 0
      Session ID: 0 Serial number: 0  


При старте БД:

sudo service oracle-xe start
Starting Oracle Net Listener.
Starting Oracle Database 11g Express Edition instance.
Failed to start Oracle Net Listener using /u01/app/oracle/product/11.2.0/xe/bin/tnslsnr
and Oracle Express Database using /u01/app/oracle/product/11.2.0/xe/bin/sqlplus.


Ставила по этой инструкции.
Но пропустила шаг: 

sudo rm -rf /dev/shm
sudo mkdir /dev/shm 


потому, что при простой замене имени каталога /dev/shm у меня пропал интернет. Просто
так удалять системные файлы, боязно. Теперь не могу удалить /dev/shm, т.к. он занят.
    


Ответы

Ответ 1



Сообщение об ошибке: ORA-27101: shared memory realm does not exist означает, что процесс (обычно Listener, sqlplus) не может подсоединиться к System Global Area (SGA). В основном это вызывают две причины: SGA действительно не существует, так как инстанция БД не стартовала. Стартуйте инстанцию БД под пользователeм oracle: $ echo startup|sqlplus / as sysdba Shared memory segment Id для подключения к SGA генерируется из значений переменных окружения: $ORACLE_SID + $ORACLE_HOME. Если эти значения не соответствуют тем, которые были использованы при запуске инстанции БД, то будет выше указанная ошибка, так как такого сегмента не существует. Проверьте переменные окружения: env | egrep -i "oracle_(sid|home)" Значения $ORACLE_SID + $ORACLE_HOME, которые были использованы при установке хранятся в /etc/oratab и устанавливаются так: export ORACLE_SID=orcl; . oraenv Например, если попытаться установить вручную и при этом ошибиться: $ echo exit|sqlplus -l user/pass Connected to: Oracle Database 11g Release 11.2.0.1.0 - Production $ ORACLE_HOME=$ORACLE_HOME/; test -d $ORACLE_HOME && echo "directory exists" # ------^ directory exists Всё хорошо, директория существует и sqlplus из неё будет вызываться, но незначащий слэш даст при подсчёте shmid другое значение: $ echo exit|sqlplus -l user/pass ERROR: ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist Linux Error: 2: No such file or directory

четверг, 13 февраля 2020 г.

Как получить из таблиц последнюю запись по сгенерированному идентификатору?

#sql #oracle #oracle11g


Как получить самую последнюю запись из таблицы?

Например, в таблице есть такие идентификаторы:

1
2
7
3
10
5


Последняя запись здесь с идентификатором 10.

Из известных составляющих выражения - это имя таблицы. При этом подразумеваем, что
поиск нужен по первому столбцу который Primary Key и хранит идентификаторы.

Иденитификатор для каждой таблицы создается триггером, который при вставке записи
формирует Id для этой записи. Имена колонок с идентификатором отличаются и заранее
неизвестны, поэтому запрос вообще не должен быть привязан к именам колонок.
Идентификаторы создаются последовательностями, где только CYCLE_FLAG=N.

Вот что я использую (меняю только имя таблицы):

select a.* from (
    select rownum rnum, MESSAGES.* 
    from MESSAGES
) a 
where rnum=(select count(1) from MESSAGES);


Пример работает и я получаю в ответ одну строку, которая иногда является записью
с самым последним Id в таблице, а в некоторых таблицах этот запрос не выдает последнию
 запись, как если бы первое поле таблицы не было отсортировано по порядку. 
    


Ответы

Ответ 1



Если только первая колонка содержит идентификатор, то надо так: select t.* from table_name t order by 1 desc fetch first row only; Для версий <12.1 (опробовано на 11.2.0.4) попробуйте так: with table_name as ( select to_number (trim (column_value)) id, 'item '||rownum name from xmltable ('1,2,7,3,10,5') ) -- здесь начинается запрос select * from ( select t.* from table_name t order by 1 desc ) where rownum = 1; Результат: ID NAME ---------- ----------- 10 item 5 PS Убедитесь, что используется опция NOCYCLE в генераторах последовательностей.

суббота, 11 января 2020 г.

Не удаляется ранее загруженная Java-библотека. (Ошибка: ORA-29537: класс или ресурс не могут быть созданы)

#java #sql #oracle #oracle11g


С помощью утилиты командной строки loadjava была загружена JAVA-библиотека в БД.
Команда с параметрами:

loadjava -jarsasdbobjects -resolve -verbose -thin -user login/pass@host:port:SID
"sqljdbc.jar"


Теперь я пытаюсь удалить эту библиотеку следующим образом:

dropjava -jarsasdbobjects -resolve -verbose -thin -user login/pass@host:port:SID
"sqljdbc.jar"


На что я получаю ошибку: 

dropping: class com/microsoft/sqlserver/jdbc/ActivityCorrelator
Error while dropping com/microsoft/sqlserver/jdbc/ActivityCorrelator
    ORA-29537: класс или ресурс не могут быть созданы или удалены напрямую


И так для каждого класса в этой библиотеке. 

Пробовал удалять с помощью dbms_java.dropjava() и через drop java class, но ошибка
была всё та же.

Нужно сказать, что библиотека, загруженная без параметра -jarsasdbobjects, удалялась
без проблем. 

Как мне правильно удалить библиотеку?
    


Ответы

Ответ 1



TL;DR: Полное сообщение об ошибке: $ oerr ora 29537 29537, 00000, "class or resource cannot be created or dropped directly" // *Cause: An attempt was made to create or drop a Java class or resource that // is known to result from compilation of an existing Java source object. // *Action: Act on the class or resource by acting on the source, or change // the source so that it no longer defines the class or resource. Нельзя создать или удалить Java класс, который является результатом компиляции уже существующего Java объекта с исходным кодом (object_type='JAVA SOURCE'). Простейший воиспроизводимый пример: $ echo "public class SomeClass { }" >SomeClass.java $ javac SomeClass.java $ jar -cvf SomeClass.jar SomeClass.class $ connstr="user/pass@dbserver/sevice" $ loadjava -u $connstr -r -v SomeClass.jar resolving: class SomeClass Classes Loaded: 1 $ dropjava -u $connstr -v SomeClass.jar dropping: class SomeClass Пока всё хорошо, но после: $ sqlplus -l -s $connstr <<+++ create or replace and compile java source named SomeClass as $(

суббота, 28 декабря 2019 г.

Как получить информация о сеансах работы с БД в которых есть незакрытые транзакции?

#sql #oracle #oracle11g


Как из представлений словаря данных (насколько понимаю, нужно обращаться к v$session
и v$transaction и делать выборку v$session.sid и v$session.username) получить информацию
обо всех сеансах работы с БД, в которых есть незакрытые транзакции? 

Например, через консоль и SQL*Plus в виде двух колонок - ид сеанса и имя пользователя.

Для определения незакрытых транзакций можно ли использовать ограничение v$transaction.flag=7811?
Например, так:

SELECT v$session.sid, v$session.username
FROM v$session, v$transaction
WHERE v$transaction.flag=7811;


Версия: Oracle Database 11g Release 2
    


Ответы

Ответ 1



Попробуйте так: select s.sid, s.serial#, s.username from v$transaction t inner join v$session s on t.addr = s.taddr ; no rows selected select 1 from t1 for update; select s.sid, s.serial#, s.username from v$transaction t inner join v$session s on t.addr = s.taddr ; SID SERIAL# USERNAME ---------- ---------- ---------- 34 55338 OE Следует учесть, что "незакрытые транзакции" не означает, что произошли изменения данных. В примере выше, например, запрос с for update ничего не изменил.

Ответ 2



@0xdb уже показал вам как посмотреть все транзакции. Иногда бывает полезным найти только тех пользователей и их сессии, которые блокируют какие либо объекты БД (таблицы, индексы и т.д.): set lines 200 pages 200 col inst_id for 99 col obj for a45 col lock_mode for a16 col blocker_sid_serial_sqlid for a45 col os_user_pid for a18 col machine for a30 break on blocker_sid_serial_sqlid skip page select l.inst_id as inst_id ,o.owner||'.'||o.object_name as obj ,case l.locked_mode when 0 then '0:none' when 1 then '1:null (NULL)' when 2 then '2:row-S (SS)' when 3 then '3:row-X (SX)' when 4 then '4:share (S)' when 5 then '5:S/Row-X (SSX)' when 6 then '6:exclusive (X)' else to_char(l.locked_mode) end as lock_mode ,l.oracle_username||' ('||s.sid||','||s.serial#||') ['||s.sql_id||']' as blocker_sid_serial_sqlid ,l.os_user_name||' ['||l.process||']' as os_user_pid ,s.machine from gv$locked_object l join dba_objects o on l.object_id = o.object_id join gv$session s on (s.sid = l.session_id and s.inst_id=l.inst_id) /* where o.owner like '&&OWNER.%' */ order by inst_id, blocker_sid_serial_sqlid, obj ;

понедельник, 23 декабря 2019 г.

Партиционирование уже существующей таблицы по дате с периодом 1 месяц

#sql #база_данных #oracle #oracle11g


Есть таблица +20 млн. записей за 2 года. Хочу ее партиционировать по дате, период
1 месяц. 

Офф. документацию смотрел и возникли вопросы:  


обязательно ли для паритициорирования пересоздавать таблицу?  
во всех примерах партиции создаются в ручную, например:    

PARTITION BY RANGE (time_id)INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
( PARTITION p0 VALUES LESS THAN (TO_DATE('1-1-2007', 'DD-MM-YYYY')),
  PARTITION p1 VALUES LESS THAN (TO_DATE('1-1-2008', 'DD-MM-YYYY')),
  PARTITION p2 VALUES LESS THAN (TO_DATE('1-7-2009', 'DD-MM-YYYY')),
  PARTITION p3 VALUES LESS THAN (TO_DATE('1-1-2010', 'DD-MM-YYYY')) );


, можно как-то автоматизировать этот процесс? 

    


Ответы

Ответ 1



обязательно ли для паритиционирования пересоздавать таблицу? Да, существующую не паритиционированную таблицу можно изменить начиная с 12.02. Создайте новую и импортируйте данные: create table ptab (id number, time_id date) partition by range (time_id) interval (numtoyminterval (1,'month')) ( partition partdef values less than (date'2000-01-01') ); партиции создаются вручную ... можно как-то автоматизировать этот процесс? Да, он уже автоматизирован. При создании таблицы надо создать как минимум только одну партицию, например, для заведомо старых дат (см. пример выше). Новые партиции добавятся при вставке автоматически и будут выглядеть где-то так: insert into ptab select rownum, date'2019-01-01'+rownum*30 from xmlTable ('1 to 3') ; exec dbms_stats.gather_table_stats (user, 'ptab') select partition_name, high_value, num_rows from user_tab_partitions where table_name = upper ('ptab') ; PARTITION_NAME HIGH_VALUE NUM_ROWS ---------------- ---------------------------------------------------------- ---------- PARTDEF TO_DATE(' 2000-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 0 SYS_P2227 TO_DATE(' 2019-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 1 SYS_P2228 TO_DATE(' 2019-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 1 SYS_P2229 TO_DATE(' 2019-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 1

суббота, 21 декабря 2019 г.

Select for update skip locked

#sql #oracle #oracle11g


Не могу понять, на английском читаю, кажется что ничего дополнительного не делает
не документированная фича skip locked в oracle 11g. 

Объясните, какие различия с этой фичей и без неё. 
    


Ответы

Ответ 1



Разница между запросоми с for update, с опцией skip locked и без неё, следующая: Без этой опции запрос не вернётся, если в выборке есть как минимум одна залоченная строчка. Т.е. он будет ожидать (wait) пoка трансакция не будет завершена в сессии, которая затребовала lock. Если добавить nowait, то он вернётся сразу же с исключением, которое может быть обработано. ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired С опцией skip locked он вернётcя сразу же и вернёт только незалоченные строчки или no rows selected, если таковых нет. И важное отличие для работы с курсорами - курсор с for update залочит все строки попадающие под условие курсора сразу при open, а если добавить skip locked, то только те строки будут залочены, которые были действительно считаны в fetch, что позволяет ограничить количество залоченых строк, или возвращать открытый курсор как результат функции с ещё не залочеными строками. Не документированной опция skip locked была в 9i и 10g версиях. С 11g она документирована, см. здесь. В этом ответе подрузумевается row lock, для exclusive table lock см. документацию. Небольшой пример. В первой сессии: SQL> select emp_id from emp where emp_id in (1, 2) for update; EMP_ID ---------- 1 2 2 rows selected. В другой сессии: SQL> select emp_id from emp where emp_id in (1, 2, 3) for update nowait; select emp_id from emp where emp_id in (1, 2, 3) for update nowait * ERROR at line 1: ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired SQL> select emp_id from emp where emp_id in (1, 2, 3) for update skip locked; EMP_ID ---------- 3 1 row selected. SQL> select emp_id from emp where emp_id in (1, 2, 3) for update; -- ждёт, пока в первой сессии не будет произведён откат

пятница, 7 июня 2019 г.

Распарсить XML с xmltype() с обработкой исключений в запросе

Есть запрос:
select nvl(extractvalue(xmltype(p.src_doc, 871), '//*:' || pd.name), extractvalue(xmltype(p.src_doc, 871), '*/*[local-name()="AdditionalData"][*[local-name()="Name"]="' || pd.name || '"][1]/*[local-name()="Value"]')) as elm_value, pd.guid as param_guid, p.guid as pmnt_guid from payments p join services s on p.srv_guid = s.guid join parameters_definitions pd on s.guid = pd.srv_guid left outer join pmnt_elements_values elm on p.guid = elm.pmnt_guid and pd.guid = elm.param_guid where elm.guid is null and p.src_doc is not null;
В принципе корректно парсит XML в clob, но иногда может возникнуть исключение:
ORA-31011: сбой разбора XML ORA-19202: Возникла ошибка при обработке XML LPX-00601: Invalid token in: '//*: PAYMENTTYPE ' 31011. 00000 - "XML parsing failed" *Cause: XML parser returned an error while trying to parse the document. *Action: Check if the document to be parsed is valid.
Проблема в том, что некоторые XML корректны, некоторые нет, таблица довольно объемна. Единого примера XML тоже дать не могу, так как все XML-документы корректны в рамках своей схемы, но по понятным причинам имеют разные значения в нодах, разные неймспейсы и атрибуты в некоторых нодах.
Можно ли как-то обойти/проигнорировать/обработать исключения разбора XML? Можно ли хотя бы как-то получить понимание где конкретно и на чем разваливается парсер?
Версия: Oracle Database 11g Enterprise Edition.


Ответ

Надо обернуть всю логику по разбору XML в функцию, которая обработает исключения и запишет полную информацию об ошибках, например, в таблицу. Как-то так:
create table parseErrors (guid raw (16), errm varchar2 (4000), created timestamp);
create or replace function myXmlParser (docGuid raw, doc clob) return varchar2 is procedure saveParseError (guid raw, errm varchar2) is pragma autonomous_transaction; begin insert into parseErrors values (guid, errm, systimestamp); commit; end ; begin -- **здесь необходимая логика, в которой может возникнуть ошибка** return xmlType (doc).getStringVal (); exception when others then saveParseError (docGuid, sqlerrm||chr(10)||sys.dbms_utility.format_error_backtrace()); return 'errorneous'; end myXmlParser; /
Выборка для теста (вместо sys_guid() должна быть колонка с GUID из запроса):
select myXmlParser (sys_guid(), 'some data') from dual union all select myXmlParser (sys_guid(), 'illegal XML syntax') from dual ;
выведет:
RESULT ------------------------ some data errorneous
Kакие были ошибки:
set lines 999 col errm for a40 wrapp select * from parseErrors;
GUID ERRM CREATED -------------------------------- ---------------------------------------- ----------------------------- 7106268B980F02D3E0530A01A8C04FBB ORA-31011: XML parsing failed 2018-07-15 12:32:41,204757000 ORA-06512: at "SYS.XMLTYPE", line 272 ORA-06512: at "DB.MYXMLPARSER", line 10

PS В вопросе мало информации по локализации причины ошибки, но думаю ссылки на похожие топики тут и тут будут полезны.

пятница, 15 февраля 2019 г.

Автодобавление текстовых партиций

Цель: Автоматическое добавление новых партиций при добавлении нового текстового значения
Ситуация: Поступают записи, в одном поле которых есть повторяющееся текстовое значение. На это поле в целевой для этих данных таблице создана партиция. В качестве значения этого поля может прийти новое значение, которого нет в существующих партициях. Возникает ошибка, связанная с отсутствие соответствующей секции. Списком эти партиции не сделать так, как заранее не известны значения, которые могут поступать.
Вопрос: Можно ли для этого случая организовать автоматическое добавление необходимых секций? Без триггера, только средствами организации таблицы.
Что то типа такого (выдуманный пример):
create table char_part ( id integer, txt varchar2(200) ) partition by range (txt) interval (1) -- Проблема в автодобавлении нового текст. значения ( partition "abc" values less than ('abc'), partition "max" values less than (maxvalue) -- Для null - значений )


Ответ

TL;DR: В версии 11g это невозможно. Лучшее решение - перейти на 12c, так как в этой версии уже введено автоматическое лист секционирование.

Можно решить задачу через секционирование по interval появившиеся в 11g. На основе бизнес требований надо продумать, как вычислqть колонку для секционирования. Как например, спроси у Тома.
Предложение для задачи как в вопросе:
create table char_part ( id integer, txt varchar2(200), txt# generated always as (coalesce (ora_hash (txt, power (2,20)-1), 0)) virtual ) partition by range (txt#) interval (1) ( partition "empty" values less than (0), partition "undef" values less than (1) );
insert into char_part (id, txt) select 1, 'ABC' from dual union all select 2, 'DEF' from dual union all select 3, 'ZZZ' from dual union all select 9, null from dual ;
select table_name, partition_name, high_value from user_tab_partitions where table_name=upper('char_part') ;
TABLE_NAME PARTITION_NAME HIGH_VALUE ---------- -------------------- ---------- CHAR_PART SYS_P1141 222410 CHAR_PART SYS_P1142 59915 CHAR_PART SYS_P1143 627928 CHAR_PART empty 0 CHAR_PART undef 1

вторник, 5 февраля 2019 г.

Ошибка после установки на Ubuntu ORA-27101: shared memory realm does not exist

SQL*PLUS выдаёт ошибку:
ERROR: ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist Linux-x86_64 Error: 2: No such file or directory Process ID: 0 Session ID: 0 Serial number: 0
При старте БД:
sudo service oracle-xe start Starting Oracle Net Listener. Starting Oracle Database 11g Express Edition instance. Failed to start Oracle Net Listener using /u01/app/oracle/product/11.2.0/xe/bin/tnslsnr and Oracle Express Database using /u01/app/oracle/product/11.2.0/xe/bin/sqlplus.
Ставила по этой инструкции Но пропустила шаг:
sudo rm -rf /dev/shm sudo mkdir /dev/shm
потому, что при простой замене имени каталога /dev/shm у меня пропал интернет. Просто так удалять системные файлы, боязно. Теперь не могу удалить /dev/shm, т.к. он занят.


Ответ

Сообщение об ошибке:
ORA-27101: shared memory realm does not exist
означает, что процесс (обычно listener, sqlplus) не может подсоединится к System Global Area (SGA).
В основном две причины:
SGA действительно не существует, так как инстанция БД не стартовала. Стартуйте инстанцию БД под пользователeм oracle
$ echo startup|sqlplus / as sysdba Shared memory segment Id для подключения к SGA генерируется из значений переменных окружения: $ORACLE_SID + $ORACLE_HOME. Если эти значения не соответствуют тем, которые были использованы при запуске инстанции БД, то будет выше указаная ошибка, так как такого сегмента не существует. Проверте переменные окружения:
env | egrep -i "oracle_(sid|home)"
Значения $ORACLE_SID + $ORACLE_HOME, которые были использованы при установке хранятся в /etc/oratab и устанавливаются так:
export ORACLE_SID=orcl; . oraenv
Например, если попытаться установить вручную и ошибиться:
$ echo exit|sqlplus -l user/pass
Connected to: Oracle Database 11g Release 11.2.0.1.0 - Production
$ ORACLE_HOME=$ORACLE_HOME/; test -d $ORACLE_HOME && echo "directory exists" directory exists
Всё хорошо, директория существует и sqlplus из неё будет вызываться, но незначащий слэш даст при подсчёте shmid другое значение:
$ echo exit|sqlplus -l user/pass
ERROR: ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist Linux Error: 2: No such file or directory