Пользователь
0,0
рейтинг
8 ноября 2011 в 10:52

Разработка → Online redo logs или Событие контрольной точки в Oracle из песочницы

Довольно часто случается такая неприятность, что в alert.log базы одно за другим сыпятся сообщения типа «Checkpoint not complete». Стандартный совет в этом случае: «увеличьте количество и/или размер redo логов». А дальше вопрос, кто такие эти redo логи и с чем их едят.

Немного теории


Итак. Когда приложение запрашивает данные, база складывает их в буферный кэш — область памяти в SGA. Когда данные изменяются, база производит изменения не непосредственно в файле данных, а в буферном кэше. Одновременно в отдельную область памяти — redo log buffer — записывается информация, по которой, в случае необходимости, можно будет повторить произошедшее изменение. Когда изменение фиксируется (commit), оно, опять же, не сбрасывается сразу в файл данных, но информация из redo log buffer сбрасывается в online redo лог — специально для этого предназначенный файл. До тех пор, пока изменение не записано в файл данных, необходимо хранить информацию о нём где-то на диске на тот случай, если база упадёт. Если, к примеру, выключится питание сервера, то, само собой, все данные, хранящиеся в памяти, будут потеряны. В этом случае redo лог — это единственное место, где хранится информация о произошедшем изменении. После рестарта базы Oracle фактически повторит прошедшую транзакцию, вновь изменит нужные блоки и сделает commit. Поэтому до тех пор, пока информация из redo лога не будет сброшена в файл данных, повторно использовать этот redo лог невозможно.

Специальный фоновый процесс базы данных DBWn по мере необходимости освобождает буферный кэш, а также выполняет событие контрольной точки (checkpoint). Контрольная точка — это событие, во время которого «грязные» (изменённые) блоки записываются в файлы данных. За событие контрольной точки отвечает процесс CKPT (checkpoint process), который и пишет информацию о контрольной точке в control file (о том, что такое control file, в другой раз) и заголовки файлов данных.

Событие контрольной точки обеспечивает согласованность данных и быстрое восстановление базы. Восстановление данных ускоряется, т.к. все изменения до контрольной точки пишутся в файлы данных. Это избавляет от необходимости во время восстановления применять redo логи, сгенерированные до контрольной точки. Контрольная точка гарантирует, что все изменённые блоки в кэше действительно записаны в соответствующие файлы данных.

Существует несколько видов контрольных точек.
  • Потоковые контрольные точки (thread checkpoins). В файл данных пишутся подряд все изменения, произошедшие в рамках определённого экземпляра до определённого момента. Случаются они в следующих ситуациях:
    • полная остановка базы;
    • alter system checkpoint;
    • переключение online redo лога;
    • alter database begin backup.
  • Контрольные точки файлов данных и табличных пространств. Случаются, когда происходят операции с табличными пространствами и файлами данных (alter tablespace offline, alter tablespace read only, ужатие файла данных и.т.п.)
  • Инкрементальные контрольные точки. Подвид контрольной точки экземпляра, предназначенный для того, чтобы избежать записи на диск огромного количества блоков во время переключения redo логов. Процесс DBWn как минимум раз в три секунды проверяет, появились ли новые «грязные» блоки для записи на диск. Если появились, то они заносятся в файлы данных, метка контрольной точки в redo лог сдвигается (чтобы в следующий раз пришлось просматривать меньше логов), но заголовки файлов данных при этом не изменяются.
Частые события контрольной точки обеспечивают более быстрое восстановление после сбоев, но могут вызвать ухудшение производительности. В зависимости от количества файлов данных в системе, событие контрольной точки может быть достаточно ресурсоёмкой операцией, т.к. в этот момент все заголовки всех файлов данных становятся недоступны.

Параметры, от которых зависит частота событий контрольной точки и которые при желании можно настраивать:
  • FAST_START_MTTR_TARGET (сколько времени в секундах займёт восстановление базы после сбоя; если я что-нибудь в чём-нибудь понимаю, то речь идёт о времени, которое потребуется для применения имеющихся в наличии online redo логов).
  • LOG_CHECKPOINT_INTERVAL (частота события контрольной точки — допустимое количество блоков файла online redo log, которые были заполнены после пердыдущей контрольной точки; блоки — это блоки в терминах операционной системы, а не базы данных).
  • LOG_CHECKPOINT_TIMEOUT (максимально допустимое количество секунд, между двумя событиями контрольной точки).
  • LOG_CHECKPOINTS_TO_ALERT (true/false; определяет, скидывать ли переключение контрольной точки в alert.log; полезная штука, лучше бы выставить в true).

Имеет смысл уточнить, что параметры FAST_START_MTTR_TARGET и LOG_CHECKPOINT_INTERVAL, если верить документации, являются взаимоисключающими.

Заглянем теперь в нашу базу

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

Для отслеживания частоты переключения логов можно заглянуть в alert log.
Пример переключения online redo логов.

Wed Nov 02 17:51:20 2011
Thread 1 advanced to log sequence 83 (LGWR switch)
  Current log# 2 seq# 83 mem# 0: D:\ORACLE\ORADATA\ORADB\REDO02.LOG
Thread 1 advanced to log sequence 84 (LGWR switch)
  Current log# 3 seq# 84 mem# 0: D:\ORACLE\ORADATA\ORADB\REDO03.LOG

Иногда в alert.log можно обнаружить следующие ошибки.

Wed Nov 02 17:51:53 2011
Thread 1 cannot allocate new log, sequence 87
Checkpoint not complete
  Current log# 2 seq# 86 mem# 0: D:\ORACLE\ORADATA\ORADB\REDO02.LOG

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

Из cookbook. Как изменить размер и/или количество online redo логов



