(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Администратору Oracle: Раскрываем секреты - глубинный анализ журналов (Mining for Clues)

Источник: Oracle Magazine

Использование утилиты Oracle LogMiner для восстановления транзакций и отмены изменений.

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

Джон, главный администратор базы данных банка, должен был действовать не теряя времени. Он быстро выполнил запрос к таблице ACCOUNTS (счета), который показал, что значение столбца ACC_MGR_ID (идентификатор персонального менеджера) для счета 4567 (счет Эллен) равно 1, тогда как идентификатор Пола - 5. Раньше это значение определенно было равно 5. Кто мог изменить его и почему? Кроме того, отдельный запрос показал, что Полу был назначен другой клиент (с номером счета 9876), которого Пол не признает. Почему это случилось, и кто действительный персональный менеджер счета 9876?

"Рытье носом" в архивах

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

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

Когда происходят изменения, записи повторного выполнения помещаются в журнальные буфера в системной глобальной области (SGA). Затем процесс записи в журнал LGWR записывает эти записи в оперативный журнал, и, если сервер базы данных работает в режиме архивирования (ARCHIVELOG), процесс архивирования ARC0 сохранит эти записи в архивном журнале. Назначение этих журнальных записей заключается в том, чтобы гарантировать (в случае повреждения базы данных) повторное выполнение сделанных ранее операций. В случае полной потери базы данных ее администратор может восстановить созданную ранее резервную копию базы данных и применить все архивные журнальные файлы, сгенерированные после создания этой копии, чтобы "накатить" эту копию на момент отказа.

А как насчет записей отката? Согласно модели согласованности чтения в СУБД Oracle пользователь видит измененное значение только после фиксации этого изменения; в противном случае сервер базы данных возвращает предыдущие (неизменные) значения. Эти предыдущие значения извлекаются из сегментов отката. Кроме того, во время восстановления данных после их повреждения сервер базы данных Oracle для поддержки согласованности и целостности данных должен "откатить" все изменения, которые не были зафиксированы. Эти записи извлекаются из сегментов отката. Сегменты отката изменяются также как и другие сегменты базы данных, поэтому и для них генерируются журнальные записи, которые записываются в оперативный журнал, а затем и в архивный.

В результате оперативный и архивный журналы содержат как информацию отката, так и повторного выполнения. Администраторы базы данных могут использовать их для извлечения как старых значений данных, так и новых. Однако формат оперативного и архивного журналов не опубликован и они не удобочитаемые. Для чтения и поиска в оперативном и архивном журналах администраторы баз данных используют утилиту Oracle LogMiner (глубинный анализ журнала). С этой утилитой можно работать с помощью поставляемого пакета DBMS_LOGMNR, появившегося в сервере Oracle8 i . В этой статье описано, как использовать этот мощный инструмент для решения простых и не так уж и простых проблем, возникающих при изменениях базы данных Oracle.

Начинаем анализ

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

Однако ретроспективные запросы работают только в интервале времени, задаваемом параметром UNDO_RETENTION (сохранение информации в пространстве отката), значение которого в OLTP-системах часто не превышает 30 минут. В таком случае ретроспективные запросы не найдут изменений.

Джон может найти ответ на рассматриваемый вопрос с помощью утилиты LogMiner, просматривая непосредственно файлы оперативного журнала. Шаги для настройки и использования LogMiner:

  1. Инсталлировать пакет DBMS_LOGMNR. Джон инсталлировал пакет, а затем в утилите SQL*Plus подключился к системе как пользователь SYS и выполнил скрипт $ORACLE_HOME/rdbms/admin/dbmslm.sql.
  2. Предоставить роль. Затем Джон предоставляет пользователю, который будет анализировать журнал, (в данном случае, самому себе) роль, необходимую для выполнения этого пакета:
    GRANT EXECUTE_CATALOG_ROLE TO JOHN;
  3. Создать синоним. Джон создает публичный синоним:
    CREATE PUBLIC SYNONYM DBMS_LOGMNR FOR SYS.DBMS_LOGMNR;
    
    

    Эти первые три шага нужно выполнить только один раз.

  4. Определить область действия анализа. Ошибка, возможно, случилась совсем недавно, поэтому изменение может все еще находиться в оперативных журнальных файлах. Так что, на первом проходе Джон решает анализировать только оперативные журнальные файлы. Он определяет эти файлы, выполняя следующий запрос:
    SELECT distinct member LOGFILENAME FROM V$LOGFILE;
    
    LOGFILENAME
    _______________________
    /dev/vgredo01/rlog1a
    /dev/vgredo01/rlog1b
    

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

    BEGIN
       DBMS_LOGMNR.ADD_LOGFILE
          ('/dev/vgredo01/rlog1a');
       DBMS_LOGMNR.ADD_LOGFILE
          ('/dev/vgredo01/rlog1b');
    END;
    
  5. Запустить сеанс утилиты LogMiner и указать словарь данных (каталог). Для запуска сеанса этой утилиты Джон выполняет следующий SQL-код:
    BEGIN
       DBMS_LOGMNR.START_LOGMNR
       (options =>
    dbms_logmnr.dict_from_online_catalog);
    END;
    

    Используя параметр OPTIONS, он также указывает, чтобы при запуске сеанса утилиты LogMiner сервер базы данных Oracle прочитал информацию словаря данных (для преобразования имен объектов) из оперативного словаря данных.

    Как упоминалось ранее, журнальные записи хранятся не в виде открытого текста. Утилита LogMiner обеспечивает их удобочитаемый вывод, но некоторые значения могут выводиться не похожими на оригинальные объекты. Например, имена владельцев, таблиц и столбцов не записываются в оперативный журнал в том виде, в котором их вводили пользователи; они преобразованы в шестнадцатеричный формат. Например, имя таблицы ACCOUNTS может храниться как OBJ#45C1. Чтобы сделать журнальные данные более удобочитаемыми, Джон может указать утилите LogMiner на необходимость преобразования этих значений в более узнаваемые, транслируя их по словарю данных.

  6. Проверить содержимое. При запуске сеанса утилиты LogMiner заполняется представление V$LOGMNR_CONTENTS, в котором Джон может обнаружить, что же случилось со счетом Эллен Смит. В запросах ищутся пользователи и время любых обновлений таблицы ACCOUNTS. Запрос к представлению V$LOGMNR_CONTENTS и его результаты показаны на листинге 1. Заметим, Джон должен выполнять запросы к этому представлению в том же самом сеансе, в котором он запустил сеанс утилиты LogMiner. Он ищет только обновления, поэтому в строке 6 листинга 1 он использует предикат.

На листинге 1 Джон видит, что пользователь по имени JOE (Джо) обновил эту таблицу в 14:16. Столбцы SID и SERIAL# идентифицируют сеанс, в котором работал этот пользователь.

ЛИСТИНГ 1: извлечение информации из представления V$LOGMNR_CONTENTS.

SQL>  select username, to_char(timestamp,'mm/dd/yy hh24:mi:ss') timestamp,
  2  seg_type_name, seg_name, table_space, session# SID, serial#
  3  from v$logmnr_contents
  4  where table_name = 'ACCOUNTS'
  5  and seg_owner = 'ARUP'
  6  and operation = 'UPDATE';

USERNAME  TIMESTAMP	          SEG_TYPE_N	SEG_NAME   TABLE_SPAC  SID  SERIAL#
________  __________________ __________  ______________  ________  ____   _____
JOE	     01/26/05 14:16:41 TABPART	     ACCOUNTS,P1	ACC_D1	   532    62
JOE	     01/26/05 14:16:41 TABPART	     ACCOUNTS,P2   ACC_D2	   532    62
JOE	     01/26/05 14:16:41 TABPART	     ACCOUNTS,P3	ACC_D3	   532    62
...

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

login_username=JOE
client_info=
OS_username=jsmoe
Machine_name=ACMENTNY\JSMOE
OS_terminal= OS_process_id=4080:3096 OS_program name=sqlplus.exe

По этой информации Джон узнает, что Джо обновил ряд записей таблицы ACCOUNTS с машины клиента по имени JSMOE, работавшей в сети ACMENTNY. Последняя порция информации, OS_program name=sqlplus.exe, также содержит важные сведения. Джо использовал утилиту SQL*Plus, поэтому он, вероятно, выполнил нерегламентированное обновление, но Джо - разработчик, ему запрещено обновлять промышленную базу данных, кроме случаев чрезвычайной ситуации. Почему он сделал эти изменения?

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

ЛИСТИНГ 2: вывод содержимого столбцов SQL_UNDO и SQL_REDO.

SQL>  select sql_undo, sql_redo
  2  from v$logmnr_contents
  3  where table_name = 'ACCOUNTS'
  4  and seg_owner = 'ARUP'
  5  and operation = 'UPDATE';

SQL_UNDO	                                    SQL_REDO
___________________________-_______________        ___________ ________________________________
update "ARUP"."ACCOUNTS" set "ACC_M	            update "ARUP"."ACCOUNTS" set "ACC_M
GR_ID" = '2' where "ACC_MGR_ID" = '	            GR_ID" = '6' where "ACC_MGR_ID" = '
6' and ROWID = 'AAOKdAALAAAGcEAB'	            2' and ROWID = 'AAOKdAALAAAGcEAB'

update "ARUP"."ACCOUNTS" set "ACC_M	            update "ARUP"."ACCOUNTS" set "ACC_M
GR_ID" = '1' where "ACC_MGR_ID" = '	            GR_ID" = '6' where "ACC_MGR_ID" = '
6' and ROWID = 'AAAOKdAALAAAGcEAB0'	            1' and ROWID = 'AAAOKdAALAAAGcEAB0'

update "ARUP"."ACCOUNTS" set "ACC_M	            update "ARUP"."ACCOUNTS" set "ACC_M
GR_ID" = '5' where "ACC_MGR_ID" = '	            GR_ID" = '6' where "ACC_MGR_ID" = '
6' and ROWID = 'AAAOKdAALAAAGcEAB5'	            5' and ROWID = 'AAAOKdAALAAAGcEAB5'

...

При личной встрече Джо признает, что он сделал эти изменения. В свою защиту, однако, Джо предоставляет весьма разумное объяснение. Очень важный клиент - Эллен Смит - имела неприятный опыт работы с ее назначенным персональным менеджером и потребовала сменить его. Такие изменения в базе данных обычно делаются главным менеджером, но он отсутствовал, и вновь назначенный персональный менеджер позвонил Джо и попросил "поколдовать" и помочь ему. Джо сделал это, выполнив следующий оператор:

UPDATE ACCOUNTS
SET acc_mgr_id = 6
WHERE first_name = 'Ellen'
AND last_name = 'Smith';

Но Джо не заметил, что этот оператор обновил 340 записей , каждая из которых соответствовала клиентке с именем Эллен Смит. Джо хотел обновить запись только одной клиентки, но по неосмотрительности обновил 340 записей. Среди затронутых была и клиентка Пола, которая совсем не хотела замены своего персонального менеджера.

Заметим, в вышеприведенном примере, Джон анализировал оперативные журнальные файлы. Однако если бы проблема возникла давно, содержимое оперативного журнала уже было бы перенесено в архивные журнальные файлы. В этом случае Джон мог бы также анализировать и архивный журнал. Для этого он просто бы указал имена архивных журнальных файлов в вызовах процедуры DBMS_LOGMNR.ADD_LOGFILE. Оставшаяся часть задач остается той же самой. Эти имена можно определить по представлению словаря данных V$ARCHIVED_LOG.

Отмена изменений

Следующая задача Джона состоит в том, чтобы немедленно обновить другие 339 записей, вернув их старые значения. Заметим, на листинге 2, текст под заголовком SQL_REDO показывает, что было изменено первоначально, а текст под заголовком SQL_UNDO показывает операторы, которые могут использоваться для отмены этих изменений. Хотя Джо первоначально использовал только один оператор, утилита LogMiner реконструирует операторы для модификации каждой записи по отдельности, как это и показано на листинге. Для восстановления старых идентификаторов персональных менеджеров Джон может выполнить каждый из операторов, перечисленных под заголовком SQL_UNDO. Это отменит изменения, которые сделал Джо.

Удобный вывод

Вывод значений столбцов SQL_UNDO и SQL_REDO на листинге 2 не очень легко читать - все они выдаются в одной строке. Для решения этой проблемы Джон может использовать опцию print_pretty_sql. Он также хочет выполнить SQL-операторы в цикле PL/SQL, используя динамический SQL, а этот подход требует, чтобы точка с запятой в конце каждого оператора была удалена. Эта задача решается с помощью опции no_sql_delimiter.

Джон решает запустить сеанс утилиты LogMiner, используя следующие опции:

begin
   dbms_logmnr.start_logmnr(
      options =>
          dbms_logmnr.
dict_from_online_catalog +
          dbms_logmnr.print_pretty_sql +
          dbms_logmnr.no_sql_delimiter
   );
end;

После выполнения этого кода текст столбца SQL_UNDO в запросе листинга 2 будет выглядеть так:

SQL_UNDO
_____________________________
update "ARUP"."ACCOUNTS"
  set
    "ACC_MGR_ID" = 2
  where
     "ACC_MGR_ID" = 6 and
     ROWID = 'AAOKdAALAAAGcEAB'
...

Выборочная коррекция

В предыдущих разделах мы обсуждали способ извлечения SQL-операторов для отмены всех операций обновления таблицы ACCOUNTS. Конечно, эту таблицу могли также обновлять и другие пользователи, Джон не хотел бы отменять их изменения. Чтобы выбирать только подходящие операторы, он может фильтровать содержимое представления V$LOGMNR_CONTENTS, как это показано на листинге 3.

ЛИСТИНГ 3: выборочный вывод из представления V$LOGMNR_CONTENTS.

select
   acc_type, first_name, last_name,
   dbms_logmnr.mine_value(redo_value,'ARUP.ACCOUNTS.ACC_MGR_ID') new_value,
   dbms_logmnr.mine_value(undo_value,'ARUP.ACCOUNTS.ACC_MGR_ID') old_value
from v$logmnr_contents l, accounts a
where table_name = 'ACCOUNTS'
and operation = 'UPDATE'
and dbms_logmnr.column_present(undo_value,'ARUP.ACCOUNTS.ACC_MGR_ID') =1
and dbms_logmnr.column_present(redo_value,'ARUP.ACCOUNTS.ACC_MGR_ID') =1
and a.rowid = l.row_id;

A FIRST_NAME	    LAST_NAME	   NEW_VALUE	  OLD_VALUE
_______________    _____________  _____________  ____________
D Ellen	            Smith	   5	           6
M Ellen	            Smith	   5	          10
D Ellen                  Smith	   5	           7

...

Внимательно рассмотрите этот SQL-код. В нем используются дополнительные функции пакета DBMS_LOGMNR. Первая функция, MINE_VALUE, выбирает значение указанного столбца, записанного до или после изменения. Например, оператор DBMS_LOGMNR.MINE_VALUE (UNDO_VALUE, 'ARUP.ACCOUNTS.ACC_MGR_ID')показывает значение столбца ACC_MGR_ID перед изменением. Если параметр UNDO_VALUE изменить на REDO_VALUE, то этот оператор возвратит значение после изменения.

Кроме того, функция COLUMN_PRESENT возвращает 1, если значение столбца существует и 0 в противном случае. Когда выполняется соединение с таблицей ACCOUNTS, она показывает другие подходящие детали счетов.

Выходные данные на листинге 3 показывают старые и обновленные значения столбца ACC_MGR_ID, тип счета ACC_TYPE, а также имена и фамилии (столбцы FIRST_NAME и LAST_NAME). Эти данные помогают Джону мгновенно определить все поврежденные данные и способ их исправления. Используя SQL-оператор, показанный на листинге 3, Джон может написать простой PL/SQL-код для восстановления первоначальных значений столбца ACC_MGR_ID (выборочно, после проверки других столбцов, таких, как ACC_TYPE или FIRST_NAME, как это показано на листинге 4.

ЛИСТИНГ 4: PL/SQL-код для выполнения операторов раздела SQL_UNDO.

SQL>  begin
  2    for undo_rec in (
  3      select sql_undo, row_id
  4      from v$logmnr_contents
  5      where table_name='ACCOUNTS' and seg_owner='ARUP' and operation='UPDATE'
  6      and dbms_logmnr.column_present(undo_value,'ARUP.ACCOUNTS.ACC_MGR_ID')=1
  7      and dbms_logmnr.column_present(redo_value,'ARUP.ACCOUNTS.ACC_MGR_ID')=1
  8      )
  9      loop
 10        begin
 11           execute immediate undo_rec.sql_undo;
 12        exception
 13          when no_data_found then
 14             dbms_output.put_line('RowId '//undo_rec.row_id//' Failed.');
 15        end;
 16      end loop;
 17   end;

Удаленный анализ журнала

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

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

Если Джон занимается удаленным анализом журнала, он имеет два альтернативных варианта решения этой проблемы:

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

Оба этих варианта требуют выгрузки оперативного словаря данных либо в журнал, либо в обычный файл. Эта задача может быть выполнена с помощью поставляемого пакета DBMS_LOGMNR_D. Если этот пакет отсутствует, Джон может создать его, выполнив скрипты dbmslmd.sql и prvtlmd.sql, находящиеся в каталоге $ORACLE_HOME/rdbms/admin.

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

begin
   dbms_logmnr_d.build (
      options => dbms_logmnr_d.store_in_redo_logs
   );
end;

Заметим, этот вариант возможен, если в сервере базы данных включен режим архивирования (archivelog). В этом режиме словарная информация записывается в оперативные журнальные файлы, а затем, естественно, и в архивные журнальные файлы. Во время подготовки к анализу Джон пересылает эти архивные файлы (используя утилиту передачи файлов, такую, как FTP) и с помощью процедуры add_logfile пакета dbms_logmnr включает их для использования при анализе.

После этого он запускает сеанс утилиты LogMiner, но с немного другим параметром:

dbms_logmnr.start_logmnr( options =>
       dbms_logmnr.dict_from_redo_logs
   );

Если Джон выберет второй вариант (хранение словаря данных в обычном файле), то он укажет файл, в который будет записан этот новый словарь. Для записи в файл используется пакет UTL_FILE, поэтому в параметре инициализации UTL_FILE_DIR должен быть задан путь доступа к этому файлу. Если это еще не сделано, Джон укажет, например, /tmp (в ОС UNIX):

utl_file_dir = '/tmp'

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

begin
   dbms_logmnr_d.build (
      dictionary_filename => 'ora_dict.txt',
      dictionary_location => '/tmp'
   );
end;

Этот код генерирует в каталоге /tmp файл ora_dict.txt. Затем Джон пересылает файл /tmp/ora_dict.txt из сервера исходной базы данных в каталог /tmp сервера удаленной базы данных и запускает сеанс утилиты LogMiner, выполняя:

dbms_logmnr.start_logmnr(dictfilename => '/tmp/ora_dict.txt');

Обратите внимание на новый параметр dictfilename, который указывает файл со словарем, созданный ранее. Нет никакой необходимости использования параметра OPTIONS, поскольку Джон не читает из оперативных словаря данных или журнальных файлов. Он может использовать параметр OPTIONS , например, для включения форматирования SQL-операторов, удаления точек с запятой в конце этих операторов и т.д.

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

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

Давайте рассмотрим немного другой сценарий истории "Персональный менеджер клиентки Эллен Смит". Предположим, таблица ACCOUNTS секционирована по диапазону значений столбца ACC_MGR_ID, где для каждого значения этого столбца создается отдельная секция. В этом случае, когда Джо обновил столбец ACC_MGR_ID, строки были перемещены в другую секцию. Например, строка ACC_MGR_ID = 6 находилась в шестой секции, но когда Джо установил в этом столбце значение 3, строка переместилась в третью секцию. Идентификатор строки ROWID основан на физическом местоположении строки, поэтому в результате этого физического перемещения был изменен идентификатор этой строки.

Как вы должны действовать в этом случае?

Если для отмены обновления вы выполните следующий оператор, извлеченный из сеанса утилиты LogMiner (см. листинг 2):

update "ARUP"."ACCOUNTS" set "ACC_MGR_ID" = '6' where "ACC_MGR_ID" = '3' 
                 and ROWID =  'AAAOKeAAcAAAH8MAA7';

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

Следующие шаги

ЧИТАЙТЕ более подробно:
об утилите LogMiner
о пакете DBMS_LOGMNR

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

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

alter database add supplemental log data (primary key) columns;


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

update "ARUP"."ACCOUNTS" set "ACC_MGR_ID" = '6' where "ACC_NO" = '5720' 
            and "ACC_MGR_ID" = '3' and ROWID =  'AAAOKeAAcAAAH8MAA7';

Обратите внимание, в содержимом столбца SQL_UNDO в дополнение к идентфикатору ROWID появился первичный ключ, ACC_NO, который позволяет идентифицировать правильные строки.

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

Заключение

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

Арап Нанда (Arup Nanda) ( arup@proligence.com ) - директор подразделения проектирования и эксплуатации баз данных компании Starwood Hotels and Resorts (White Plains, New York). В 2003 г. он был удостоен награды " Oracle's DBA of the Year "( администратор года баз данных Oracle). Арап - соавтор книги Oracle Privacy Security Auditing (издательство Rampant TechPress, 2003) - "Средства аудита в СУБД Oracle, обеспечивающие информационную безопасность".



 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 20.12.2006 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Oracle Database Standard Edition 2 Processor License
Oracle Database Personal Edition Named User Plus License
Oracle Database Standard Edition 2 Named User Plus License
Oracle Database Personal Edition Named User Plus Software Update License & Support
VMware Workstation 14 Pro for Linux and Windows, ESD
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
eManual - электронные книги и техническая документация
ЕRP-Форум. Творческие дискуссии о системах автоматизации
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100