Направление Oracle  
  Oracle FAQ  


Настоящие материалы являются авторскими, права автора защищены Законами РФ и международными соглашениями. Для использования настоящих материалов вам необходимо ознакомиться и полностью принять лицензионное соглашение. В случае, если вы не принимаете настоящее лицензионное соглашение полностью, вы не имеете права пользоваться настоящими материалами


Данный раздел содержит обзорные ответы на вопросы и подробные ответы на относительно мелкие вопросы относилельно Oracle. Почему я не зажимаю знания, как не раз встречавшиеся коллеги ? Потому что между знать и пройти на практике есть большая разница. Потому что это всегда доступная шпаргалка, которую я перерабатываю и обновляю, и пользуются ей сотрудники уже нескольких команд, с которыми я работал. Так проще. Поточу что, чтобы приходило - нужно отдавать, этот Закон проверен на практике не раз по разным темам. Ну и чтобы идти дальше, нужно опустошать ёмкости ...

В то же время нужно понимать, что в раздел этот дописывались разные статьи с 8 версии СУБД, и что то может быть неактуальным или устаревшим

акцент - выделенные статьи

акцент - технологии

акцент - утилиты

акцент - операции мониторинга СУБД

акцент - операции оптимизации прикладного горизонта

акцент - операции административные с СУБД

акцент - операции административные с БД

акцент - операции административные с объектами

акцент - разное


Что такое FRA ?

[v.10+] FRA (Fast Recovery Area) является выделенной областью, например каталогом, а лучше партицией на отдельных шпинделях, и содержит файлы для бэкапа и восстановления, а именно контрольный файл, оперативные и архивные журналы, журналы flashback и бэкапы RMAN. Файлы делятся на постоянные (оперативные журналы и контрольные файлы) и временные (остальные) - в первую очередь это бэкапы, если они идут не на ленту, и flashback журналы. Последние при отсутствии места в FRA могут и удаляться. Место во временной части FRA балансируется между архивными журналами и бэкапами для удовлетворения политик хранения и прочими файлами, которые могут быть темой для удаления

Включается FRA параметрами DB_RECOVERY_FILE_DEST_SIZE (этот параметр нужно установить первым и важно, что около 10% уходит на служебную информацию) и DB_RECOVERY_FILE_DEST (файловая система или ASM, но не raw файлы) без перезагрузки базы. Также есть необязательный параметр DB_FLASHBACK_RETENTION_TARGET и команда ALTER DATABASE FLASHBACK ON - описано в вопросе Как управлять FLASHBACK и точками восстановления ?. В конфигурации с активированными архивными журналами параметр LOG_ARCHIVE_DEST_1 может указывать как и раньше на специально созданный каталог, а может указывать на FRA. Для этого значение USE_DB_RECOVERY_FILE_DEST

-- включение FRA
ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE = 500G;
ALTER SYSTEM SET DB_RECOVERY_FILE_DEST = '/oracle/flash_recovery_area';
-- опционально
ALTER SYSTEM SET DB_FLASHBACK_RETENTION_TARGET=4320;

-- отключения FRA
1. ALTER DATABASE FLASHBACK OFF;
2. если LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST'
   тогда ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=/ORACLE/DBS/';
3. ALTER SYSTEM SET DB_RECOVERY_FILE_DEST=''; 

RMAN использует FRA, если FRA активирован, для этого нужно пропустить указание имён и опцию FORMAT команд RMAN


Как управлять FLASHBACK и точками восстановления ?

[v.10+] В СУБД Oracle есть две известные технологии с термином flashback - один, довольно старый, позволяет делать запросы к старым версиям данных, вытаскивая их из undo. Если UNDO не хватает - данные вы не получите, а получите известную ошибку ORA-1555 snapshot too old. Пример запроса этой технологии: "SELECT * FROM test.test2 AS OF TIMESTAMP TO_DATE('2010-10-10 01:01:01','YYYY-MM-DD HH24:MI:SS') ;". Вторая технлогия позволяет откатить всю БД на точку в прошлом, причём такая точка может быть гарантированной. В FRA при этом создаются журналы, храняшие старые версии данных с разрывами - это позволяет экономить место, и подкатываться после отката назад до произвольного состояния вперёд архивными журналами автоматически. Если FLASHBACK ON не отработать, точки отката всё равно можно будет создавать, но вот откатиться на произвольную грубина в пределах параметра DB_FLASHBACK_RETENTION_TARGET будет нельзя, хотя размер FLASHBACK журналов при этом будет существенно меньше

-- конфигурируем FRA (дублируем тему FRA)
ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE = 500G;
ALTER SYSTEM SET DB_RECOVERY_FILE_DEST = '/oracle/flash_recovery_area';
ALTER SYSTEM SET DB_FLASHBACK_RETENTION_TARGET=4320;
-- включаем FLASHBACK
STARTUP MOUNT;
ALTER DATABASE FLASHBACK ON;
ALTER DATABASE OPEN ; (или ALTER DATABASE OPEN READ ONLY для стэндбая)
-- проверяем
SELECT FLASHBACK_ON FROM V$DATABASE ;
ARCHIVE LOG LIST ;
-- создаём точку отката
CREATE RESTORE POINT before_upgrade;
CREATE RESTORE POINT guarant_before_upgrade GUARANTEE FLASHBACK DATABASE;
SELECT NAME, SCN, TIME, DATABASE_INCARNATION#,GUARANTEE_FLASHBACK_DATABASE,STORAGE_SIZE
       FROM V$RESTORE_POINT;
DROP RESTORE POINT before_upgrade;
-- восстанавливаемся на точку отката
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
FLASHBACK DATABASE TO RESTORE POINT BEFORE_UPGRADE_G;
ALTER DATABASE OPEN RESETLOGS;

Есть нюансы - например, после восстановления на старую точку (минус 10 часов) нельзя повторно восстановиться на новую (минус 8 часов). или вот корректная процедура flashback database в случае добавленных между точками восстановления datafiles описана в Oracle Support Note: Flashback Recovery With Added Datafiles [1538357.1]


Что такое корзина ?

[v.10+] Корзиной называется функциональность, вместо удаления таблиц переименовывающая их с дочерними объектами для последующего восстановления. В конзине может храниться несколько копий одной и той же таблицы. Вот пример типичных команд:

SHOW RECYCLEBIN ;
-- содержимое корзины пользователя, общей, объект:
SELECT * FROM RECYCLEBIN ;
SELECT * FROM DBA_RECYCLEBIN ;
SELECT object_name AS recycle_name, original_name, type FROM RECYCLEBIN ;
-- вычистить корзину свою
PURGE RECYCLEBIN;
-- вычистить корзину всю
PURGE DBA_RECYCLEBIN;
-- восстановить таблицу до удаления
FLASHBACK TABLE "BIN$ххххххххххххххх" TO BEFORE DROP ;
FLASHBACK TABLE TEST.TEST_TABLE TO BEFORE DROP ;
FLASHBACK TABLE "BIN$ххххххххххххххх" TO BEFORE DROP RENAME TO TEST.TEST_TABLE ;
-- удалить навсегда
DROP TABLE my_table PURGE;
или
PURGE TABLE "BIN$xxxxxxxxxxxxxxxxxxxxxxxxxx";
-- отключить корзину системно
ALTER SYSTEM SET RECYCLEBIN=OFF SCOPE=SPFILE;
SHUTDOWN IMMEDIATE ;
STARTUP OPEN ;
-- отключить в сессии
ALTER SESSION SET RECYCLEBIN=OFF;

Как задать политики хранения RMAN ?

[v.10+] Политика хранения для количества копий и окна (диапазона, для любой точки которого может быть проведено восстановление) включается и выключается командами

CONFIGURE RETENTION POLICY TO REDUNDANCY 3;
CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
CONFIGURE RETENTION POLICY TO NONE;

Ещё одно интересная политика - удалять полученные standby архивные журналы после применения. Как показывает опыт, применённые журналы удаляются не сразу, а после того, как в FRA останется меньше ~10% свободного места от выставленного параметром DB_RECOVERY_FILE_DEST_SIZE

CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY ;

Как включить аудит базы ?

[v.9+] Для включения аудита устанавливается параметр инициализации AUDIT_TRAIL=DB|OS|none. Далее командой AUDIT/NOAUDIT выставляется нужная детализация, в частности операторов|привелегий|операторов с модификациями WHENEWER (NOT) SUCCESSFULL и BY ACCESS/SESSION. Выборка производится или из таблицы AUD$, или из журналов операционной системы

Кроме того существует пакет DBMS_FGA, позволяющий создавать расширенные правила для фиксации операций со строками, удовлетворяющими условиям правил. При активации этого режима требуется выставить параметр инициализации DBA_FGA_AUDIT_TRAIL


Что такое AWR и чем он лучше StatsPack ?

