Восстановление в базе данных Oracle

Процесс восстановления в базе данных OracleПосле того, как Вы потратили изучили особенностей работы процессов dbwr и lgwr, настала пора рассмотреть одну из наиболее важных задач – восстановление в базе данных Oracle. Когда происходит сбой, администратор должен иметь возможность восстановить базу данных. Я уже говорил о восстановлении экземпляра (то есть о том, что происходит в случае сбоя экземпляра): в принципе, достаточно просто перезапустить его и Oracle сам применит все записи повторения из журнала, чтобы привести базу данных к состоянию, предшествовавшему сбою. Внимания здесь заслуживает момент, как Oracle минимизирует объем работ, необходимых для этого – и в этом ему помогают контрольная точка восстановления носителя, инкрементальная контрольная точка и записи с информацией о сохраненных блоках.

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

Примечание. Связь между переключением файлов журнала и контрольными точками восстановления носителя немного сложнее, чем я описал, и в Oracle 11g было добавлено два новых параметра настройки: _defer_log_boundary_ckpt (если установить в значение true, выполнение контрольной точки будет отложено до границы журнала) и _defer_log_count (число границ журнала для отложенной контрольной точки восстановления носителя). Фактически, эти два параметра позволяют настроить отложенное копирование буферов на диск в контрольных точках восстановления носителя, пока не произойдут дополнительные переключения файлов журнала. Этот механизм был реализован в версии 9i – со скрытыми параметрами управления – по-видимому в надежде, что ценой небольшой задержки в периоды пиковой нагрузки можно будет распределить операции записи по инкрементальным контрольным точкам, которые иначе пришлось бы выполнить контрольной точке восстановления носителя.

Итак, когда экземпляр перезапускается, он может проверить наименьший номер SCN, записанный в заголовки файлов данных. (Здесь может возникать множество сложностей, таких как автономные события, табличные пространства, доступные только для чтения, и т.д.. Но, если вы хотите во всех деталях разобраться, как выполняется восстановление, я рекомендую обратиться к специализированным книгам, посвященным только этой теме, которые обновляются для каждой новой версии Oracle.) Каждый файл журнала повторений хранит в своем заголовке наименьший номер SCN, записанный в нем. Это означает, что Oracle может сразу определить, с какого файла начать сканирование. Если быть более точным, управляющий файл также хранит последний инкрементальный номер SCN и RBA, то есть (если это не противоречит решению, принятому на основе заголовков файлов данных и заголовков файлов журнала повторений) Oracle может перейти сразу в нужное место, откуда можно начать применение записей повторения.

Но существует двухфазный подход к применению записей повторения. Сначала Oracle сканирует все журнальные записи, в поисках списков записанных блоков (block written record). Так как для каждого блока в списке хранится номер SCN последнего изменения, Oracle может сконструировать список всех блоков с большими значениями SCN, для блока, который заведомо хранится на диске. Затем, на втором проходе, Oracle может игнорировать векторы изменений для любых блоков в списке, если значение SCN в векторе изменений не выше номера SCN последнего изменения в блоке. Благодаря этому устраняется необходимость читать с диска блоки, не требующие пока применения векторов изменений.

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

Заключительный этап процедуры восстановления часто вызывает недопонимание. Многие задаются вопросом: «Что происходит с транзакциями, которые не были подтверждены?». Проще всего ответить на этот вопрос, предложив мысленный эксперимент: представьте, что вместо наблюдения за сбоем вы просто крикнули (очень громко): «Конец работы!». Для процедуры восстановления это в точности тот самый момент, до которого требуется выполнить восстановление Oracle (на техническом языке это обычно называют восстановлением с повтором, или «накатыванием», всех завершенных транзакций (rollforward)) – все (зарегистрированные в журнале) блоки в базе данных прекрасно восстанавливаются, включая блоки отмены и заголовки undo-сегментов с их таблицами транзакций. База данных выглядит так, как если бы она просто остановилась. То есть, если в этот момент вы захотите сымитировать последний этап восстановления, достаточно сообщить всем, что необходимо выполнить rollback. В реальной жизни такой точкой является момент, когда процесс smon (возможно с помощью, а иногда вопреки подчиненным параллельным процессам) берет управление на себя и откатывает все неподтвержденные транзакции, которые будут найдены в таблице транзакций.

 

Восстановление носителя

