23 июня 2020 г.

Базовые механизмы СУБД Oracle: Redo Logs и Undo Segments

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

Поэтому этот пост прошу воспринимать не как попытку показать какой я умный, а как попытку упорядочить картину прежде всего у себя в голове. Знаете же выражение: пока объяснял, сам понял. :)


Теперь можно начинать. :)

Представим базовую часть СУБД Oracle в виде схемы, изображённой на рисунке 1. Предупреждаю сразу: тут далеко не все части и процессы Oracle. Я отобразил только те процессы и компоненты, которые важны в рамках механизмов, которые я буду описывать далее.

Рис. 1. Базовая структура базы данных Oracle.

СУБД Oracle можно разделить на две части:
  • инстанция базы данных, состоящая из процессов и общих областей памяти (System Global Area или SGA), 
  • файлы базы данных на уровне файловой системы.

Как вы скорее всего уже знаете, при использовании базы данных Oracle в SAP системах в качестве клиентов базы данных выступают рабочие процессы SAP инстанций (SAP WPs). Каждому такому процессу соответствует один рабочий процесс со стороны инстанции Oracle (shadow process).


Data block
Самая маленькая логическая единица, которую Oracle использует при операциях с данными - это data block. При создании базы данных его размер можно выбрать, но в SAP инсталляциях размер data block всегда 8 Кб (8 192 байт).


Database buffer cache
Все данные базы данных Oracle содержатся в дата-файлах (data files), которые хранятся на дисковом хранилище. Однако обработка данных никогда не производится напрямую в файлах. При операциях чтения соответствующий процесс базы данных (shadow process) сначала копирует данные из дата-файлов в Database buffer cache (конечно, если этих данных еще нет в кэше). И только после этого передаёт данные пользователю, то есть рабочему процессу SAP. Так как все подключенные к инстанции Oracle пользователи могут совместно использовать одни и те же, скопированные из дата-файлов в Database buffer cache, данные, то данный механизм существенно ускоряет последующие операции чтения.

Размер Database buffer cache инстанции Oracle имеет ограниченный размер, так как оперативная память сервера не безгранична. Поэтому в кэше хранятся только последние прочитанные блоки данных. А перезапись блоков кэша происходит по алгоритму LRU («наиболее давно используемый»).

Любые изменения данных в базе данных (операции INSERT, UPDATE или DELETE) также всегда производятся в Database buffer cache. При этом изменённые блоки кэша помечаются как «dirty blocks». При копировании данных в кэш такие блоки (dirty buffers) не могут быть перезаписаны shadow процессами, до тех пор пока эти изменённые блоки не будут скопированы в дата-файлы. Записью «dirty blocks» занимается не shadow процесс, а специальный фоновый процесс инстанции Oracle - DBW0 (database writer).

Процесс DBW0 активируется в следующих случаях:
  • перед тем, как скопировать данные в кэш, shadow процесс сканирует области Database buffer cache на наличие не изменённых блоков, которые можно перезаписать. И если количество сканированных блоков достигает определённого порогового значения, то shadow процесс сигнализирует DBW0, чтобы он записал часть «dirty blocks» на диск. DBW0 копирует часть «dirty blocks» в дата-файлы, используя алгоритм LSU (Least Number of Stream Used). После этого эти блоки в кэше становятся доступными для shadow процессов.
  • в момент Checkpoint, когда DBW0 записывает все «dirty blocks» из Database buffer cache в файлы на дисках. Событие Checkpoint инициируется фоновым процессом CKPT. Детали будут чуть ниже.

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

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


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

Как я уже рассказывал здесь, транзакция базы данных - это LUW (logical unit of work) сервера базы данных. Так как LUW всегда атомарная, то изменения из LUW должны быть или выполнены полностью, или полностью отменены. Для достижения консистентности данных (и консистентности чтения данных) в рамках концепции LUW СУБД Oracle использует Redo-записи для отката или восстановления (например, после сбоя) и Undo-записи для отката неподтверждённых (uncommitted) транзакций.


Redo-записи
Redo-записи содержат информацию необходимую и достаточную для того, чтобы реконструировать, восстановить или откатить, внесенные в базу данных с помощью SQL-запросов данные прежде всего в подтверждённых (commit) транзакциях.

Параллельно с изменением блоков данных в Database buffer cache, shadow процесс записывает Redo-записи в Redo log buffer. Это круговой буфер, находящийся в SGA, в который временно записываются все завершённые и незавершённые изменения данных. Фоновый процесс LGWR (log writer) периодически записывает порции записей из Redo log buffer последовательно на диск - в Online redo log file