[v.10+] AWR является продолжением развития инструментария для мониторинга работы экземпляра, это следующее после Statspack поколение. Наряду с расширенными возможностями этот инструмент требует отдельного лицензирования, стоимость которого сопоставима со стоимостью лицензий за БД. Поэтому использование его спорно. Более детальное описание AWR доступно в документации от производителя, в частности по пакету DBMS_WORKLOAD_REPOSITORY. Ниже приводятся отдельные команды, наиболее востребованные при работе с AWR

  • развёртывание и свёртывание AWR - не гулял, однако @?/rdbms/admin/CATAWRTB.sql, @?/rdbms/admin/CATNOAWR.sql, при этом уровень статистики должен быть выставлен STATISTICS_LEVEL = TYPICAL or ALL. Без удаления отключить сбор можно, если выставить STATISTICS_LEVEL = BASIC, или установить нулевой интервал сбора ...modify_snapshot_settings(interval=>0), или отключить сбор dbms_scheduler.disable('GATHER_STATS_JOB')
  • Список всех снапшотов и DBID - SELECT snap_id, begin_interval_time, end_interval_time FROM dba_hist_snapshot ORDER BY 1; select dbid from v$database ;
  • AWR DBtime script
    select * from ( select begin_snap, end_snap, timestamp begin_timestamp, inst, a/1000000/60 DBtime 
                           from ( select e.snap_id end_snap, lag(e.snap_id) over (order by e.snap_id) begin_snap, 
                                         lag(s.end_interval_time) over (order by e.snap_id) timestamp,
                                         s.instance_number inst, e.value,
                                         nvl(value-lag(value) over (order by e.snap_id),0) a 
                                         from dba_hist_sys_time_model e, DBA_HIST_SNAPSHOT s
                                         where s.snap_id = e.snap_id and e.instance_number = s.instance_number and
                                               to_char(e.instance_number) like to_char(e.instance_number) and
                                               stat_name = 'DB time' )
                           where begin_snap between 0 and 99999999 and begin_snap=end_snap-1 order by dbtime desc ) 
             where rownum < 100 ;
    
  • Снапшоты можно создавать автоматически:
    BEGIN 
    DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS( retention => 43200, interval => 30, topnsql => 100,
         dbid => 3310949047); 
    END;
    /
    
  • Изменить параметры можно так:
    select snap_interval, retention from dba_hist_wr_control ;
    exec dbms_workload_repository.modify_snapshot_settings (retention => 14*24*60) //14 дней
    execute dbms_workload_repository.modify_snapshot_settings(interval => 0);
    execute dbms_workload_repository.modify_snapshot_settings(interval => 60);
  • Создать/удалить снапшот руками:
    BEGIN DBMS_WORKLOAD_REPOSITORY.create_snapshot('ALL'); END;
    SELECT DBMS_STATS.GET_STATS_HISTORY_RETENTION from dual;
    BEGIN DBMS_STATS.ALTER_STATS_HISTORY_RETENTION (7); END;
    BEGIN DBMS_STATS.PURGE_STATS(to_timestamp_tz('01-09-2007 00:00:00 Europe/Moscow',
          'DD-MM-YYYY HH24:MI:SS TZR')); end;
    BEGIN DBMS_WORKLOAD_REPOSITORY.drop_snapshot_range (low_snap_id => 22,high_snap_id => 32); END;
    EXECUTE DBMS_WORKLOAD_REPOSITORY.create_snapshot();
  • Отчёты аналогичные statspack строятся следующими запросами:
    set long 1000000 pagesize 0
    SELECT output FROM TABLE (dbms_workload_repository.awr_report_text (Db_Id, Instance_num,
           Snap_begin, Snap_end) );
    @?/rdbms/admin/awrrpt.sql, @?/rdbms/admin/awrgrpt.sql (RAC)
    @?/rdbms/admin/awrrpti.sql (экземпляр)
    @?/rdbms/admin/awrgrpti.sql (RAC и экземпляр)
    @$ORACLE_HOME/rdbms/admin/awrddrpt.sql (период),
    @?ORACLE_HOME/rdbms/admin/ashrpt.sql (Active Session Hist)
  • Относительно SQL, отражённых в отчёте, план выполнения можно посмотреть запросом:
    select * from TABLE(dbms_xplan.display_awr('хэш_SQL_запроса'));

Конечно же AWR/ADDM+ASH являются удобной технологией от вендора, однако она требует дополнительного лицензирования пакетов TNING PACK и DIAGNOSTIC PACK. Если возможности лицензировать эти опции нет, приходится обходиться тем, что доступно. А доступно не так уж мало - а именно входящий в СУБД пакет StatsPack. Этот пакет не требует лицензирования, однако проводит аналитику только по двум срезам данных, не отражая динамику показателей

Для обхода этого ограничения в моём авторском продукте ОрСиМОН БЕССТ использовались сводные таблицы дельт значений показателей с последующей обработкой аналитическими модулями отчётов. Однако это всё же меньший функционал, в частности ASH не заменяется даже при таком расширении функционала StatsPack. К тому же в настоящее время считаю использование сводных таблиц менее эффективным способом, и для третьего поколения ОрСиМОН используются оконные функции, позволяющие не привязываться к надстройкам. Эти же функции можно использовать и для анализа представлений AWR, например вот так:

select sn.begin_interval_time, sn.end_interval_time, vals.snap_id,
       vals.event_name, vals.curr, vals.old, vals.curr - vals.old diff
       from ( select snap_id, event_name, total_timeouts curr,
                     lag(total_timeouts,1,0)
                        over (partition by event_name 
                              order by snap_id) old
                     from sys.dba_hist_system_event ) vals,
                          dba_hist_snapshot sn
       where vals.snap_id = sn.snap_id and old > 0
       order by event_name, snap_id

Какие есть утилиты командной строки от вендора ?

[v.10+] Не sqlplus единым, есть немало других утилит. Использовал - lsnrctl, srvctl, rman, crsctl, adrci, dgmgrl, expdp, impdp, exp, imp ...

-- немного полезных команд кластерного ПО crsctl
# тушим crs на узле
crsctl stop crs
# смотрим статус crs на узле
crsctl stat res -init -t
crsctl check crs
# смотрим статус crs кластера
crsctl check cluster -all
# останавливаем/поднимаем кластер
crsctl stop|start cluster -all
# отключаем/включаем crs чтобы не стартовал после перезагрузки
crsctl disable|enable crs

-- немного полезных команд srvctl
srvctl status|stop|start instance -db testdb9 -instance testdb91
srvctl status|stop|start database -db testdb9
       [-stopoption (...|immediate)|-startoption (..|mount)]
srvctl status|stop|start service -db testdb9

-- немного полезных команд lsnrctl
...

-- немного полезных команд dgmgrl
# посмотреть конфигурацию и статус отдельной БД
show configuration [verbose] ;
show database testdb92 ;
# отключение и включение операций с БД в конфигурации
disable|enable database testdb9 ;
# отключение применения журналов на стэндбае
edit database testdb9 set state = 'APPLY-OFF';
# включение синхронного наката
edit database testdb9 set state = 'APPLY-ON';
# включение наката с задержкой на смонтированном и подготовленном стэндбае
- дописать установку параметра задержки dgmgrl

# альтернативы управления стэндбаем из sqlplus
alter database recover managed standby database
      USING CURRENT LOGFILE DISCONNECT FROM SESSION ;
alter database recover managed standby database disconnect from session;
alter database recover managed standby database
      delay 480 disconnect from session;
# накатить стэндбай до конкретного SCN
alter database recover managed standby database
      until change 14702729191589 disconnect from session ;
# отключить DGuard
alter system set dg_broker_start = FALSE scope = both sid='*' ;

-- немного полезных команд rman
# выставить на стэндбае политику удаления журналов после приенения
# реальное удаление - когда в FRA отстаётся ~10% свободно
CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY ;
# включение отлдадки, в т.ч. отображение % при долгой дупликации
rman debug on trace=/.../.../.../path log=/.../.../.../path

-- немного полезных команд adrci
metalink про ADR 1283137.1, 564269.1


Как перегрузить данные в другую базу через утилиты expdp, impdp, exp, imp ?

[v.8+] Стандартными считаются утилиты Export/Import. Существует несколько режимов выгрузки/загрузки - полный (при котором однако не перегружаются объекты схемы sys), списка схем, списка таблиц, транспортируемых табличных пространств. Утилиты запускается аналогично sqlplus и может принимать аргументы или в командную строку, или в файл параметров, например формируем файл параметров file.param

# параметры для экспорта
FILE=./export.dmp
LOG=./export.log
#CONSISTENT=YES
FULL=YES | OWNER=схема[,схема ...] | TABLE=[владелец.]имя_таблицы[,[владелец.]имя_таблицы ...]
CONSTRAINTS=YES
TRIGGERS=YES
GRANTS=YES
INDEXES=YES
ROWS=YES
STATISTICS=none

# параметры для импорта
FILE=./export.dmp
LOG=./import.log
#CONSISTENT=Y
FULL=NO
FROMUSER=владелец_строй_БД TOUSER=владелец_новой_БД
CONSTRAINTS=yes
GRANTS=y
INDEXES=y
ROWS=y

И запускаем экспорт командой exp \'sys as sysdba\' PARFILE=file.param. Аналогично готовим файл параметров и запускаем импорт. Важно, что при переносе прикладных данных можно заранее создать пользователя/схему с иными параметрами, например другим табличным пространством по умолчанию, после чего запустить импорт и получить данные в другом табличном пространстве. Также для таблиц можно заранее создать таблицы в других табличных пространствах, и потом провести импорт, что позволит перенести таблицы с изменением параметров хранения

Также нужно отметить, что c 10 версии появились новые утилиты под названием DataPump, призванные заменить Export/Import. Особенностями этих утилит является существенно более быстрая работа, функионирование через job, что обеспечивает продолжение работы в случае отрыва терминальной сессии. Все основные параметры по выгрузке уже включены по умолчанию, и при необходимости нужно явно указывать исключения