А теперь разберемся, чем отличаются восстановление экземпляра (instance recovery) от восстановления носителя (media recovery). В действительности – ни чем, если вы регулярно создавали копии своих файлов данных и архивировали файлы оперативного журнала (утилита Oracle RMAN значительно упрощает эти операции, если у вас достаточно места для хранения). Важно помнить, что вам потребуются все архивные файлы журнала, созданные с момента, когда была создана резервная копия файлов данных. В принципе можно взять резервную копию базы данных, созданную сразу после окончания выполнения инструкции create database, применить к ней все архивные файлы журнала, накопившиеся с того момента, и довести совершенно пустую базу данных до состояния, соответствующего последней подтвержденной транзакции. Конечно, это может занять много времени и, в зависимости от версии, потребовать от вас помучиться с добавлением несуществующих файлов. Однако сам принцип и механизмы остаются теми же: имея действительный блок и (архивный) журнал повторений, включающий последний номер SCN этого блока, можно в цикле находить и применять векторы изменений, пока блок не уйдет достаточно далеко во времени от первоначальной версии. Все остальное в процедуре восстановления – это лишь сопутствующие служебные операции и хранение.

Считаю важным упомянуть также процессы архивирования (arcN), потому что они могут выполнять массу операций записи, а данная статья как раз посвящена таким операциям. По сути, процесс архивирования копирует оперативный журнал в другое место, сразу после переключения файлов журнала. Обычно «другое место» находится на том же множестве жестких дисков, где располагается сама база данных. Процесс или процессы архивирования действуют очень эффективно, выполняя чтение и запись крупными блоками, но они осуществляют самый обычный ввод/вывод и многие часто забывают, что эти операции ввода/вывода создают нагрузку на систему, которая может быть одной из причин появления проблем с производительностью.

Иногда место для хранения архивов заполняется до отказа и тогда архиватор прекращает работу. Это означает прекращение копирования оперативных журналов повторений и lgwr не сможет повторно использовать файлы оперативного журнала, если было настроено архивирование и архиватору не удалось создать копию этого журнала. То есть, переполнение пространства для архивных копий (а в действительности, если вам очень не повезет, даже замедление работы хранилища архивов, например, из-за перегрузки сети) может привести к временной остановке базы данных. Приступая к использованию преимуществ, которые дает хранение архивных копий журнала, вы обязательно должны подумать о выделении достаточного пространства для этих копий и обеспечении быстрого доступа к нему.

 

Резервные базы данных Oracle

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

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

Еще одной особенностью резервных баз данных, вызывающей у меня беспокойство, является идея возложить на lgwr ответственность за первую стадию передачи журнала в удаленную систему в реальном времени и в режиме максимальной защиты для Data Guard. Реализация этого механизма продолжает изменяться, поэтому нам остается только надеяться, что разработчики Oracle своевременно будут обнаруживать и исправлять любые ошибки.

Как происходит восстановление данных в Oracle 

Ретроспективные базы данных Oracle

Журнал повторений обеспечивает движение вперед, а ретроспективная база данных Oracle (Flashback Database) – назад. На первый взгляд эти два механизма никак не связаны между собой; но без журнала и механизма восстановления ретроспекция в базе данных не будет работать. Ретроспективное журналирование (flashback logging) является еще одним источником большого числа операций ввода/вывода, что послужило причиной его включения в эту статью.

После включения механизма ретроспекции база данных начнет генерировать ретроспективный журнал (flashback log), который удивительно похож на файл Before-Image (BI), который поддерживался в Oracle 5 – он хранит целые блоки. Грубо говоря, перед изменением блока данных Oracle проверяет, записан ли он в текущий файл ретроспективного журнала, и при необходимости копирует его туда (через буфер ретроспективного журнала). Вопреки распространенному мнению, копирование выполняется не при каждом обновлении, поэтому ретроспективный журнал хранит весьма разреженную историю использования блоков в базе данных, которую саму по себе нельзя использовать для восстановления базы данных. Однако, ретроспективный журнал содержит достаточно информации для воссоздания ближайшей, более старой версии базы данных, чем нужно, и затем с помощью архивного журнала повторений восстановить («накатить») ее до требуемой точной версии.

Чтобы увидеть, как действует ретроспективное журналирование, взгляните на рис. 1, где представлено развитие единственного блока в базе данных. С течением времени он преодолевает десять разных версий, часть из которых попала в ретроспективный журнал. В нижней части рис. 1 показаны версии блока, сохраненные в файлах ретроспективного журнала. Обратите внимание, что каждый файл характеризуется номером SCN, текущим на момент сохранения в файле первой записи.

Схема ретроспективного журналирования Oracle

Рис. 1. Схема ретроспективного журналирования