Oracle redo log file имеет заранее заданный фиксированный размер и не растёт динамически, как обычный файл. Поэтому, когда текущий Online redo log file заполняется, процесс LGWR закрывает файл и начинает запись в следующий. В SAP инсталляциях по умолчанию используется 4 группы Online redo log files по 2 копии файлов в каждой. Online redo log file, в который LGWR пишет в данный момент, называется CURRENT. А процедура переключения файлов называется log switch.

Так как количество Online redo log files также заранее ограничено, Oracle перезаписывает старые Redo-записи новыми, используя эти файлы по кругу. 

Каждый log switch СУБД увеличивает LSN (log sequence number). С помощью LSN Oracle автоматически создаёт последовательные номера для Redo log files

LGWR начинает запись в следующие моменты:
  • при подтверждении (commit) любой транзакции,
  • каждые 3 секунды,
  • когда Redo log buffer полон на одну треть,
  • когда DBW0 собирается записать изменённые блоки из Database buffer cache на диск, а некоторые соответствующие Redo-записи еще не были записаны в Online redo log files. Таким образом предотвращается попытка записи с опережением журналирования (write-ahead logging).

Этого достаточно для того, чтобы всегда иметь место для новых Redo-записей в Redo log buffer. При этом по умолчанию размер этого буфера при установке в SAP системах небольшой (1 - 8 Мб).

Дополнительно когда пользователь (рабочий процесс SAP) подтверждает завершение (commit) транзакции, транзакции присваивается SCN (system change number) базы данных. Oracle записывает SCN, вместе с Redo-записями транзакции в Redo log buffer. При этом DBW0 нет необходимости записывать блоки данных в момент подтверждения (commit) транзакции. Потому что в СУБД Oracle используется журналирование с опережением записи.

Новые значения модифицированных данных, которые хранятся в Redo-записях, называются «after images».


Undo-записи
Undo-записи содержат информацию необходимую для отмены или отката любых изменений в блоках данных, которые были выполнены в результате неподтверждённых (uncommitted) транзакций.

Undo-записи содержат старые значения изменённых данных, называемые «before images».

Oracle хранит Undo-записи в специальных Undo сегментах, которые хранятся в специальном пространстве - Undo space. При этом Undo space может быть реализовано двумя способами:
  • Automatic Undo Management (AUM),
  • Manual Undo Management.  

При AUM администратор должен лишь создать специальное табличное пространство - Undo tablespace (PSAPUNDO) достаточного размера и настроить пару параметров Oracle. Управление Undo сегментами СУБД осуществляет сама.

При ручном управлении необходимо создать и настроить некоторое количество Rollback segments, у которых необходимо тщательно рассчитать размер и параметры. Данные сегменты также располагаются в отдельном табличном пространстве (PSAPROLL). Про проблемы с данными сегментами у меня был отдельный пост

Начиная с Oracle 9i по умолчанию используется AUM.

Таким образом Undo-записи хранят информацию для транзакций, сохраняя её в Undo space, как минимум, до завершения транзакции. Так как данные записи используются для отката транзакций, то Undo-записи могут быть перезаписаны только после того, как транзакция будет подтверждена (commit) или сброшена (rollback). 

Стоит отметить, что Oracle может использовать Undo-записи и для других целей. Например, для консистентного чтения из snapshots. В этом случае данные читаются из «before images». В то время, как происходит изменение этих же данных в ещё неподтверждённых (uncommitted) транзакциях.


Control file
Каждая база данных Oracle имеет свой контрольный файл (control file). Это маленький бинарный файл, необходимый как в момент старта базы данных, так и в процессе работы. Следовательно данный файл должен быть всегда доступен на запись.

Control file содержит записи, которые определяют физическую структуру и состояние базы данных. Например, в нём хранится информация о табличных пространствах, именах и положении дата-файлов и Online redo log files, а также текущий LSN.

Править файл напрямую нельзя. Только процессы СУБД могут вносить изменения в control files. Если физическая структура базы данных изменяется (например, добавляется новый дата-файл), СУБД автоматически обновляет control file.

Oracle control file очень важен для работы базы данных. Поэтому несколько копий могут быть сохранены в разных местах, а СУБД обновляет их одновременно. В SAP системах по умолчанию сконфигурировано 3 копии control files.


Checkpoint
Checkpoint это момент времени, в котором файлы базы данных находятся в консистентном состоянии. Достигается это состояние тем, что в этот момент DBW0 сбрасывает все текущие изменённые блоки из Database buffer cache в дата-файлы. За инициацию события Checkpoint отвечает специальный фоновый процесс CKPT, который и даёт команду процессу DBW0 начать запись блоков. Одновременно Checkpoint обозначает специальную позицию в Redo log

