Точное восстановление базы Oracle с помощью TSPITR и LogMiner на примерах

Все рассмотренные до сих пор приемы показали, что как RMAN, так и пользовательские стратегии восстановления представляют собой надежные методы для восстановления баз данных при наличии проблемы с носителем. Однако предположим, что требуется всего лишь отменить какие-то изменения в базе данных Oracle Database. Даже процедуры неполного восстановления, хотя они и позволяют избавиться от нежелательных изменений, будут приводить к потере данных. Кроме того, в некоторых случаях бывает просто невозможно определить, когда точно было внесено изменение и, следовательно, выполнить точное неполное восстановление. При выполнении восстановления всей базы данных может также понадобиться закрыть базу данных от пользователей на время процесса восстановления.

К счастью, доступны несколько других более точных методов восстановления, которые можно использовать при наличии более конкретных потребностей. В их число входят процедура TSPITR, утилита LogMiner и функция Flashback Query. Процедура TSPITR позволяет восстанавливать табличное пространство до состояния, в котором оно находилось на определенный момент времени в прошлом, утилита LogMiner, которую Oracle поставляет бесплатно — выполнять чрезвычайно точное восстановление на основе считывания изменений, зафиксированных в журналах повторного выполнения, а функция Flashback Query — выявлять и восстанавливать утраченные или по ошибке зафиксированные неправильные данные. В зависимости от имеющихся потребностей, один из этих альтернативных методов может оказаться более удобным способом для устранения связанных с потерей данных проблем, по сравнению с проведением восстановления базы данных при каждом возникновении необходимости просто отменить результаты какой-нибудь ошибки приложения.

 

Восстановление табличного пространства до состояния на определенный момент времени в прошлом (TSPITR)

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

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

 

Применение RMAN для выполнения TSPITR

Восстановление табличных пространств из базы данных (целевой (target)) сначала предусматривает выполнение процедуры восстановления до состояния на определенный момент времени в прошлом (PITR) во временном экземпляре, называемом вспомогательной (auxiliary) базой данных, который создается исключительно для выполнения роли промежуточного участка в процессе восстановления табличных пространств.

Ниже перечислены шаги, требуемые для выполнения процедуры TSPITR с помощью утилиты RMAN.

1. Создайте вспомогательную базу данных. Используйте для вспомогательного экземпляра скелет файла параметров инициализации вместе с такими строками: 

db_name=help (this is the target database_name)
db_file_name_convert=('/oraclehome/oradata/target/', '/tmp/')
/* Преобразование имен файлов данных целевой базы данных */
log_file_name_convert=('/oraclehome/oradata/target/redo', '/tmp/redo')
/* Преобразование имен файлов журналов повторного выполнения,
принадлежащих целевой базе данных */
instance_name=aux
control_files=/tmp/control1.ctl
compatible=11.1.0
db_block_size=8192

2. Запустите вспомогательную базу данных в режиме NOMOUNT:

$ sqlplus /nolog
SQL> CONNECT sys/oracle@aux AS sysdba
SQL> STARTUP NOMOUNT PFILE = /tmp/initaux.ora 

3. Сгенерируйте некоторые архивные журналы повторного выполнения и подготовьте резервную копию целевой базы данных. Для генерации архивных файлов журналов повторного выполнения можно использовать команду ALTER SYSTEM SWITCH LOGFILE.

4. Подключитесь ко всем трем базам данных — базе данных каталога, целевой базе данных и вспомогательной — следующим образом: 

$ rman target sys/sys_passwd@nick catalog rman/rman1@nina
auxiliary system/oracle@aux

5. Выполните процедуру TSPITR. При желании провести восстановление, например, до конкретного времени, можно воспользоваться следующим оператором (при условии, что формат NLS_DATE выглядит как Mon DD YYYY HH24:MI:SS (Мес ДД ГГГГ ЧЧ24:ММ:СС)):