Работают утилиты дата-помпы через объявленный в СУБД каталог (create catalog). Вопрос целостности данных также решён иначе - в файле параметров можно указать FLSHBACK_SCN (например select current_scn from v$database), на который будет сформирован срез выгрузки. Такде для работы с помпой необходимо выдать пользователю роли DATAPUMP_EXP_FULL_DATABASE и DATAPUMP_IMP_FULL_DATABASE, а также EXEMPT ACCESS POLICY TO SYSTEM/SYS. Кроме того на многоядерных системах полезно функция распараллеливания задачи. Запускать под system, а не под sys, например "expdp directory=dpdir FULL=y DUMPFILE=exp_20160121.dmp LOGFILE=exp_omsdb12_20160121.log". Полезной может оказаться и функция перегрузки данных через dblink. Ниже приведены примеры файлов параметров для импорта и экспорта Data Pump:

# export
DIRECTORY=<зарегистрированный в БД каталог с правами на запись
          пользователя, под которым запускается экземпляр>
FLASHBACK_SCN=
FLASHBACK_TIME="TO_TIMESTAMP(<альтернативно можно увазать время>)"
DUMPFILE=<имя дампа, для паралелизации с маской, например "dumpfl_%u">
LOGFILE=<имя файла журнала, альтернатива NOLOGFILE=y>
PARALLEL=<включает параллелизацию, учитывать это в имени дампа>
JOB_NAME=<>
FULL=
SCHEMAS=<можно перечислить требуемые схемы>
TABLES=<перечень таблиц>
#import
DIRECTORY=<...>
DUMPFILE=<имя дампа, для паралелизации с маской, например "dumpfl_%u">
LOGFILE=<имя файла журнала, альтернатива NOLOGFILE=y>
PARALLEL=<включает параллелизацию, учитывать это в имени дампа>
FULL=
SCHEMAS=<можно перечислить требуемые схемы>
NETWORK_LINK=<имя dblink, при этом возможно указание параметров
              FLASHBACK_SCN или FLASHBACK_TIME>
TABLES=<перечень таблиц>

Если убить job - подключаемся к нему командой expdp attach=имя джоба (например expdp attach=SYS_EXPORT_FULL_01). Посмотреть имя job можно командой select owner_name, job_name, operation, state from dba_datapump_jobs where state = 'EXECUTING';

Примеры старта из командной строки без файла параметров

expdp userid="'/ as sysdba'" schemas="SCHEMA01","D$SCHEMA02","XX\$SCHEMA03"
      parallel=5 cluster=n compress=y DIRECTORY=STORE
      DUMPFILE=SCHEMAS%U.dmp LOGFILE=SCHEMAS_EXP.log
impdp userid="'/ as sysdba'" schemas="D$SCHEMA02","XX\$SCHEMA03" parallel=5
      cluster=n DIRECTORY=STORE DUMPFILE=SCHEMAS%U.dmp LOGFILE=SCHEMAS_IMP.log

Как организовать резервирование базы

В настоящее время можно посмотреть статью о создании горячего резерва с помощью RMAN - наиболее перспективной в настоящее время технологиии


Как скопировать базу на другой сервер (в т.ч. дупликация) ?

[v.10+] В настоящее время можно посмотреть статью о создании горячего резерва с помощью RMAN - наиболее перспективной в настоящее время технологиии


Как мониторить состояние инстанса и базы

[v.10+] Хорошее корпоративное решение начиная с 10 версии - Enterprise Manager, он же Grid Control, он же Cloud Control

[v.8+] Первый источник получения данных - журналы работы операционной системы, данные статистики загрузки компонентов, журналы экземпляра и листенеров SQL Net. Расположение журналов ОС зависит от операционной системы (для SUN Solaris это /varl/log и /var/adm, для Linux - /var/log и т.д.). Средства сбора статистики о загрузке компонентов системы зависят от ОС и конкретной реализации механизма сбора статистики администратором. Журнал работы экземпляра располагается в каталоге BDUMP init - файла экземпляра и называется alertИМЯ_ЭКЗЕМПЛЯРА.log, а журналы листенеров SQL Net располагаются в местах, указанных в конфигурационных файлах каждого листенера

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

Далее - счётчики различных событий и статистик представлены в Oracle представлениями V$..., а именно: v$system_event, v$system_wait, v$session_event, v$session_stat, v$sesion_wait, v$filestat, v$segstats (для версии от 9) и др. Кроме того здесь могут пригодиться представления, отражающие текущие сессии (v$session, v$process), выполняемые ими запросы (v$sqltext ...), блокировки (lock$, dba_blockers) и другие. Более глубокий разбор - это тема отдельной вводной статьи по понятиям тюнинга системы. Однако статистичская информация собирается и может быть проанализироана поставляемым в составе движка пакетом Statspack

Следующим шагом может быть активирование сбора статистической информации о работе экземпляра с помощью поставляемых с СУБД утилит utlbstat, utlestat (для версии 8) или же statspack (с версии 9), скрипты которого, также, как и документация, могут быть найдены в каталоге $ORACLE_HOME/rdbms/admin/sp*. Эти инструменты позволят получить срезы многочисленных статистических счетчиков экземпляра и последующее построение отчета как разницы по двум произвольно выбранным срезам. По хорошему statspack является лишь "зародышем" полноценного решения по анализу, которое может быть разработано каждым администратором самостоятельно. Альтернативой является использование AVR (но только с версии 10), однако это опция, и на неё требуется отдельная лицензия за очень хорошие деньги

Еще одним методом является использование пакета RDAOracle, не поставляемого с базой, но доступного на metalink пользователям, подписанным на поддержку продуктов Oracle. Однако этот инструмент больше подходит для "глобального" ознакомления с существующей системой, т.к. он предназначен для сбора "глобального" среза данных по операционной системе, установленной СУБД, конфигурации экземпляра и т.д.

Кроме того может потребоваться сбор статистики динамики роста объектови т.п., реализуемые каждым администратором самостоятельно


Как мониторить работу физического стэндбая, организованного по технологии DataGuard ?

[v.10+] Для трассировки необходимо установить параметр LOG_ARCHIVE_TRACE с нужными значениями, что ляжет в трэйсы в udump