Что происходит в момент Checkpoint:
  1. DBW0 активируется, получая сигнал в определённые моменты времени от фонового процесса CKTP.
  2. DBW0 копирует все текущие «dirty blocks» на диск. Причём, пока DBW0 закончит выполнять запись, другие блоки в кэше могут быть изменены, но они уже не записываются.
  3. Когда событие Checkpoint закончится (то есть будут записаны все выбранные блоки), самый старый буфер из «dirty blocks» в Database buffer cache будет обозначать точку в Redo log, после которой может быть начато восстановление в случае сбоя. Это позиция журнала и называется Checkpoint position.

Кроме этого процесс CKTP также выполняет следующие шаги:
  • записывает информацию о Checkpoint в заголовок каждого дата-файла,
  • записывает информацию о Checkpoint position в Online redo log file в контрольный файл Oracle (control file).

Информация о позиции Checkpoint в Online redo log file в контрольном файле необходима в процессе восстановления инстанции. Позиция Checkpoint сообщает инстанции Oracle, что все Redo-записи, которые были записаны до этого момента, не нуждаются в восстановлении. Так как эти данные уже записаны в дата-файлы.

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

Хотя частоту Checkpoint можно настроить через параметры Oracle, при разворачивании SAP систем эти параметры не используются. А Checkpoint всегда возникает только в моменты переключения Online redo log files (log switch).


Восстановление базы данных
Теперь основываясь на всех механизмах, которые были описаны выше, разберём как происходит восстановление базы данных.

Речь пойдёт не о восстановлении из резервной копии базы данных, которую должен выполнять администратор. А речь пойдёт об автоматическом восстановлении базы данных, которое СУБД производит в момент старта. Так называемое instance recovery. Оно необходимо, если предыдущий останов базы данных был выполнен не чисто, например, с опцией IMMEDIATE или ABORT. Или произошёл сбой работы сервера базы данных по аппаратной или программной причине.

Автоматическое восстановление при старте содержит следующие важные шаги:
  1. В control file находится последний Checkpoint. После этого, начиная с позиции Checkpoint, читаются Redo-записи из Online redo log files и заново проводятся все транзакции, указанные в журнале. Происходит процесс roll forward. Заметьте, что этот шаг всегда включает и проведение изменений для Undo space, то есть восстанавливаются «before images».
  2. Для всех заново применённых транзакций, которые не были подтверждены (commit) до сбоя или были отменены прямо перед сбоем (поэтому для них нет подтверждения в Redo log), выполняется откат. Для отката используется образ «before images» из Undo space. СУБД уверена, что это всегда возможно, потому что Undo-записи незавершённых транзакций из Undo space никогда не удаляются и не перезаписываются.

В результате после открытия консистентная база данных содержит только те изменения, которые были подтверждены (commit) перед сбоем.

Из процесса восстановления базы данных видно, что Online redo log files это одна из критически важных частей сервера Oracle. А если вспомнить, что в SAP установках Checkpoint наступает только в момент log switch, то при автоматическом восстановлении СУБД всегда нужен последний Online redo log file целиком. И если он будет потерян во время сбоя, то полное восстановление (complete recovery of database) будет невозможно. В результате чего данные будут потеряны, а база данных может оказаться в неконсистентном состоянии.

Поэтому-то Online redo log files должны храниться минимум в двух копиях, каждая из которых расположена на отдельном диске. Так же в продуктивной системе база данных должна работать в ARCHIVELOG режиме. В этом режиме фоновый процесс ARC0 (archiver) копирует каждый только что записанный Online redo log file в Offline redo log fileOffline redo log file в своём имени содержит LSN. Понятно, что копирование возможно начать только после переключения (log switch) и необходимо закончить до повторного возвращения процесса LGWR к этому файлу. Так как в таком режиме перезапись старых Redo-записей в Online redo log files не разрешается до тех пор, пока эти записи не скопированы в Offline redo log files.

Ну и должно соблюдаться ещё одно ограничение: могут быть перезаписаны только те Redo-записи, которые расположены до позиции Checkpoint в Redo log. То есть соответствующие им изменения уже записаны в дата-файлы. Это гарант возможности автоматического восстановления инстанции в случае сбоя.

Об Online redo log file и ARCHIVELOG режиме я подробно рассказывал в постах:

Если хотите разобраться в вопросах администрирования базы данных Oracle на практике, то можете приобрести мой обучающий курс SAPADM 2.0. Этой теме в курсе полностью посвящён третий пакет заданий. 


Автор: Шиболов Вячеслав Анатольевич

Комментариев нет:

Отправить комментарий