RMAN> RECOVER TABLESPACE users UNTIL TIME ('JUN 30 2005 12:00:00');

Это обманчиво простой шаг, потому что на самом деле во время этого шага утилита RMAN выполняет целый ряд задач, а именно — восстанавливает файлы данных из табличного пространства users во вспомогательной базе данных, потом проводит для них процедуру RECOVER на основании указанного времени, а затем экспортирует метаданные о содержащихся в табличных пространствах объектах из вспомогательной базы данных в целевую, а также применяет команду SWITCH для указания управляющему файлу на новые только что восстановленные файлы данных.

6. По завершении процесса восстановления переведите табличное пространство users в оперативный режим: 

$ rman target sys/sys_passwd@nick
RMAN> SQL "alter tablespace users online";
RMAN> Exit;

7. Остановите вспомогательный экземпляр и удалите все управляющие файлы, файлы журналов повторного выполнения и файлы данных, которые имеют к нему отношение.

 

Применение утилиты LogMiner для выполнения точного восстановления

Oracle предлагает замечательную утилиту LogMiner, которая помогает выполнять точное восстановление за счет использования данных, зафиксированных в журналах повторного выполнения. Утилита LogMiner может считывать содержимое журналов повторного выполнения, что открывает целый ряд возможностей. Напоминаем, что в журналах повторного выполнения содержится информация о хронологии вносившихся в базу данных изменений. Хотя способностью утилиты LogMiner считывать журналы повторного выполнения и можно пользоваться для выполнения связанных с обеспечением безопасности и проведением аудита задач, в настоящей главе главный интерес представляет исключительно ее применение для целей восстановления.

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

Утилита LogMiner упрощает выполнение точного восстановления за счет устранения нежелательных изменений из таблицы. Помимо того, что она служит замечательным инструментом для точного восстановления, она еще помогает воссоздавать SQL-операторы и тем самым оказывать помощь при проведении аудита и отладки. Ее также можно использовать для определения периода времени, во время которого произошло логическое повреждение.

Для извлечения информации из журналов повторного выполнения утилита LogMiner предусматривает использование поставляемых Oracle пакетов DBMS_LOGMNR и DBMS_LOGMNR_D (вместе с другими менее важными пакетами). Помимо этого она еще также предусматривает использование нескольких динамических представлений производительности для оказания помощи в анализе информации, содержащейся в журналах повторного выполнения. Предоставлять обычным пользователям доступ к пакетам, владельцем которых является пользователь SYS, можно путем назначения им роли EXECUTE_CATALOG_ROLE. Чтобы позволить LogMiner сопоставлять ее собственные идентификаторы объектов с реальными именами объектов базы данных, необходимо указывать применяемый словарь данных, наиболее простым вариантом для чего является назначение LogMiner обычного словаря данных, который принадлежит базе данных.

В представлении V$LOGMNR_CONTENTS содержится масса информации, которую LogMiner использует для оказания помощи в устранении нежелательных изменений из данных таблицы. Ниже приведен краткий перечень фиксируемых в этом представлении сведений:

  • метка времени;
  • имя пользователя;
  • тип действия (вставка, обновление, удаление или DDL);
  • номера транзакций и SCN-номера;
  • таблицы, задействованные в транзакции;
  • реконструированный SQL-код, приведший к изменениям;
  • SQL-код, который отменит изменение, если потребуется.

Как работает утилита LogMiner

Утилита LogMiner считывает файлы журналов повторного выполнения и помещает извлекаемую информацию в представление V$LOGMNR_CONTENTS, к которому затем можно выполнять запросы и получать детали об интересующих транзакциях. Из-за того, что информация в журналах повторного выполнения хранится в виде внутренних идентификаторов объектов и данных в шестнадцатеричном формате, в Oracle рекомендуют обеспечить утилиту LogMiner доступом к словарю данных, чтобы она могла преобразовывать содержимое этих журналов в удобную для немедленного восприятия форму.