1. Для начала просто посмотрим на состояние логов.

SQL> select group#, bytes, status from v$log;

    GROUP#      BYTES STATUS
---------- ---------- ----------------
         1   52428800 ACTIVE
         2   52428800 ACTIVE
         3   52428800 CURRENT

Попробуем увеличить размеры логов до 100M.

2. Посмотрим непосредственно на файлы redo логов.

SQL> select group#, member from v$logfile;

    GROUP# MEMBER
---------- ----------------------------------------
         3 D:\ORACLE\ORADATA\ORADB\REDO03.LOG
         2 D:\ORACLE\ORADATA\ORADB\REDO02.LOG
         1 D:\ORACLE\ORADATA\ORADB\REDO01.LOG

3. Создадим три новых группы логов по 100M каждая.

SQL> alter database add logfile group 4 'D:\ORACLE\ORADATA\ORADB\REDO04.LOG' size 100M;

Database altered.

SQL> alter database add logfile group 5 'D:\ORACLE\ORADATA\ORADB\REDO05.LOG' size 100M;

Database altered.

SQL> alter database add logfile group 6 'D:\ORACLE\ORADATA\ORADB\REDO06.LOG' size 100M;

Database altered.

Посмотрим, что получилось

SQL> select group#, bytes, status from v$log;

    GROUP#      BYTES STATUS
---------- ---------- ----------------
         1   52428800 INACTIVE
         2   52428800 INACTIVE
         3   52428800 INACTIVE
         4  104857600 INACTIVE
         5  104857600 ACTIVE
         6  104857600 CURRENT

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

SQL> alter system switch logfile;

Теперь с чистой совестью удаляем лишние логи
                                
SQL> alter database drop logfile group 1;

Database altered.

SQL> alter database drop logfile group 2;

Database altered.

SQL> alter database drop logfile group 3;
alter database drop logfile group 3
*
ERROR at line 1:
ORA-01624: log 3 needed for crash recovery of instance oradb (thread 1)
ORA-00312: online log 3 thread 1: 'D:\ORACLE\ORADATA\ORADB\REDO03.LOG'

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

SQL> alter system checkpoint;

System altered.

После чего смело повторяем попытку.

SQL> alter database drop logfile group 3;

Database altered.

5. Проверим, всё ли у нас получилось.

SQL> select group#, bytes, status from v$log;

    GROUP#      BYTES STATUS
---------- ---------- ----------------
         4  104857600 ACTIVE
         5  104857600 ACTIVE
         6  104857600 CURRENT

6. Сейчас самое время сделать бэкап базы. Так, на всякий случай.

7. Теперь можно удалить лишние файлы операционной системы.
D:\> del D:\oracle\oradata\oradb\REDO01.LOG
D:\> del D:\oracle\oradata\oradb\REDO02.LOG
D:\> del D:\oracle\oradata\oradb\REDO03.LOG                                                  


Что делать, если у нас установлен Oracle RAC.

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

Команда ALTER SYSTEM CHECKPOINT LOCAL работает только с экземпляром, с которым вы в данный момент соединены. Чтобы вызвать событие контрольной точки для всей базы, нужно вызвать ALTER SYSTEM CHECKPOINT или ALTER SYSTEM CHECKPOINT GLOBAL.

Команда ALTER SYSTEM SWITCH LOGFILE влияет только на тот экземпляр, с которым вы в данный момент соединены. Чтобы переключить online redo логи для всей системы можно воспользоваться командой ALTER SYSTEM ARCHIVE LOG CURRENT.

Создавать новые online redo логи придётся для каждого экземпляра в отдельности.
ALTER DATABASE ADD LOGFILE THREAD 1 GROUP 4 '+ASMGRP/ORADB/REDO04.LOG' SIZE 100M;
ALTER DATABASE ADD LOGFILE THREAD 2 GROUP 4 '+ASMGRP/ORADB/REDO04.LOG' SIZE 100M;

Кстати, имя файла можно не указывать. База сама назовёт его в соответствии сосвоими представлениями о прекрасном.

Ещё кстати. Можно файлы online redo логов размножить.
ALTER DATABASE ADD LOGFILE GROUP 7 ('D:\ORACLE\ORADATA\ORADB\REDO07.LOG','C:\ORACLE\ORADATA\ORADB\REDO07.LOG') SIZE 100M;

Зачем размножить? Потому что, если по каким-то причинам файл online redo лога будет повреждён или потерян, то, имея его неповреждённую и непотерянную копию на другом диске, восстановление — дело двух минут. А вот если копии нет, то придётся повозиться (но процесс восстановления утерянных redo логов — уже совсем другая история).

___________________________
Литература
Oracle Database 11.2 official documentation.
Oracle Support nodes 147468.1 and 1035935.6
Thomas Kyte, Expert Oracle Database Architecture: 9i and 10g Programming Techniques and Solutions
@mashuka
карма
7,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (2)

  • 0
    Спасибо за статью.
    Маловато написано про параметры. По моему опыту обычно ставится:
    LOG_CHECKPOINT_INTERVAL=0
    LOG_CHECKPOINT_TIMEOUT=0
    LOG_CHECKPOINTS_TO_ALERT=true
    И основным параметром для настройки активности dbwr является:
    FAST_START_MTTR_TARGET
    Изначально можно поставить в 0 или 1800 и плавно уменьшать при наличии checkpoint not complete или желании более быстрого recover при crash.
    Для скорости работы dbwr также критично наличие возможности асинхрнного ввода-вывода, определяется комбинацией операционной системы и используемого способа хранения datafiles (фс,raw,asm).
    • 0
      Пожалуй, да, надо бы дополнить про параметры. Спасибо.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.