Ручной метод контоля архивации и переноса журналов (этап архивации журналов) предлагает:

  • определить состояние журналов - SELECT THREAD#, SEQUENCE#, ARCHIVED, STATUS FROM V$LOG;
  • вычислить максимальный заархивированный - SELECT MAX(SEQUENCE#) FROM V$ARCHIVED_LOG;
  • вычислить максимально отданный журнал для каждого приёмника - SELECT DESTINATION, STATUS, ARCHIVED_THREAD#, ARCHIVED_SEQ# FROM V$ARCHIVE_DEST_STATUS WHERE STATUS <> 'DEFERRED' AND STATUS <> 'INACTIVE';
  • вычислить отсутствующие в нелокальном (относительно локального) источнике журналы - SELECT LOCAL.THREAD#, LOCAL.SEQUENCE# FROM (SELECT THREAD#, SEQUENCE# FROM V$ARCHIVED_LOG WHERE DEST_ID=1) LOCAL WHERE LOCAL.SEQUENCE# NOT IN (SELECT SEQUENCE# FROM V$ARCHIVED_LOG WHERE DEST_ID=2 AND THREAD# = LOCAL.THREAD#);
    либо.
    автораспознанная последняя недополученная последовательность - SELECT * FROM V$ARCHIVE_GAP;

Далее нужно обеспечить стэндбаю журналы - либо руками

  • вычислить недостающие журналы - SELECT NAME FROM V$ARCHIVED_LOG WHERE THREAD#=1 AND DEST_ID=1 AND SEQUENCE# BETWEEN 7 AND 10;
  • скопировать их рукми на стэндбай и зарегистрировать в базе - ALTER DATABASE REGISTER LOGFILE '/physical_standby1/thread1_dest/arcr_1_7.arc';

либо автоматически - указав параметры FAL_CLIENT (на основной базе указывает на стэндбай) и FAL_SERVER (на стэндбай, указывает на основную базу)

Метод просмотра состояния применения (этап применения журналов) журналов:

  • просмотреть состояние отвечающих за standby сервисов (запрос на физическом стэндбае) - SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, BLOCKS FROM V$MANAGED_STANDBY;
  • определить примененные журналы (запрос на физическом стэндбае) - SELECT THREAD#, SEQUENCE#, FIRST_CHANGE#, NEXT_CHANGE# FROM V$LOG_HISTORY;
  • или послежний журнаи и состояние приёмника (запрос на физическом стэндбае) - SELECT ARCHIVED_THREAD#, ARCHIVED_SEQ#, APPLIED_THREAD#, APPLIED_SEQ# FROM V$ARCHIVE_DEST_STATUS;
  • принятые и зарегистрированные жарналы (запрос на физическом стэндбае) - SELECT REGISTRAR, CREATOR, THREAD#, SEQUENCE#, FIRST_CHANGE#, NEXT_CHANGE# FROM V$ARCHIVED_LOG;
  • события подсистемы (запрос на основной базе и на физическом стэндбае раздельно) - SELECT MESSAGE FROM V$DATAGUARD_STATUS;

Также вот несколько полезных команд

старт стэндбай базы - STARTUP NOMOUNT; ALTER DATABASE MOUNT STANDBY DATABASE; ALTER DATABASE RECOVER MANAGED STANDBY DATABASE; ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;

стоп стэндбай базы - ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

контроль процессов восстановления - SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, BLOCKS FROM V$MANAGED_STANDBY;


Как настроить statspack на съём снапшотов с заданной периодичностью и удаление старых данных ?

[v.8+] После развёртывания пакета Statspack для настройки периодического снятия снапшотов и удаления данных старых снапшотов можно использовать такой SQL скрипт

spool spauto_enable.log
-- разлочить пользователя принудительно
alter user perfstat account unlock identified by пароль_пользователя_perfstat ;
commit ;
-- добавить место в табличном пространстве
alter database datafile '.../statspack00.dbf' autoextend on maxsize 4096m ;
variable jobno number;
variable instno number;
-- добавить периодический съём снапшотов
begin
select instance_number into :instno from v\$instance;
dbms_job.submit(:jobno, 'statspack.snap(10);', sysdate+15/1440, 'SYSDATE+30/1440', TRUE, :instno);
commit;
end;
/
-- добавить удаление старых снапшотов
select job, next_date, next_sec from user_jobs where job = :jobno;
begin
select instance_number into :instno from v\$instance;
dbms_job.submit(:jobno, 'delete from perfstat.stats$snapshot where snap_time<sysdate-7;', 
         sysdate+1, 'SYSDATE+1', TRUE, :instno);
commit;
end;
/
-- просмотреть содержимое заданий
select job, next_date, next_sec from user_jobs where job = :jobno;
spool off;
col WHAT for a60
col NLS_ENV for a30
col INTERVAL for a30
col MISC_ENV for a30
set linesize 300
select JOB,LOG_USER,PRIV_USER,SCHEMA_USER,LAST_DATE,LAST_SEC,THIS_DATE,THIS_SEC,NEXT_DATE,NEXT_SEC,
        TOTAL_TIME,INTERVAL,FAILURES,WHAT from dba_jobs ;
-- просмотреть размер табличного пространства под хранение снапшотов
col TABLESPACE_NAME for a30
col FILE_NAME for a60
select TABLESPACE_NAME,FILE_NAME,BYTES,MAXBYTES,AUTOEXTENSIBLE,INCREMENT_BY 
       from dba_data_files where tablespace_name = 'STATSPACK_DATA' ;
select USERNAME,DEFAULT_TABLESPACE,TEMPORARY_TABLESPACE,CREATED,PROFILE from dba_users where username = 'PERFSTAT' ;
exit

Как выявить блокировки в системе

[v.8+] Блокировки отражены в представлении v$lock, и, в связке с представлениями dba_objects, obj$, v$session, v$process позволяют выявить не только сами блокировки. но также сессию, серверный процесс, запущенную программу, имя Oracle и ОС пользователя. Ниже представлен простой пример, отражающий блокированные объекты, пользователя и сессию, ожидающую освобождения блокировки

SELECT s.SID,s.SERIAL#,u.USERNAME,o.OBJECT_ID,o.OWNER,o.OBJECT_NAME,o.OBJECT_TYPE,
       DECODE(l.TYPE,'TM','DML enqueue','TX','Transaction enqueue',
                     'UL','User supplied','Sys type - '||l.TYPE) AS LOCK_TYPE,
       DECODE(l.LMODE,0,'none',1,'null',2,'row-S (SS)',3,'row-X (SX)',4,'share (S)',
                      5,'S/Row-X (SSX)',6,'exclusive (X)',l.LMODE) AS LOCK_MODE,
       DECODE(l.REQUEST,0,'none',1,'null',2,'row-S (SS)',3,'row-X (SX)',4,'share (S)',
                        5,'S/Row-X (SSX)',6,'exclusive (X)',l.REQUEST) AS REQUEST,
       l.CTIME,l.BLOCK
       FROM V$LOCK l, DBA_OBJECTS o, V$SESSION s, dba_users u
            WHERE l.ID1 = o.OBJECT_ID AND l.SID = s.SID AND s.USER# = u.USER_ID 
	          AND s.SID > 2 ;

Как выявить сессии, блокирующие другие сессии

Такие сессии отражены в представлении dba_blockers, и вытаскиваются обычным select'ом

select p.spid, s.process, s.sid, s.serial#, s.username, s.osuser, s.terminal, 
       s.program, au.name
       from dba_blockers b, v$session s, v$process p, audit_actions au
              where b.holding_session = s.sid AND s.paddr = p.addr 
	            AND s.command = au.action ;

Как посмотреть детали блокировок TX

[v.8+] Для блокировки строки, характерной для TX mode 6, с 10 версии СУБД посмотреть на ожидаемые объекты и получить шаблон запросов для вывода ожидаемых строк можно скриптом, приведённым ниже. Логика скрипта учитывает данные ожидающих сессий, но именно для mode 6 они должны совпадать с удерживающей сессией

select 'select * from '||o.owner||'.'||o.object_name||' where rowid = '''||
       DBMS_ROWID.ROWID_CREATE(1,s.ROW_WAIT_OBJ#,s.ROW_WAIT_FILE#,
                  s.ROW_WAIT_BLOCK#,s.ROW_WAIT_ROW#)||''';',
       l.SID,  o.object_type
       from v$lock l, v$session s, dba_objects o
       where l.type='TX' and l.lmode = 0 and l.request = 6 and
             l.sid = s.sid and o.object_id = s.ROW_WAIT_OBJ# ;

Для блокировки строки, характерной для TX mode 4, есть конкуренция за транзакционный слот в блоке ITL. Хохма в том, что СУБД должна увеличивать количество выделенных ITL при необходимости, однако если места в блоке нет - будет цедуля. Данные по транзакционному слоту можно увидеть следующими запросами

SELECT sid, TRUNC(id1/POWER(2,16)) rbs, BITAND(id1,POWER(2,16)-1)+ 0 slot, id2 seq
       FROM v$lock WHERE sid = _waiting_sid_ AND type = 'TX';
SELECT s.sid, t.xidusn, xidslot, xidsqn
       FROM v$transaction t, v$session s WHERE t.addr = s.taddr;



Как вычислить пользователя ОС и Oracle для произвольной сессии в режиме dedicated

[v.9+] для варианта работы через терминальную сессию можно
- вычислить терминал по IP адресу пользователя (who | grep IP)
- вычислить идентификаторы оракловой сессии (select SID,SERIAL# from v$session where TERMINAL = 'вычисленный_в_шаге_1_pts' ;


Как посмотреть занимаемое и свободное место в табличных пространствах

[v.8+] Предлагается вариант, суммирующий занимаемый принадлежащими табличному пространству сегментами (представления словаря dba_table_spaces и dba_segments). Также можно посмотреть занимаемое и свободное место для суммы использованного объема, принадлежащих конкретному табличному пространству файлов данных (представление словаря dba_data_files) - в сравнении с общим объёмом и возможностями авторасширения

Однако это только часть проблемы, т.к. каждый вновь создаваемый объект базы размещается в табличных пространствах в одноименном сегменте, которому могут быть присвоены более строгие ограничение по доступному объему. Такие ограничения могут быть заданы при создании табличного пространства, и в дальнейшем - наследоваться для каждого вновь создаваемого сегмента. Эти данные также можно получить в представлении словаря dba_segments

Ёще одним источником информации может служить представление словаря dba_free_spaces. Ниже приводится пример запросов для sqlplus, позволяющим получить детальную картину по использованному и свободному месту в табличных пространствах и конкретных файлах табличных пространств с учетом возможного авторасширения. Также эти запросы отразят максимально возможный размер для вновь выделяемого экстента

set pagesize 300
set linesize 200

rem -- агрегированная утилизация табличных пространств
rem -- USERSIZE     - занятый объем табличного пространства (уровень HWL)
rem -- CURRSIZE     - текущий размер файлов табличного пространства
rem -- CURRDELTA    - размер неиспользованного в табличных пространствах места
rem -- MAXGROW      - размер разрешенного авторасширения табличных пространств
rem -- MAXSIZE      - макс. размер табличных пространств с учетом авторасширения
rem -- MAXDELTA     - макс. неиспользуемый размер табл. простр. с учетом авторасширения
rem -- FREESPACE    - текущее свободное место в табл. пространствах без учета авторасширения
rem -- MAXFREESPACE - текущее свободное место в табл. пространствах без учета авторасширения
rem -- BIGCURREXT   - макс. размер свободной последовательности блоков под выделение экстента

col usersize for 999999999999
col currsize for 999999999999
col maxsize for 999999999999
col currdelta for 999999999999
col maxgrow for 999999999999
col maxdelta for 999999999999
col freespace for 999999999999
col maxfreespace for 999999999999
col bigcurrext for 999999999999
col tablespace_name for a12
col file_name for a35

select df.TABLESPACE_NAME,df.USERSIZE,df.CURRSIZE,df.CURRDELTA,df.MAXGROW,df.MAXSIZE,
       df.MAXDELTA, fs.FREESPACE, fs.FREESPACE + df.MAXDELTA as MAXFREESPACE,fs.BIGCURREXT
       from
          (select TABLESPACE_NAME,sum(user_bytes) as USERSIZE, sum(bytes) as CURRSIZE, 
	          sum(bytes) - sum(user_bytes) AS CURRDELTA,
                  sum(CASE WHEN AUTOEXTENSIBLE = 'YES' then MAXBYTES else BYTES end) 
		     as MAXSIZE,
                  sum(CASE WHEN AUTOEXTENSIBLE = 'YES' then MAXBYTES else BYTES end) - 
		     sum(user_bytes) as MAXDELTA,
		  sum(CASE WHEN AUTOEXTENSIBLE = 'YES' then MAXBYTES else BYTES end) - 
		     sum(BYTES) as MAXGROW
                  from dba_data_files GROUP BY TABLESPACE_NAME) df,
          (select TABLESPACE_NAME,sum(bytes) AS FREESPACE,max(bytes) AS BIGCURREXT 
	          from dba_free_space 
	          GROUP BY TABLESPACE_NAME) fs
       where df.TABLESPACE_NAME = fs.TABLESPACE_NAME ;


col usersize for 99999999999
col currsize for 99999999999
col maxsize for 999999999999
col currdelta for 99999999999
col maxdelta for 99999999999
col freespace for 99999999999
col maxfreespace for 99999999999
col maxgrow for 99999999999
col tablespace_name for a10
col file_name for a35

select df.TABLESPACE_NAME,df.FILE_NAME,df.USERSIZE,df.CURRSIZE,df.CURRDELTA,df.MAXGROW,
       df.MAXSIZE, df.MAXDELTA, fs.FREESPACE, fs.FREESPACE + df.MAXDELTA as MAXFREESPACE
       from
          (select TABLESPACE_NAME,FILE_NAME,FILE_ID,sum(user_bytes) as USERSIZE, 
	          sum(bytes) as CURRSIZE, 
	          sum(bytes) - sum(user_bytes) AS CURRDELTA,
                  sum(CASE WHEN AUTOEXTENSIBLE = 'YES' then MAXBYTES else BYTES end) 
		     as MAXSIZE,
                  sum(CASE WHEN AUTOEXTENSIBLE = 'YES' then MAXBYTES else BYTES end) - 
		     sum(user_bytes) as MAXDELTA,
		  sum(CASE WHEN AUTOEXTENSIBLE = 'YES' then MAXBYTES else BYTES end) - 
		     sum(BYTES) as MAXGROW		  
                  from dba_data_files GROUP BY TABLESPACE_NAME,FILE_NAME,FILE_ID) df,
          (select TABLESPACE_NAME,FILE_ID,sum(bytes) AS FREESPACE from dba_free_space 
	          GROUP BY TABLESPACE_NAME,FILE_ID) fs
       WHERE df.TABLESPACE_NAME = fs.TABLESPACE_NAME AND df.FILE_ID = fs.FILE_ID 
       ORDER BY TABLESPACE_NAME, FILE_NAME ;

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


Как быстро посчитать объём redo ?

[v.9+]

-- redo per day per hour
select TO_CHAR(d.dayhour,'YYYY-MM-DD') day, sum(d.mbsize) sum_mbsize,
       avg(d.mbsize) avg_mbsize, min(d.mbsize) min_mbsize, max(d.mbsize) max_mbsize
       from  ( select TO_DATE(TO_CHAR(FIRST_TIME,'YYYY-MM-DD HH24'),'YYYY-MM-DD HH24') dayhour,
                      sum(BLOCKS * BLOCK_SIZE)/1024/1024 mbsize
                      from v$archived_log
                      group by TO_DATE(TO_CHAR(FIRST_TIME,'YYYY-MM-DD HH24'),'YYYY-MM-DD HH24')
                      order by 1) d
       group by TO_CHAR(d.dayhour,'YYYY-MM-DD') order by 1 ;

-- redo per day only max per hour
set linesize 400 pagesize 400
select * from (select TO_CHAR(d.dayhour,'YYYY-MM-DD') day, max(d.mbsize) max_mbsize
              from (select TO_DATE(TO_CHAR(FIRST_TIME,'YYYY-MM-DD HH24'),'YYYY-MM-DD HH24') dayhour,
                           sum(BLOCKS * BLOCK_SIZE)/1024/1024 mbsize
                           from v$archived_log 
                           group by TO_DATE(TO_CHAR(FIRST_TIME,'YYYY-MM-DD HH24'),'YYYY-MM-DD HH24')
                           order by 1) d
               group by TO_CHAR(d.dayhour,'YYYY-MM-DD') order by 2 desc) where rownum < 10;

-- easy max per hour
select * from (select TO_CHAR(FIRST_TIME,'YYYY-MM-DD HH24') dayhour,
                      sum(BLOCKS * BLOCK_SIZE)/1024/1024 mbsize
                      from v$archived_log group by TO_CHAR(FIRST_TIME,'YYYY-MM-DD HH24')
                      order by 2 desc)
       where rownum < 10 ;

3.11 Как посмотреть задания планировщика ?

# есть старый вариант DBMS_JOB, новый DBMS_SCHEDULER и планировщики ОС.
# Здесь пока про DBMS_SCHEDULER
select * from (select OWNER,JOB_NAME,JOB_SUBNAME,STATUS,ACTUAL_START_DATE,RUN_DURATION
                      from dba_scheduler_job_run_details
                      where RUN_DURATION like '+001%' or  RUN_DURATION like '+002%'
                            or RUN_DURATION like '+003%' or RUN_DURATION like '+004%'
                      order by ACTUAL_START_DATE desc) where rownum < 100 ;

select owner,job_name,elapsed_time from all_scheduler_running_jobs ;

select * from (select OWNER,JOB_NAME,JOB_SUBNAME,STATUS,ACTUAL_START_DATE,RUN_DURATION
                      from dba_scheduler_job_run_details order by ACTUAL_START_DATE desc)
         where rownum < 100 ;

select OWNER,JOB_NAME,JOB_SUBNAME,STATUS,ACTUAL_START_DATE,RUN_DURATION
       from ALL_SCHEDULER_JOB_RUN_DETAILS where JOB_NAME = 'J$JOB_TEST_1' order by 5 ;

3.12 Как посмотреть chained rows ?

# создаёмтаблицу для отображения результатов
create table CHAINED_ROWS (
       owner_name varchar2(30),
       table_name varchar2(30),
       cluster_name varchar2(30),
       partition_name varchar2(30),
       subpartition_name varchar2(30),
       head_rowid rowid,
       analyze_timestamp date );

# используем конструкцию для проведения анализа
analyze table … list chained rows
begin
for i in ( select table_name from user_tables ) loop
    execute immediate 'analyze table ' || i.table_name ||' list chained rows into CHAINED_ROWS';
    end loop;
end;
/

# смотрим результат
select table_name, count(*) from chained_rows group by table_name order by 2 ;

# либо в DBA_TABLES - только после DBMS_STATS, например DBMS_STATS.GATHER_SCHEMA_STATS( 'SYS' ); 
select owner,table_name,num_rows,chain_cnt from dab_tables ...
# либо по блокам
exec dbms_stats.gather_table_stats( user, 'T' );
select blocks, (select count(distinct dbms_rowid.rowid_block_number(rowid)) from t) from user_tables where table_name = 'T';


Как проводить прикладную оптимизацию ?

[v.8+] Опубликовал отдельную статью. Прикладная оптимизация имеет смысл только при оптимизированном предварительно экземпляре. Соответственно, при условии, что экземпляр оптимизирован, а аппаратная платформа не захлёбывается под нагрузкой, что подтверждается статистикой ОС, показателями эффективности работы экземпляра, такими, как коэффициенты попадания и вменяемая статистика и показания событий ожидания, а также вменяема аналитика соответствующий инструментов от statspack до ADDM, можно смотреть в сторону выявления проблемных прикладных запросов


Как включить трассировку, в т.ч. для произвольной сессии

[v.8+] Трассировка является одним из инструментов, используемых при отладке и анализе работы БД. Она позволяет ответить на вопрос - что детально делала выбранная сессия Oracle, в т.ч. предоставляет детальные данные по затратам процессорного времени, ввода-вывода, событиям ожидания, реальному плану исполнения и т.д.

Трассировка в общем случае сводится ее включению, получению трассировочных файлов, их обработке и анализу. Реально все может быть сложнее (средства для реальной сводной трассировки сложных конфигураций с MTS и распарралеливанием в автоматическом режиме декларированы только в 10 версии)

Включение трассировки в своей сессии возможно командой "ALTER SESSION SET SQL_TRACE = TRUE;", то же самое для всей системы делается аналогичной командой "ALTER SYSTEM ...". Более информативным вариантом является трассировка по событию 10046 в варианте запуска командой (включение - ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 12'; отключение - ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT OFF';)

Но наиболее интересным вариантом является включение администратором трассировки отдельной работающей сессии по событию 10046, управляемого функцией недокументированного пакета (exec dbms_system.SET_SQL_TRACE_IN_SESSION(SID,SERIAL#,...) или dbms_system (DBMS_SYSTEM.SET_EV(SID,SERIAL#,10046, level,''), где level 0 - отключить, 1 - включить, 4 - включить и добавить данные о связанных переменных, 8 - включить и добавить информацию об ожиданиях, 12 - включить с полной детализацией). Альтернативой является использование функций пакета DBMS_SUPPORT, который также является недокументированным. Документированным является только пакет DBMS_MONITOR, появившийся в 10 версии Oracle

Вычисление SID и SERIAL# в случае DEDICATED режима работы Oracle можно провести по представлению V$SESSION, согласовав его с выводом команд who и ps операционной системы. Трассировка в MTS режиме и при распараллеливании затруднена, средства сквозной трассировки декларированы только в версии 10 (такие как DBMS_MONITOR, trcsess)

Трассировочный файл создается в соответствующем инстансу каталоге udump (также возможны варианты в bdump), и может анализироваться вручную, либо предварительно обрабатываться командой tkprof, агрегирующей данные и показывающей их в более удобном для восприятия виде

Также имеет смысл перевести инициализационный параметр TIMED_STATISTICS в TRUE, или хотя бы включать его на уровне сессии (ALTER SESSION TIMED_STATISTICS). Это позволит получить хрональный профиль трассируемой сессии, что может быть востребовано, например, для выявления "тяжелых" запросов. Также не стоит забывать про устанавливающий уровень детализации параметр STATISTICS_LEVEL (для сессии включается командой ALTER SESSION STATISTICS_LEVEL)


Как получить текст SQL запроса, выполняемый произвольной сессией в настоящее время

[v.8+] В общем случае необходимо вычислить интересующую нас сессию Oracle из представления cv$session, и используя представления v$sqlarea, v$sqltext или v$sqltext_with_newlines, извлечь текущий запрос. Ниже приведены примеры запросов. Отличия результатов в том, что v$sqlarea отобразит только первые 1000 символов запроса, а v$sqltext и v$sqltext_with_newlines отобразят весь запрос, разбитый на части (piece), причем v$sqltext_with_newlines отразит также и скрываемые в v$sqltext символы новой строки

select s.username,s.sid,s.serial#,sa.sql_text
       from v$session s, v$sqlarea sa
       where s.SQL_ADDRESS = sa.ADDRESS and s.SQL_HASH_VALUE = sa.HASH_VALUE
       order by username ;

select s.username,s.sid,s.serial#,st.piece,st.sql_text
       from v$session s, v$sqltext st
       where s.SQL_ADDRESS = st.address and s.SQL_HASH_VALUE = st.hash_value
       order by s.sid,s.serial#,piece asc ;

select s.username,s.sid,s.serial#,st.piece,st.sql_text
       from v$session s, v$sqltext_with_newlines st
       where s.SQL_ADDRESS = st.address and s.SQL_HASH_VALUE = st.hash_value
       order by s.sid,s.serial#,piece asc ;

Как посмотреть план исполнения SQL запроса ?

[v.8+] предлагаю четыре варианта под разные случаи

Вариант EXPLAIN PLAN. Предварительно создаются объекты для разбора @?/RDBMS/ADMIN/UTLXPLAN.SQL (при каждом обновлении движка рекомендуется удалять и пересоздавать). Далее возможен разбор командой EXPLAIN PLAN [SET STATEMENT_ID = 'некий_id'] [INTO имя_таблицы] FOR текст_запроса. Скрипты @?/RDBMS/ADMIN/UTLXPLS.sql и @?/RDBMS/ADMIN/UTLXPLP.sql (используют пакет DBMS_XPLAN) выводят результаты разбора для последовательных и параллельных запросов. Также вывод доступен через непосредственно через обращение к DBMS_XPLAN

SET LINESIZE 130 PAGESIZE 0 ;
SELECT * FROM table(DBMS_XPLAN.DISPLAY('имя_таблицы_разбора|NULL по-умолчанию','некий_id|NULL последний','тип_отображения'));
Или же можно создать свой запрос, например:

SELECT cardinality "Rows",lpad(' ',level-1)||operation||' '||options||' '||object_name "Plan"
       FROM PLAN_TABLE
       CONNECT BY prior id = parent_id AND prior statement_id = statement_id
               START WITH id = 0 AND statement_id = 'некий_id'
       ORDER BY id;

Вариант TKPROF. При сборе трассировки и последующей обработке через tkprof можно запросить разбор плана исполнения (смотри опции tkprof, фактически он производит такой же разбор, как и EXPLAIN PLAN)

Вариант для SQLPLUS. Команда SET AUTOTRACE (OFF|ON|ON EXPLAIN|ON STATISTICS|TRACEONLY) активирует опцию и выводит не только результаты запросов, но и план выполнения и статистику запроса, при этом у пользователя должна быть создана и присвоена роль PLUSTRACE. Также должна быть создана таблица трассировки скриптом @?/SQLPLUS/ADMIN/PLUSTRCE

Вариант V$SQL_PLAN. Нужно понимать, что все эти варанты могут выдать совсем не тот план разбора, который будет выработан оптимизатором при реальном исполнении, что возможно в силу изменения различных причин. Поэтому для получения именно правильного плана разбора необходимо воспользоваться представленим v$sql_plan. При этом можно использовать модификацию указанного выше ручного запроса, а идентификаторы конкретного запроса вытащить, например, из v$sql_text


Как подготовить хранимый план исполнения ?

[v.11+] Ремарка - наиболее удобные возможности фиксации плана представлены в пакете SQL Plan Management (SPM), в моей отдельной статье приведён более полный обзор методов фиксации плана

[v.9+] Метод подмены инструкций каркасных планов исполнения выглядит так

  • готовится оригинальный запрос и модифицированный подсказками до получения требуемого плана исполнения
  • в сессии пользователя с привелегиями (create any outline, alter any outline, drop any outline) включается сбор каркасных планов и собираются планы оригинального и модифицированного запросов
sqlplus> alter session set create_stored_outlines = имя_категории_без_кавычек ;
sqlplus> оригинальный запрос
sqlplus> модифицированный запрос
sqlplus> alter session set create_stored_outlines = false ;
-- альтернатива через приватные аутлайны для сессии
sqlplus> create or replace private outline POL_SRC on полный_текст_проблемного_запроса ;
sqlplus> create or replace private outline POL_TGT on полный_текст_корректированного_запроса ;

Данные собранных каркасных планов хранятся в таблицах outln.ol$ (список каркасных планов) и outln.ol$hints (инструкции исполнения) и (с 10 версии) outln.ol$nodes, соединение таблиц идёт по полю OL_NAME. Идея заключается в том, чтобы в таблице инструкций вычистить подсказки для начального запроса и выставить поле OL_NAME для подсказок модифицированного запроса в значение начального запроса. В результате после активации хранимых планов в выбранной ранее категории имя_категории_без_кавычек при выполнении начального запроса будут использоваться подсказки модифицированного запроса

-- удалить детализирующие строки проблемного (SRC) запроса
sqlplus> delete from ol$hints where ol_name = 'POL_SRC' ;
sqlplus> delete from ol$nodes where ol_name = 'POL_SRC' ;
-- сменить принадлежность детализирующих строк оптимизированного (TGT) запроса на SRC
sqlplus> update ol$hints set ol_name = 'POL_SRC' where ol_name = 'POL_TGT' ;
sqlplus> update ol$nodes set ol_name = 'POL_SRC' where ol_name = 'POL_TGT' ;
-- обновить outline (пакет описан в документации только до 10 версии включительно,
-- в более поздних отрабатывает, но работает и без обновления)
sqlplus> execute immediate dbms_outln_edit.refresh_private_outline('POL_SRC'));

Активация производится командой alter session (system) set use_stored_outline = имя_категории_без_кавычек ; Для создания публичного аутлайна из приветного можно использовать команду create public outline PUBOL_xxxx from private POL_SRC for category outenbl ;


Как выявить наиболее "тяжёлые" запросы ?

[v.8] Запросы в разобранном виде помещаются в библиотечный кэш, и для каждого из них на время жизни в кэше Oracle хранит статистику, по которой можно найти наиболее ёмкие по тому или иному ресурсу запросы. Если библиотечный кэш сконфигурировано корректно (его хватает и не происходит постоянного вытеснения), то планы исполнения запросов после разбора, а вместе с ними и статистика, могут сохраняться довольно долго, что позволяет при периодическом снятии статистики пакетом statspack захватывать и эти данные. Поэтому statspack может отражать наиболее тяжёлые запросы с непрерывным охватом, даже несмотря на периодичность его запуска. Из системных представлений имеет смысл обратить на v$sql, v$sqlarea и смежные с ними


Как ограничить доступ посредством SQL Net по IP адресу

[v.9+]В общем случае разрешенные IP адреса перечисляются в файле sqlnet.ora, расположенном в каталоге с конфигурацией требуемого листенера (значение переменной TNS_ADMIN) - для версии Oracle 9. Также пришлось напрорться в 9 версии на то, что команда lsnrctl имя_листенера RELOAD не перегружает конфигурацию, и результат получается после пары команд lsnrctl имя_листенера STOP; lsnrctl имя_листенера START; приводящей, однако, ко временной (очень краткой) невозможности подключения новых сессий через переконфигурируемый листенер


Как перенести софт движка в другой каталог ?

[v.9+] Можно просто вынести софт в новый каталог, создав символическую ссылку со старым именем, указывающую на новое место расположения. Альтернативно можно перенести софт в новое место расположения, выставить переменную ORACLE_HOME и воспользоваться поставляемым в составе движка скриптом $ORACLE_HOME/bin/relink

Кроме того существует вариант от вендора с использованием специальной скриптовой обвязки, которая позволяет параллельно с перелинковкой поддерживать в актуальном состоянии oraIbventory. Этот вариант опробован практически, в том числе при обновалении БД под SAP, и описан к отдельном разделе книги по установке СУБД (например для Linux)


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

[v.11+] Скрипт $ORACLE_HOME/install/unix/rootadd.sh добавляет разрешения на каталоги и файлы софта движка Oracle локальным пользователям сервера. Альтернативой является установка отдельного клиента на этом же сервере


Как выделить экземпляру v.11 больше половины оперативной памяти в Linux?

[v.11+] Этот момент часто связывается с установкой 64bit версии операционной системы, что позволяет оперировать более, чем 4Гб оперативной памяти. При попытке создания базы и указания автоматического управления памятью ASMM размер /dev/shm должен быть не меньше, чем задаваемый размер памяти. По умолчанию этот раздел монтируется через tmpfs с настройками по умолчанию, отгребающими половину свободной памяти. Для изменения размера необходимо добавить параметр size=размер в соответствующую строку fstab, или использовать ручное управление памятью, что не так уж и плохо


Как получить доступ под пользователем Oracle, не зная пароля

[v.8+] В общем случае провести какие - либо действия в базе под именем определенного пользователя может тот, кто имеет администраторские права в базе (т.е. sys или имеющий привилегию sysdba) - путем сохранения хэша старого пароля, смены пароля пользователя на произвольный для проведения каких либо действий и последующего восстановления пароля

Итак, сначала запросом SELECT * FROM DBA_USERS WHERE USERNAME = 'имя_пользователя'; вытаскивается существующий хэш пароля пользователя. Далее командой ALTER USER имя_пользователя IDENTIFIED BY новый_пароль; пароль меняется на произвольный новый. Далее под новым паролем можно войти в базу и провести необходимые изменения. В конце работ необходимо восстановить прежний пароль пользователя командой ALTER USER имя_пользователя IDENTIFIED BY VALUES 'хэш_старого_пароля' ;

Наличие кавычек является в последней команде обязательным. Что еще можно сказать по теме - соблюдайте законность. Автор и его коллеги время от времени использует этот метод как штатное средство решения административных задач, и обращает внимание читателя, что использование этого метода возможно, если есть права администратора в базе, злонамеренное использование этого метода является явным нарушением Законов РФ и может повлечь ответственность. Также автор слышал, что в версии 10 Oracle этот метод более не работает (в 9 и 8 работает точно), но автор не проверял достоверность этого заявления


Как посмотреть скрытые параметры и активированные инициализационные события экземпляра ?

[v.9+] Есть соответствующие запросы:

select KSPPINM, KSPPDESC, KSPPSTVL, KSPPSTDVL, KSPPSTDF from X$KSPPSV a, x$ksppi b where a.indx = b.indx ;
для явно выставленных - select name,description from v$parameter where name like '\_%'ESCAPE'\' ;
select (translate(value,chr(13)||chr(10),'')) from s$parameter2 where upper(name) = '_TRACE_EVENTS' and isdefault = 'FALSE' ;
select (translate(value,chr(13)||chr(10),'')) from s$parameter2 where upper(name) = 'TRACE' and isdefault = 'FALSE' ;


Как переименовать базу

[v.8+]В общем случае - сказать ALTER SYSTEB BACKUP CONTROLFILE TO TRACE; Далее сформировать из соответствующего вновь появившегося trace-файла команду создания нового контрольного файла. изменив место расположения файлов данных, а также заменив определение DATABASE имя_базы REUSED на SET DATABASE новое_имя_базы. Далее необходимо положить базу и, при необходимости перемещения, скопировать файлы данных, init файл и структуру каталогов в новое место. После чего правится имя базы в init файле, а также пути к данным, контрольным файлам и т.д. Далее старые контрольные файлы перемещаются куда нибудь, база поднимается в NOMOUNT и подготовленным их трэйса скриптом создаются контрольные файлы. После чего командой ALTER DATABASE OPEN RESETLOGS база переводится в рабочий режим - уже с новым именем

Нужно понимать, что новой инкарнации (RESETLOGS) при переименовании не избежать, т.к. оперативные журналы в любом случае начинают писаться с нуля. Также надо понимать, если скрипт создания новых контрольных файлов не своримрован. его придется сформировать. разово запустив базу со старым именем - из чего есть следствие - нельзя запустить 2 базы с одним именем на одном хосте. Это нужно учитывать


Как добавлять/удалять группы оперативных журналов

[v.8+] Тонкость в понимании того, что такое текущая, и что такое активная журнальные группы, а также нужно знать команды ALTER SYSTEM SWITCH LOGFILE, ALTER SYSTEM CHECKPOINT, ALTER SYSTEM ARCHIVE LOG (ALL etc...). Общая последовательность - добавить новые журнальные группы, переключить журнальные группы и (при необходимости) активировать запись архивных журналов так, чтобы удаляемые (при необходимости) журнальные группы не имели статуса активной (требуемой для восстановления после сбоя экземпляра) или текущей группы, после чего можно удалять соответствующую группу. Детальнее - позднее


Как собрать системную статистику для оптимизатора ?

Как собрать объектную статистику для оптимизатора ?

[v.9+] Основным средством является пакет DBMS_STATS, часть функций которого и приведена ниже

-- управление таблицей статистики
DBMS_STATS.CREATE_STAT_TABLE('владелец', 'имя_таблицы') ;
DBMS_STATS.DELETE_TABLE_STATS('владелец', 'имя_таблицы');
-- активация мониторинга необходимости сбора статистики
DBMS_STATS.ALTER_SCHEMA_TABLE_MONITORING(схема|NULL=текущая,TRUE|FALSE) ;
DBMS_STATS.ALTER_DATABASE_TABLE_MONITORING(TRUE|FALSE,TRUE|FALSE - охватывать объекты словаря) ;
DBMS_STATS.FLUSH_SCHEMA_MONITORING_INFO(схема|NULL=текущая) ;
DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO ;.
-- сбор объектной статистики
DBMS_STATS.GATHER_INDEX_STATS(OWNER,INDEX_NAME,STATTAB=>'имя_таблицы'|NULL,STATID=>'идентификатор_статистики'|NULL,
           STATOWN=>'владелец_таблицы'|NULL,GRANULARITY=>'DEFAULT|SUBPARTITION|PARTITION|GLOBAL|ALL'|NULL,
           CASCADE=>TRUE|FALSE) ;
DBMS_STATS.GATHER_TABLE_STATS(OWNER,TABLE_NAME,STATTAB=>'имя_таблицы'|NULL,STATID=>'идентификатор_статистики'|NULL,
           STATOWN=>'владелец_таблицы'|NULL,GRANULARITY=>'DEFAULT|SUBPARTITION|PARTITION|GLOBAL|ALL'|NULL,
           METHOD_OPT=>[FOR ALL [INDEXED | HIDDEN] COLUMNS [size_clause] |
                        FOR COLUMNS [size clause] column|attribute SIZE {integer | REPEAT | AUTO | SKEWONLY}..
                            [,column|attribute [SIZE {integer | REPEAT | AUTO | SKEWONLY} ]...], |
                        вёдер_гисторгаммы (от 1 до 254) | REPEAT | AUTO | SKEWONLY],
           CASCADE=>TRUE|FALSE) ;
DBMS_STATS.GATHER_SCHEMA_STATS(OWNER,STATTAB=>'имя_таблицы'|NULL,STATID=>'идентификатор_статистики'|NULL,
           STATOWN=>'владелец_таблицы'|NULL,GRANULARITY=>'DEFAULT|SUBPARTITION|PARTITION|GLOBAL|ALL'|NULL,
           METHOD_OPT=>[FOR ALL [INDEXED | HIDDEN] COLUMNS [size_clause] |
                        FOR COLUMNS [size clause] column|attribute SIZE {integer | REPEAT | AUTO | SKEWONLY}..
                            [,column|attribute [SIZE {integer | REPEAT | AUTO | SKEWONLY} ]...], |
                        вёдер_гисторгаммы (от 1 до 254) | REPEAT | AUTO | SKEWONLY],
           CASCADE=>TRUE|FALSE,
           OPTIONS=>[GATHER|GATHER AUTO|GATHER STALE|GATHER EMPTY|LIST AUTO|LIST STALE|LIST EMPTY) ;
DBMS_STATS.GATHER_DATABASE_STATS(
           GRANULARITY=>'DEFAULT|SUBPARTITION|PARTITION|GLOBAL|ALL'|NULL,
           METHOD_OPT=>[FOR ALL [INDEXED | HIDDEN] COLUMNS [size_clause] |
                        FOR COLUMNS [size clause] column|attribute SIZE {integer | REPEAT | AUTO | SKEWONLY}..
                            [,column|attribute [SIZE {integer | REPEAT | AUTO | SKEWONLY} ]...], |
                        вёдер_гисторгаммы (от 1 до 254) | REPEAT | AUTO | SKEWONLY],
           CASCADE=>TRUE|FALSE),
           OPTIONS=>[GATHER|GATHER AUTO|GATHER STALE|GATHER EMPTY|LIST AUTO|LIST STALE|LIST EMPTY) ;
-- функции ручных отображения и модификации статистик
GET|SET|DELETE_INDEX|TABLE|COLUMN|DATABASE|SYSTEM_STATS() ;
-- сбор системной статистики
DBMS_STATS.GATHER_SYSTEM_STATS('NOWORKLOAD'|'INTERVAL|['START'|'STOP'],интервал_минут|NULL,таблица_статистики|NULL,
           ID_статистики|NULL,владелец_таблицы|NULL) ;.
-- импорт и экспорт собранной статистики
DBMS_STATS.IMPORT_SYSTEM_STATS('таблица_статистики','ID_статистики','владелец_таблицы'|NULL);
DBMS_STATS.EXPORT|IMPORT_SYSTEM|DATABASE|SCHEMA|TABLE_INDEX|COLUMN_STATS(OWNNAME=>'владелец объекта/схемы',
           TABNAME|INDNAME=>'имя_объекта',COLNAME=>'имя_колонки',STATTAB=>'таблица_статистики',
           STATID=>'ID_статистики',STATOWN=>'владелец_таблицы_статистики', CASCADE=>TRUE|FALSE) ;
--
# для таблиц можно сказать 
ALTER TABLE xxx MONITORING ;
exec dbms_stats.gather_schema_stats(схема, options => 'gather stale');
exec dbms_stats.gather_schema_stats(схема, options => 'gather empty');

Как вывести oracle из ступора при падении инстанса в режиме BEGIN BACKUP

[v.89] Если экземпляр упал в процессе создания горячего бэкапа методом BEGIN BACKUP/END BACKUP, то восстановление экземпляра после перехода в режим MOUNT напорется на то, что часть файлов данных (или все) будет находиться в BEGIN BACKUP. Используя представление v$backup вычислить открытые в режиме BEGIN BACKUP файлы и сказать им ALTER DATAFILE file# END BACKUP, после чего база сможет перейти из MOUNT в режим OPEN. Если есть необходимость оперировать не только системными номерами файлов, но и их именами, можно посмотреть имена в представлении v$datafile

Имеет смысл рассмотреть использование RMAN в качестве утилиты для создания/восстановления бэкапа, созревшей к 9 версии Oracle и имеющей много плюсов по сравнению с прежним механизмом горячего резервирования. Также заявлено, что в версии 9 можно "окучить" все зависшие в BEGIN BACKUP файлы данных одной командой ALTER DATABASE END BACKUP, и это работает. Но вот сделать BEGIN BACKUP на всю базу вы не сможете, как и раньше этот режим придётся включать для каждого табличного пространства отдельно


Как выявить все права, выданные пользователю или роли

[v.8+] Гранты отражены в следующих представлениях: DBA_SYS_PRIVS - системные привилегии, DBA_TAB_PRIVS - объектные привилегии, DBA_COL_PRIVS - объектные привилегии на столбцы

Вытащить их можно обычным select'ом. Также имеет смысл учитывать, что пользователю могут быть присвоены определенные роли, часть из которых или все могут быть активированы в произвольной сессии. Поэтому эффективные права могут отличаться от присвоенных непосредственно объекту


Как восстанавливать сбойные блоки ?

[v.11+] Сбойные блоки выявляются командами RMAN, ANALYSE (а также DBVerify) и доступны в представлении V$DATABASE_BLOCK_CORRUPTION, а восстанавливаются поимённо или скопом командами:

rman> BLOCKRECOVER DATAFILE 2 BLOCK 15 DATAFILE 3 BLOCK 44 ;
rman> BLOCKRECOVER CORRUPTION LIST;

Однако это для случая, когда используется RMAN. Если используется "user managed" резервирование данных, методом является восстановление из копии с последующим подкатом изменений из архивных журналов. Кроме того с версии 11.2 появилась автоматическая возможность восстанавливать сбойные блоки с физического стэндбая (Data Guard)


Как восстановить рядом с работающей вторую копию БД с тем же именем ?

[тест на v.12+] Пошагово:

  • Подготовить pfile с новыми путями, в т.ч. для контрольных файлов, и уникальным параметром DB_UNIQUE_NAME - без него экземпляр с новым SID стартует, но не смонтируется, новым orapw, создать при необходимости каталог аудита и стартовать экземпляр с отдельным ORACLE_SID (системным идентификатором) в nomount
  • зайти в rman target=/, сказать set DBID=xxx (подсмотреть в работающей БД) и восстановить контролфайл restore controlfile from 'полный_путь_к_бэкапу', после чего смонтировать БД alter database mount
  • вытащить имена файлов базы командами select name from v$datafile ; select name from v$tempfile ; select name from v$controlfile ; select member from v$logfile ;
  • перейти в новый экземпляр в sqlplus и переименовать оперативные журналы командой alter database rename file 'старый_путь' to 'новый_путь' ;
  • подготовить rman скрипт с блоком указания точки восстановления и переименования файлов данных и временных и восстановить базу: run { set until sequence xxx ; set newname for datafile 'старый_путь' to 'новый_путь' ; ... set newname for datafile 'старый_путь' to 'новый_путь' ; restore database ; switch datafile all ; restore database ; alter database open resetlogs ; }

Можно отдельно восстанавливать архивные журналы в новый путь, указав в блоке rman { set archivelog destination to 'новый_путь' ; ... }

В случае в ASM файлы данных также нужно переименовать. Практические эксперименты показывают, что, если этого не сделать - будут перезаписаны файлы данных на первой, всё ещё работающей базе, что приведёт к краху. Поэтому скрипты готовим пофазно с проверкой (сначала отрабатываем без restore database и switch datafile all ;) и очень осторожно, а лучше - избегаем такой активности вообще


Что добавить в init новой БД ?

[v.10+] Если хватает производительности, выставить DB_BLOCKS_CHECKSUM = TYPICAL и DB_BLOCK_CHECKING = FULL (для 11.x можно ещё посмотреть в сторону DB_ULTRA_SAFE), выставить LOG_CHECKPOINTS_TO_ALERT. Для user managed standby LOG_CHECKPOINT_INTERVAL или LOG_CHECKPOINT_TIMEOUT. LOG_ARCHIVE_MIN_SUCCESSED_DEST для standby. TIMED_STATISTIC = TRUE, TRACE_ENABLED = TRUE и MAX_DUMP_FILE_SIZE = побольше


Как управлять сервисами ?

[v.10+] ... позже


Как перенести работающую таблицу в другое табличное пространство

[v.8+] Зависит от версии. Если это 8.1.7 и выше, то для части таблиц вам поможет команда move. С 9 версии Oracle расширилось количество типов переносимых командой move таблиц, а также появился пакет redifinition. А вот в более ранних версиях процедура перевода нетривиальна, особенно если есть активные правила проверки целостности, в т.ч. внешние ключи в других таблицах, указывающих на таблицы, которые необходимо перенести. Детально - позднее ...


Как перенести обьекты табличного пространства в другое ?

[v.10+] Вариантов много. Экспорт/импорт, DBMS_REDIFINITION для таблиц. Ещё один вариант представлен ниже. Таблицы можно перенести командой move, указав новое табличное пространство. Например "ALTER TABLE имя_таблицы MOVE TABLESPACE имя_нового_табличного_пространства LOB(имя_поля) STORE AS (TABLEPACE имя_нового_табличного_пространства_для_LOB) ;"

Частным случаем является IOT, которая также переносится командой MOVE, однако для индекс ориентированных таблиц табличное пространство в dba_tables не отображается, ибо они хранятся в индексе! Можно отловить имена индексов примерно таким запросом:
select dc.table_name,dc.index_name,dt.owner,dt.tablespace_name from dba_constraints dc, dba_segments ds, dba_tables dt where dc.index_name = ds.segment_name and ds.segment_type = 'INDEX' and ds.tablespace_name = 'имя_табличного пространства' and dc.table_name = dt.table_name and dc.owner = dt.owner ;

Обычные индексы перестроить командой "ALTER INDEX имя_индекса REBUILD TABLESPACE новое_табличное_пространств ONLINE ;" Партицированные индексы можно перестроить аналогичной командой "ALTER INDEX имя_индекса REBUILD PARTITION имя_партиции TABLESPACE имя_нового_табличного_пространства ;"

Для отлова партицированных индексов и создания запросов по модификации можно использовать похожие на мои запросы:

-- просмотр партицированных объектов с подобъектами
select do.object_name,do.subobject_name,do.object_type
       from dba_objects do, dba_segments ds
       where do.subobject_name = ds.segment_name and
             ds.tablespace_name = 'имя_текущего_табличного_пространства' ;
-- а также
select owner,segment_name,partition_name,segment_type 
       from dba_segments
       where TABLESPACE_NAME = 'имя_текущего_табличного_пространства'
       order by 1,2 ;

-- подготовка запроса на перестроение партицированного индекса
select 'alter index '||index_name||' rebuild partition '||partition_name||'
       tablespace имя_нового_табличного_пространства ;'
       from dba_ind_partitions.
       where (index_owner,index_name)
             IN (select owner,segment_name from dba_segments where
                TABLESPACE_NAME = 'имя_текущего_табличного_пространства'
                group by owner,segment_name)
       order by index_owner,index_name ;
-- упрощённая альтернатива
select 'alter index '||owner||'.'||segment_name||' rebuild partition '||
       partition_name||' tablespace имя_нового_табличного_пространства ;'.
       from dba_segments 
       where TABLESPACE_NAME = 'имя_текущего_табличного_пространства'
             and segment_type = 'INDEX PARTITION'
       order by owner,segment_name ;

Как проводить поиск в полях типа LONG ?

[v.9+] Напрямую это невозможно. Однако можно нарисовать функцию, делающую выборку из поля типа LONG и преобразование к строковому типу небольшой начальной части, после чего искать в возвращённой переменной искомое значение. Ниже приведён пример функции для поиска в тексте материализованного представления:

set verify off linesize 3000 pagesize 4000 hea off ;
spool &1 ;
set serveroutput on

CREATE OR REPLACE FUNCTION BSS_GET_MVIEW_QUERY (mview_name VARCHAR2)
       RETURN VARCHAR2 AS
flong long ;
fvar VARCHAR2(15000) ;
BEGIN
-- 2008 (C) S.S.Belonin
select query into flong from dba_mviews
       where mview_name = mview_name and rownum = 1;
fvar := DBMS_LOB.SUBSTR(flong,1000) ;
return fvar ;
END ;
/

show errors
spool off ;
set hea on ;
exit ;

-- поиск производится таким запросом
-- select * from (select mview_name,UPPER(bss_get_mview_query(mview_name)) qtext
--                       from dba_mviews) where qtext like '%имя_таблицы%' ;

Как лечить ORA-06512: at "DBSNMP.BSLN_INTERNAL", line 2073 ?

[v.11+] Ситуация вызвана неконсистентностью даных baselines, и требует пересоздания пользователя DBSNMP скриптами @?/rdbms/admin/catnsnmp.sql, @?/rdbms/admin/catsnmp.sql. Есть описание на Metalink [ID 736627.1]


Где взять патч 11.2.0.2 СУБД ?

[v.11+] Это "patchset 10098816". С версии релиза СУБД 11 оформленное Patchset'ом обновление релиза является полным дистрибутивом, который рекомендуется разворачивать не поверх текущего, а рядом с ним. Ссылка требует учетки. Кстати с недавнего времени скачать патчи с edelivery.oracle.com уже нельзя, только updates, доступны только копии опубликованных на сайте дистрибутивов. Насколько я помню, раньше патчи тож были доступны


Как отследить порчу блоков данных ?

[v.10+]


Как управлять памятью экземпляра ?

[v.10+]


 
     
   
   
    Нравится      

(C) Белонин С.С., 2000-2018. Дата последней модификации страницы:2018-01-17 14:13:24