Обеспечивать LogMiner доступом к словарю данных можно тремя способами:

  • извлечением словаря данных в плоский файл;
  • размещением снимка словаря данных в журналах повторного выполнения;
  • указанием LogMiner использовать словарь данных в оперативном режиме.

Обратите внимание, что утилита LogMiner не показывает всех SQL-операторов, которые есть в журнале повторного выполнения; она отображает лишь конечный оператор, который потребуется применить к базе данных для отмены нежелательных изменений.

Дополнительная журнализация

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

Типы дополнительной журнализации

Существуют два типа дополнительной журнализации, отличающиеся друг от друга набором дополнительных столбцов, регистрируемых в журнале. Этот набор дополнительных столбцов называется группой дополнительных журналов (supplemental log group); при более ограниченной дополнительной журнализации применяется условная группа дополнительных журналов (conditional supplemental log group), а при более универсальной — безусловная группа дополнительных журналов (unconditional supplemental log group).

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

SQL> ALTER TABLE hr.employees
ADD SUPPLEMENTAL LOG GROUP key_info(empno, ename)
FROM hr.employees ALWAYS;

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

SQL> ALTER TABLE hr.employees
ADD SUPPLEMENTAL LOG GROUP key_info(empno,ename)
FROM hr.employees;

Уровни дополнительной журнализации

Дополнительную журнализацию можно включать на двух уровнях — на уровне базы данных и на уровне отдельных таблиц. В случае включения дополнительной журнализации на уровне всей базы данных следует иметь в виду, что это может негативно сказываться на производительности. Поэтому в таком случае лучше применять вариант минимальной дополнительной журнализации, который предусматривает оказание насколько возможно наименьшего воздействия на базу данных, но при этом все равно обеспечивает журнализацию информации, которая необходима для выявления и группирования операций, ассоциируемых с различными операторами DML. В Oracle настоятельно рекомендуют включать хотя бы такой уровень дополнительной журнализации, чтобы утилита LogMiner могла работать эффективным образом.

Для включения минимальной дополнительной журнализации на уровне базы данных применяется такая команда: 

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

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

SQL> ALTER TABLE HR.EMPLOYEES ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;

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


Извлечение словаря данных

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

Наиболее простым способом является использование существующего словаря данных, но он не работает с параметром DDL_DICT_TRACKING, а это означает отсутствие возможности отслеживать изменения в DDL. Кроме того, он лишает возможности отслеживать DML-операции, выполняемые в отношении таблиц, которые создаются после извлечения словаря.

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

Во время извлечения словаря в журналы повторного выполнения, с другой стороны, DDL-операторы выполняться не могут, что, следовательно, обеспечивает согласованность извлекаемого словаря. Поэтому лучше всего извлекать словарь данных в журналы повторного выполнения, поскольку этот способ гарантирует получение согласованной версии словаря данных и при этом также возможность отслеживать DDL-изменения.

Сеанс LogMiner

Прежде чем вызывать утилиту LogMiner, нужно обязательно создать для ее данных отдельное табличное пространство, потому что по умолчанию для нее используется табличное пространство System, а также удостовериться, что включена минимальная журнализация на уровне базы данных, как объяснялось в предыдущем разделе “Дополнительная журнализация”.

Давайте рассмотрим пример простого сеанса LogMiner с включенной минимальной дополнительной журнализацией. Обратите внимание на то, что права на владение пакетом DBMS_LOGMNR принадлежат пользователю SYS.

Первым делом необходимо извлечь словарь данных в журналы повторного выполнения. Пакет DBMS_LOGMNR_D создает словарь данных и сохраняет его в оперативных журналах повторного выполнения: 

SQL> EXECUTE sys.DBMS_LOGMNR_D.build( -
> OPTIONS => sys.DBMS_LOGMNR_D.store_in_redo_logs);
PL/SQL procedure successfully completed.
SQL>

