Популярно о Supplemental Logging
05.02.2010 от aryndin99Долго не доходили руки написать, но тема довольно важная в свете популярности репликации. Если достаточно просто понять для чего Supplemental Logging нужен, то вопросы об условном и обязательном журналировании, объеме дополнительно генерируемого потока журнальных данных и другие более тонкие технические вопросы всегда вызывают дополнительные вопросы.
Кроме того, еще и сам Oracle не так глубоко описывает это влияние, а если и описывает то в разных местах документации. Теоретическую информацию о Supplemental Logging еще можно найти в блогах и на металинке, но с практической информацией все сложно.
Для чего все это нужно? Я много пишу о репликации. Будь то Streams или GoldenGate - все они используют журналирование, чтобы получать изменения и транслировать их в целевую базу. А что произойдет, если база данных сильно нагружена? На какой объем дополнительной работы приходится рассчитывать? Все эти вопросы очень важны для обоснования выбора инструмента и для планирования наращивания оборудования...
Теория
Итак, журнальные файлы обычно используются для восстановления экземпляра и восстановления носителя данных. Данные, которые необходимы для этих операций автоматически заносятся в журнальные файлы. Например, перед фиксацией транзакции сначала в журнал пишется информация, необходимая для ее повторения в случае форс-мажорной ситуации (например, выключение электропитания).
В журналы пишутся так называемые журнальные записи (redo records). Каждая журнальная запись содержит все изменения для определенного SCN. Каждая журнальная запись состоит из заголовка и одного или нескольких векторов изменений (change vectors). Для каждого события может генерироваться несколько векторов изменений.
Например, когда выполняется вставка в таблицу, имеющую индексы создается несколько векторов. Вектора также создаются, когда старое значение копируется в UNDO. Каждый вектор изменений описывает изменения одного блока. Ниже приведен пример заголовка одного вектора:
CHANGE #1 TYP:2 CLS:1 AFN:4 DBA:0x0100020e OBJ:74579 SCN:0x0000.000f8cbd SEQ:2 OP:11.2 ENC:0 RBL:0
Как можно видеть указаны Datablock Address, Object ID, SCN и номер версии блока (SEQ). Т.е. для того, чтобы воспроизвести операцию из Redo необходимо иметь блок с заданным адресом и заданной версией, иначе ничего не получится. Таким образом, если представить полную побайтную копию базы данных Oracle, то информации для наката изменений будет достаточно, но если объекты внутри базы смещены физически, то эта информация становится бесполезной.
Большинство средств репликации оперируют двумя физически неодинаковыми базами данных. Объекты могут быть физически расположены в других табличных пространствах, могут быть построены дополнительные индексы, таблицы дефрагментированы, да и вообще части таблиц можете не быть. Т.е. нам потребуется другой способ идентификации изменений нежели физические адреса.
Еще проблемы:
- ну и самое важное, когда мы делаем обновление записи по первичному ключу, то сам ключ не изменяется. Изменяются другие столбцы, поэтому в журнал будут записаны только новые значения изменяемых столбцов - из журналов будет непонятно, как запись изменяется.
- из журнала будет непонятно, какие значения были в строке до изменения, а это не позволяет разрешать возникающие конфликты при двусторонней репликации.
Итак, в журналы Oracle данные ложатся оптимальным образом для восстановления, а это не дает возможности использовать их для других целей. Для того, чтобы журналы позволили решать другие задачи нужен Supplemental Logging, о котором мы и будем говорить.
Что такое Supplemental Logging
Supplemental logging - это процесс записи дополнительной информации в журнал во время выполнения операций изменения (например, изменения строки).
Supplemental log group - это набор столбцов, значения из которых должны быть журналированы, когда включено supplemental logging. Существует 2 типа групп: условные(conditional) и безусловные(unconditional):
- Unconditional supplemental log groups - значение-до-изменения для столбцов, входящих в эту группу журналируются при любом изменении, независимо от того, изменяются столбцы в этой группе. Часто такую группу столбцов называют ALWAYS log group.
- Conditional supplemental log groups - значение-до-изменения для столбцов, входящих в эту группу журналируются только если изменяется хотя бы один из столбцов в этой группе.
Supplemental log groups могут быть созданы системой или определены пользователем.
Кроме того, что есть 2 типа групп существует также 2 уровня supplemental logging: database-level supplemental logging и table-level supplemental logging.
Database-level supplemental logging
Существует 2 типа database-level supplemental logging: minimal supplemental logging и identification key logging. Первый в отличие от второго не добавляет значительную нагрузку на базу данных. Oracle рекомендует как минимум включать minimal supplemental logging.
Minimal supplemental logging
В этом режиме база данных журналирует дополнительный объем данных, необходимый для идентификации, группировки и соединения операций Redo, связанных с DML изменениями. Включение такого журналирования позволяет продуктам, основанным на использовании журналов корректно обрабатывать chained rows, а также различные дополнительные методы хранения данных - cluster tables и IOT.
Включить:
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
Выключить
ALTER DATABASE DROP SUPPLEMENTAL LOG DATA;
Я не буду вдаваться в подробности физической структуры Redo Log файлов. Если нужно, то можно посмотреть здесь и здесь. Кроме того, можно использовать команду ALTER SYSTEM DUMP LOGFILE для дампирования журнала.
Здесь же я просто приведу статистику по использованию файлов журнала в разных режимах. Для тестирования я создал 2 таблицы:
drop table test_without_chain;
create table test_without_chain (a1 number primary key,
a2 char(2000));
drop table test_with_chain;
create table test_with_chain (a1 number primary key,
a2 char(2000),
a3 char(2000),
a4 char(2000),
a5 char(2000),
a6 char(2000));
Первая не должна приводить к row chain (у меня блок 8к), а вторая должна.
Таблица test_with_chain.
| - Supp. Logging | + Min Supp. Logging |
Прирост объема журналов | |
| update test_with_chain set a2=a2||'suffix'; |
2771748 | 2974612 | 7% |
| update test_with_chain set a2=a2||'suffix', a3=a3||'suffix', a4=a4||'suffix', a5=a5||'suffix', a6=a6||'suffix'; |
5671060 | 6051296 | 6% |
| 10000 раз выполнен insert into test_with_chain values (i,'test1'||i, 'test2'||i, 'tes3'||i, 'test4'||i, 'test5'||i); |
5810620 | 6014324 | 3% |
| delete from test_with_chain; | 5266460 | 5469020 | 4% |
Таблица test_without_chain.
| - Supp. Logging | + Min Supp. Logging |
Прирост объема журналов | |
| update test_without_chain set a2=a2||'suffix'; |
4141300 | 4501832 | 8% |
| 10000 раз выполнен insert into test_without_chain values (i,'test1'||i); |
5217200 | 5423140 | 4% |
| delete from test_without_chain; | 4741424 | 4943292 | 4% |
Из этих данных можно сделать, что основной прирост объема генерируемых данных мы испытываем на обновлениях таблиц - прирост около 7% объема журналов. На удалениях и вставках строк влияние в 2 раза меньше.
Database-Level Identification Key Logging
Используя database identification key logging можно включить журналирование состояния-до-изменения для всех таблиц в базе данных. В свою очередь database identification key logging имеет ряд режимов:
- ALL - безусловно заставляет базу записывать в журналы состояние-до-изменения для всех столбцов в изменяемой строке (за исключением LOBs, LONGS, и ADTs).
- PRIMARY KEY - безусловно (даже если первичный ключ не меняется) заставляет базу записывать в журналы состояние-до-изменения для первичного ключа в изменяемой строке. Если PK, то используется один из уникальных индексов. Если нет ни PK, ни уникального ключа, то Oracle ведет себя аналогично режиму ALL
- UNIQUE - при условии, что изменяется столбец, входящий в уникальный или bitmap индекс, журналирует состояние-до-изменения для всех столбцов, принадлежащие этому индексу
- FOREIGN KEY - при условии, что изменяет столбец, входящий в FK, журналирует состояние-до-изменения для всех столбцов FK.
При включении любого из этих режимов автоматически включается Minimal supplemental logging и его нельзя отключить, пока не будут отключены все режимы database identification key logging.
Включить:
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
Выключить:
ALTER DATABASE DROP SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
Давайте опять протестируем статистику генерации журналов в двух режимах - ALL и PRIMARY KEY. В скобках указан прирост в % к объему журналов без журналирования.
| Без Supp. Logging |
+ Min Supp. Logging |
+PK | +ALL | |
| update test_with_chain set a2=a2||'suffix'; |
2772004 | 2974612 (7%) | 3175196 (13%) | 3848308 (28%) |
| update test_with_chain set a2=a2||'suffix', a3=a3||'suffix', a4=a4||'suffix', a5=a5||'suffix', a6=a6||'suffix'; |
5671060 | 6051296 (6%) | 6189932 (8%) | 6189088 (8%) |
| 10000 раз выполнен insert into test_with_chain values (i,'test1'||i, 'test2'||i, 'tes3'||i, 'test4'||i, 'test5'||i); |
5810620 | 6014324 (3%) | 6014744 (3%) | 6014648 (3%) |
| delete from test_with_chain; | 5266460 | 5469020 (4%) | 5469188 (4%) | 5469436 (4%) |
Как и следовало ожидать наибольший прирост объема журналирования произошел в случае изменения таблицы. Этот прирост становится значительным при обновлении только малого количества полей.
Очевидно, что связано это с тем, что поля, которые в данный момент не изменяются про на затрагиваются механизмом журналирования. Если же мы включаем журналирование состояния ВСЕХ столбцов до изменения, то неизменяемые столбцы также попадают в журнал.
Поэтому нужно быть очень аккуратным, когда включаете Supplemental Logging для всех операций. Нужно понимать, что это может привести к снижению производительности операций DML, но прежде всего, конечно, операций UPDATE.
Я бы вообще рекомендовал избегать использования глобального режима Supplemental Logging, а вместо него применять включение журналирования на уровне
Table-Level Identification Key Logging
Supplemental Logging на уровне таблиц позволяет включать те же самые режимы, что и на уровне базы данных ALL, PRIMARY KEY, UNIQUE, FOREIGN KEY. Например, что включить журналирование изменений состояния-до-изменения для всех столбцов таблицы:
ALTER TABLE HR.EMPLOYEES ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
Однако, помимо предопределенных режимов можно настроить режим, определенный пользователем. Так называемые Supplemental Log Groups.
Table-Level User-Defined Supplemental Log Groups
С помощью Supplemental Log Groups можно настроить списки столбцов, которые будут журналироваться. Различают 2 типа Supplemental Log Groups:
- User-defined unconditional log groups - для создания безусловно журналируемых групп необходимо использовать ключевое слово ALWAYS. Для столбцов, входящих в такую группу, при каждом UPDATE в журнал записывается состояние-до-изменения. Значение столбца будет журналироваться даже если изменяются столбцы, не входящие в группу.
- User-defined conditional supplemental log groups - для создания условно журналируемых групп необходимо опустить ключевое слово ALWAYS. Состояние-до-изменения для столбцов, входящих в такую группу будет записываться в журнал только если UPDATE изменяет столбцы в группе.
Пример создания user-defined unconditional log group:
ALTER TABLE HR.EMPLOYEES
ADD SUPPLEMENTAL LOG GROUP emp_parttime (EMPLOYEE_ID, LAST_NAME,
DEPARTMENT_ID) ALWAYS;
Пример создания user-defined conditional supplemental log group:
ALTER TABLE HR.EMPLOYEES
ADD SUPPLEMENTAL LOG GROUP emp_fulltime (EMPLOYEE_ID, LAST_NAME,
DEPARTMENT_ID);
Есть один нюанс, связанный с использованием User-defined log groups - количество столбцов не должно быть больше 32. Если столбцов больше нужно создавать несколько групп.
Представления для просмотра информации о Supplemental Logging
1. V$DATABASE - позволяет увидеть состояние Supplemental Logging на уровне базы данных:
select SUPPLEMENTAL_LOG_DATA_MIN,SUPPLEMENTAL_LOG_DATA_PK,SUPPLEMENTAL_LOG_DATA_UI,SUPPLEMENTAL_LOG_DATA_ALL from V$DATABASE;
2. ALL_LOG_GROUPS, ALL_LOG_GROUP_COLUMNS - список Supplemental Log Groups и столбцов, входящих в них, для таблиц, к которомым пользователь имеет доступ:
select * from ALL_LOG_GROUPS a JOIN ALL_LOG_GROUP_COLUMNS b
on (a.owner=b.owner and a.log_group_name=b.log_group_name);
Заключение
Журналы Oracle предназначены в исходном состоянии для восстановления базы данных в аварийной ситуации. Их работа оптимальна и в них нет ничего лишнего.
Однако, для целей репликации данных там присутствует не все что нужно. Поэтому приходиться смиряться с этим неизбежным злом, поскольку в остальном репликация с использованием журналов Oracle очень эффективна. Все рассуждения в этой статье характерны как для Oracle Streams, так и для GoldenGate.
Хоть это и неизбежное зло, но мы можем значительно снизить дополнительную нагрузку за счет более грамотного тонкого включения Supplemental Logging. Включать его нужно на уровне таблиц и желательно продумывать, значения каких столбцов нужно дополнительно журналировать. Приведу пару примеров:
- Обычно следует включать журналирование Primary Key
- Если репликация двусторонняя, то нужно включать режим Supplemental Logging для столбцов, по которым возможно возникновение конфликта
- Если в таблице Primary Key отсутствует по факту, но он формально поддерживается (например, в случае биллинга), то следует явно создать группу журналирования для столбца-первичного ключа.
- Вам также могут быть интересны следующие статьи:
- Использование GoldenGate для live reporting
- Обзор возможностей Oracle Multimedia
- Пример триггера на spatial таблицу
- ndmdemo.ear – веб-приложения для анализа сетей
- Использование Oracle Streams для репликации (часть 5)
Рубрики: Data Warehouse, Data Warehousing, Database, GoldenGate, Streams | Комментарии (3) »

31.03.2010 в 17:46
Получается что у «Supplemental Logging» только один недостаток он увеличивает Redo Logs, а что же по поводу нагрузки на апаратную часть системы? и на общую производительность базы. Насколько увеличивается нагрузка на базу ?
03.04.2010 в 20:10
Из-за увеличения объема журналов будет увеличена нагрузка на систему ввода-вывода.
Возможно несколько вариантов:
1. Журналы лежат на отдельно томе RAID 1, на котором другого I/O нет
2. Журналы лежат на интеллектуальном хранилище, на RAID 10 с хорошим кэшем.
3. Журналы лежат на том же диске, что и база. Объем кэша небольшой.
В первых двух вариантах обычно эта нагрузка не приведет к заметным последствиям.
В третьем варианте – будут проблемы. Ну третий вариант изначально будут работать плохо.
Вот по процессорным ресурсам – нужно тестировать. Мое субъективное мнение – дополнительная нагрузка будет минимальной.
20.08.2010 в 21:36
спс за статью.