Представьте теперь, что мы пытаемся вернуться в прошлое, до номера SCN 132 867, то есть до номера SCN, которому соответствует версия 3 блока, которая никогда не сохранялась в ретроспективном журнале. Ретроспекция – это процесс, состоящий из двух этапов: на первом этапе выполняется возврат до ближайшей старшей версии блока. Любой блок, хранящийся в файле 195 журнала, будет иметь номер SCN последнего изменения меньше 133 279, но совершенно необязательно, что в нем найдется блок с номером SCN меньше искомого SCN. Любой блок, хранящийся в файле 194 журнала, будет иметь номер SCN последнего изменения меньше 132 564, поэтому данный файл является хорошей начальной точкой. Так же поступает и реализация в Oracle – она читает список файлов ретроспективного журнала в обратном направлении (начиная с самого нового), перезаписывает существующие блоки блоками из журнала, если только блок из ретроспективного журнала имеет номер SCN последнего изменения меньше искомого.

Когда этот этап завершится, в реконструированной базе данных не останется блоков, более новых, чем они должны быть. К сожалению, остается множество блоков, старше искомого; наш блок, например, будет иметь версию 2, хотя нам требуется вернуться в точку во времени, когда текущей была версия 3. То есть мы имеем немного неполную базу данных. Но это не является большой проблемой, если имеются архивные файлы журнала повторений. Далее Oracle начинает движение в обратную сторону – восстанавливать базу данных, начиная с архивного файла журнала повторений, имеющего SCN 132 564, и останавливается, достигнув искомого номера SCN. Затем, как при любом другом восстановлении, выполняется откат всех неподтвержденных транзакций, обнаруженных в таблице транзакций.

 

Побочные эффекты

Кроме увеличения накладных расходов на ввод/вывод, которые влечет за собой ретроспективное журналирование, также увеличатся накладные расходы на ввод/вывод из-за изменения способа обработки табличных пространств. Когда требуется записать блок отмены по-верх существующего (исключая заголовок сегмента) и увеличить его порядковый номер, просто создается новая версия блока в памяти, но если включена поддержка ретроспективного журналирования, старая версия блока будет прочитана с диска и записана в ретроспективный журнал – это событие фиксируется в статистике physical reads for flashback new. А если часто выполняются служебные операции, такие как create table и rebuild index, вы наверняка заметите, что эти задачи выполняются дольше обычного и выполняют больше операций ввода/вывода, потому что любое пространство, куда записывается новый блок, сохраняется в ретроспективный журнал перед повторным использованием.

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

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

 

В заключение

Oracle использует стратегию опережающего журналирования (writeahead logging), то есть измененные блоки данных не сохраняются в файлах, пока не будет сохранено описание этих изменений.

За исключением скрытой оптимизации в PL/SQL и документированного варианта подтверждения в Oracle 10g, сохранность транзакций обеспечивается в соответствии с правилом, требующим записи буфера журнала на диск в момент подтверждения транзакции. Запись буфера журнала осуществляется отдельным процессом lgwr. Каждый раз, когда сеанс подтверждает транзакцию, он посылает сообщение, получив которое процесс lgwr записывает содержимое буфера на диск (если в этот момент lgwr не занят записью буфера), и затем переходит в режим ожидания ответного сообщения от lgwr.

Блоки данных копируются на диск в отложенном режиме. Существует две основных стратегии, используемые в Oracle для выбора следующих блоков для копирования. Одна из них предусматривает простое копирование блоков, измененных раньше других. Другая предусматривает копирование измененных блоков, которые могут быть вытолкнуты из кэша алгоритмом LRU/TCH.

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

Стратегия LRU/TCH требует, чтобы вся цепочка LRU в Oracle заканчивалась второй парой связанных списков. Всего получается четыре отдельных цепочки: REPL_MAIN, REPL_AUX, WRITE_MAIN и WRITE_AUX. Первую пару часто называют списком замены (replacement list), а вторую – списком записи (write list, или LRU-W).
Когда сеанс ищет свободный буфер, он просматривает список замены, начиная с REPL_AUX, и переносит все измененные («грязные») и не закрепленные буферы в список WRITE_MAIN. Когда процесс dbwr «просыпается» (что происходит каждые 3 секунды или когда сеанс посылает ему сообщение), он проверяет список WRITE_MAIN на наличие буферов, копирует их на диск, предварительно переместив в список WRITE_AUX, и затем перемещает скопированные буферы в список REPL_AUX, помечая их как «чистые».

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

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

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

Ищем и исправляем ошибки в баз...
Ищем и исправляем ошибки в баз... 6815 просмотров Александров Попков Tue, 21 Nov 2017, 13:18:05
Восстановление баз данных Orac...
Восстановление баз данных Orac... 9449 просмотров Дэн Tue, 21 Nov 2017, 13:18:05
Выполнение восстановления базы...
Выполнение восстановления базы... 9722 просмотров Дэн Tue, 21 Nov 2017, 13:18:05
Oracle Data Guard: резервные б...
Oracle Data Guard: резервные б... 7509 просмотров Андрей Волков Tue, 21 Nov 2017, 13:18:05
Войдите чтобы комментировать