Далее необходимо указать журналы, которые должны анализироваться LogMiner. Поскольку был выбран способ с извлечением словаря данных в журналы повторного выполнения, в процедуре DBMS_LOGMNR.ADD_LOGFILE нужно указать журналы повторного выполнения, в которых содержится словарь данных, плюс прочие журналы повторного выполнения, представляющие интерес. Для первого добавляемого файла следует использовать процедуру DBMS_LOGMNR.NEWFILE, а для всех остальных — процедуру DBMS_LOGMNR.ADDFILE.

Теперь можно обратиться к представлению V$ARCHIVED_LOG для выяснения того, в какие именно файлы журналов повторного выполнения был извлечен словарь данных при вызове процедур DBMS_LOGMNR_D.BUILD. Столбцы DICTIONARY_BEGIN и DICTIONARY_END покажут, в каких файлах журналов повторного выполнения содержится словарь данных. Необходимый запрос выглядит так: 

SQL> SELECT SEQUENCE#, DICTIONARY_BEGIN, DICTIONARY_END
2 FROM V$ARCHIVED_LOG;
SEQ# DIC DIC
     BEG  END
---- ---- -----
2    NO   NO
24   YES  YES
25   NO   NO
26   NO   NO
27   NO   NO
28   NO   NO
SQL>

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

SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE( -
> LOGFILENAME => 'C:\ORACLENT\RDBMS\ARC00024.001', -
> OPTIONS => DBMS_LOGMNR.NEW);
PL/SQL procedure successfully completed.
SQL>

Помимо этого, добавить в процедуру ADD_LOGFILE пакета DBMS_LOGMNR еще также нужно и прочие представляющие интерес файлы: 

SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE( -
> LOGFILENAME => 'C:\ORACLENT\RDBMS\ARC00025.001' , -
> OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQL procedure successfully completed.
SQL>
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE( -
> LOGFILENAME => 'C:\ORACLENT\RDBMS\ARC00026.001', -
> OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQL procedure successfully completed.
SQL>

Обратите внимание, что файлы журналов можно также добавлять и без строки OPTIONS, как показано ниже:

SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE( -
> LOGFILENAME => 'C:\ORACLENT\RDBMS\ARC00027.001');
PL/SQL procedure successfully completed. 

После указания файлов журналов повторного выполнения можно приступать к запуску утилиты LogMiner. В данном примере, помимо указания утилите LogMiner использовать в качестве источника словаря данных журналы повторного выполнения, включается функция отслеживания DDL, которая по умолчанию отключена: 

SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => -
> DBMS_LOGMNR.DICT_FROM_REDO_LOGS + -
> DBMS_LOGMNR.DDL_DICT_TRACKING );
PL/SQL procedure successfully completed.
SQL>

Применение LogMiner для анализа журналов повторного выполнения

После успешного запуска LogMiner можно приступить к выполнению команд в отношении таблицы V$LOGMNR_CONTENTS и получению информации о различных DML- и DDL-операторах, охватываемых набором файлов журналов повторного выполнения, который был добавлен ранее. При каждом обращении к представлению V$LOGMNR_CONTENTS будет выполняться поочередное считывание всех указанных журналов повторного выполнения и загрузка информации в представление V$LOGMNR_CONTENTS. В листинге 16.9 показан простой пример. 


SQL> SELECT SQL_REDO
2 FROM V$LOGMNR_CONTENTS
3* WHERE USERNAME='HR';
SQL_REDO
---------------------------------------------------------------------------
set transaction read write;
select * from "SYS"."DUAL" where ROWID = 'AAAADdAABAAAANnAAA' for update;
commit;
set transaction read write;
delete from "HR"."REGIONS" where "REGION_ID" = '5'
and "REGION_NAME" =
'northern europe' and ROWID = 'AAAHrNAAFAAAAESAAE';
delete from "HR"."REGIONS" where "REGION_ID" = '6'
and "REGION_NAME" =
'pacific region' and ROWID = 'AAAHrNAAFAAAAESAAF';
update "HR"."REGIONS" set "REGION_NAME" = 'eastern europe' where
"REGION_NAME" = 'northern africa' and ROWID = 'AAAHrNAAFAAAAESAAG';
commit;
10 rows selected.
SQL>

Здесь видно, что пользователь HR удалил две и обновил одну строку. Следовательно, LogMiner можно использовать для извлечения DML-оператора за прошлый период. Применение LogMiner дает еще одно дополнительное преимущество: позволяет извлекать SQL для выполнения отмены предыдущих DML-операторов, как показано в листинге 16.10. 


SQL> SELECT SQL_UNDO
2 FROM V$LOGMNR_CONTENTS
3* WHERE USERNAME='HR';
SQL_UNDO
------------------------------------------------------------------
insert into "HR"."REGIONS"("REGION_ID","REGION_NAME")
values ('5','northern europe');
insert into "HR"."REGIONS"("REGION_ID","REGION_NAME")
values ('6','pacific region');
update "HR"."REGIONS" set "REGION_NAME" = 'northern africa' where
"REGION_NAME"= 'eastern europe' and ROWID = 'AAAHrNAAFAAAAESAAG';
10 rows selected.
SQL>

Здесь оператор INSERT заменяет удаленные данные, а оператор UPDATE аннулирует внесенные изменения. Обратите внимание, что SQL*Plus сообщает, что в ответ на запрос было выбрано десять строк, хотя выполненных пользователем HR операций DDL отображается только три.

Как видно, в столбце SQL_UNDO содержатся готовые к использованию операторы SQL вместе с символами точки с запятой и прочими необходимыми деталями. Однако читать их не очень удобно, потому что они являются длинными и сложными. Для придания выводу менее громоздкого и более удобного для чтения вида в LogMiner предусмотрена специальная процедура DBMS_LOGMNR.PRINT_PRETTY_SQL.

При желании постоянно производить анализ данных с помощью LogMiner, все время добавлять файлы вручную вовсе не обязательно. Достаточно просто добавить процедуру DBMS_LOGMNR.CONTINUOUS_MINE с использованием ключевого слова OPTIONS, и утилита LogMiner будет автоматически продолжать добавлять любые имеющиеся в архиве файлы журналов повторного выполнения в список подлежащих анализу файлов при каждом обращении к представлению V$LOGMNR_CONTENTS.

Из-за того, что в рассматриваемом примере при запуске утилиты LogMiner была включена функция отслеживания DDL, выполнение показанного ниже запроса, например, приведет к отображению всех DDL-изменений, которые были внесены пользователем SYS

SQL> SELECT sql_undo
2 FROM v$logmnr_contents
3 WHERE username='SYS'
4* AND operation='DDL'

Закончив работать с LogMiner, для завершения сеанса нужно воспользоваться процедурой DBMS_LOGMNR.end_logmnr, как показано ниже: 

SQL> EXECUTE dbms_logmnr.end_logmnr();
PL/SQL procedure successfully completed.
SQL>

 

Вас заинтересует / Intresting for you:

Восстановление баз данных Orac...
Восстановление баз данных Orac... 6307 просмотров Дэн Tue, 21 Nov 2017, 13:18:05
Выполнение восстановления базы...
Выполнение восстановления базы... 5943 просмотров Дэн Tue, 21 Nov 2017, 13:18:05
Ищем и исправляем ошибки в баз...
Ищем и исправляем ошибки в баз... 3807 просмотров Александров Попков Tue, 21 Nov 2017, 13:18:05
Исправление поврежденных блоко...
Исправление поврежденных блоко... 2938 просмотров Андрей Волков Tue, 21 Nov 2017, 13:18:05
Войдите чтобы комментировать

apv аватар
apv ответил в теме #8727 06 окт 2017 07:12
LogMiner реально не раз спасал при восстановлении оракловой базы. Отличная утилита.