Работа в режиме archivelog + standby
Для корректной работы в таком режиме, то есть что бы иметь максимальные шансы на удачное восстановление системы из standby необходимо (или максимально желательно) не проводить в базе действия с опцией nolog
Для этого нужно убедиться, что в базе нет объектов, созданных с такой опцией.
SELECT owner, table_name FROM ALL_TABLES WHERE LOGGING='NO';
SELECT owner, index_name FROM ALL_INDEXES WHERE LOGGING='NO';
Для исправления ситуации можно воспользоваться pl/sql блоком, взятым из форума на sql.ru. Он контролирует больше типов проблемных объектов. Если прав хватает, то можно удалить в курсоре ограничение по пользователю SYSTEM.
DECLARE
CURSOR c IS
SELECT 'alter table ' || owner || '.' || table_name || ' logging' ss FROM DBA_TABLES
WHERE LOGGING<>'YES' AND TEMPORARY<>'Y' AND owner<>'SYSTEM'
UNION
SELECT 'alter table ' || owner || '.' || table_name || ' logging' ss FROM DBA_PART_TABLES
WHERE table_name NOT LIKE '%LOB%' AND def_logging<>'YES' AND owner<>'SYSTEM'
UNION
SELECT 'alter table ' || table_owner || '.' || table_name || ' modify partition
' || partition_name || ' logging' ss
FROM DBA_TAB_PARTITIONS WHERE LOGGING<>'YES' AND table_owner<>'SYSTEM'
UNION
SELECT 'alter index ' || owner || '.' || index_name || ' logging' ss FROM DBA_INDEXES
WHERE LOGGING<>'YES' AND index_type<>'LOB' AND owner<>'SYSTEM'
UNION
SELECT 'alter index ' || owner || '.' || index_name || ' logging' ss FROM DBA_PART_INDEXES
WHERE table_name NOT LIKE '%LOB%' AND def_logging<>'YES' AND owner<>'SYSTEM'
UNION
SELECT 'alter index ' || index_owner || '.' || index_name || ' modify partition
' || partition_name || ' logging' ss
FROM DBA_IND_PARTITIONS WHERE LOGGING<>'YES' AND index_owner<>'SYSTEM'
UNION
SELECT 'alter table ' || owner || '.' || table_name || ' move lob (' || column_name
|| ') store as (nocache logging)' ss FROM DBA_LOBS WHERE LOGGING<>'YES'
AND (owner, table_name) NOT IN (SELECT owner, table_name FROM DBA_TABLES WHERE
TEMPORARY='Y') AND owner<>'SYSTEM'
;
BEGIN
FOR r IN c LOOP
EXECUTE IMMEDIATE r.ss;
END LOOP;
END;
/
Кроме того во вьюшке v$datafile можно посмотреть в каких файлах зафиксированы действия, не подлежащие восстановлению через log-файлы
SELECT unrecoverable_change#,unrecoverable_time,NAME FROM v$datafile;
Stanby база должна быть создана (или пересоздана) позже максимальной даты из этого запроса.
Какие ещё причины могут послужить источником неприятностей при восстановлении standby базы ?
Теоретически это
При проверке на создание таблицы, наполнение её с /*+append*/ и создание индекса с nologging , в v$datafile отразилось только создание индекса. Логи накатились без замечаний, в alert_log тоже замечаний не было.
Чем это может грозить:
Самый худший вариант - это рабочая таблица с опцией nologging - изменения в standby базу не попадают ;
Индекс с опцией nologging - при восстановлении базы, возможно прийдётся пересоздать такой индекс;
Обычные таблицы с опцией nologging в качестве временных. То есть заполнили, поизменяли, всё стёрли - пока не знаю :(
Внешнее проявление ошибок - на standby базе в trace - файлах могут появляются записи типа
Recovery is repairing media corrupt block 32491 of file 8
Если stanby базу перевести в нормальный рабочий режим, то можно узнать в какой таблице или индексе были проблемы
SELECT * FROM DBA_EXTENTS WHERE file_id=8 AND block_id=32491
Если это индекс, то его можно просто пересоздать, но если это таблица, то это уже похуже.
Исправление ситуации:
Вариант первый (самый громоздкий) - пересоздать stanby базу. Для крупных баз и баз работающих в режиме 365*24 это не самый лучший вариант.
Вариант 2 - пропустить команду для нужного таблспэйса
ALTER TABLESPACE USR BEGIN BACKUP; (иногда это может быть дост. длит.операция)
и скопировать его вместо подпорченного в stanby базе
и ALTER TABLESPACE USR END BACKUP;
или ALTER DATABASE END BACKUP (9i); для всех файлов данных.
Вариант 3. Воспользоваться утилитой dbverify или exp - только для проверки целостности таблспэйсов.
Вариант 4. Воспользоваться пакетом dbms_repair для восстановления битых объектов.