Redo Log Buffer
Redo Log Buffer — это область оперативной памяти в системе управления базами данных (СУБД) Oracle, предназначенная для временного хранения записей о всех изменениях, вносимых в базу данных, до их фиксации на диске в файлах redo log. Является критическим компонентом механизма восстановления после сбоев (instance recovery), обеспечивая возможность повторного применения (redo) изменений, которые были выполнены, но ещё не записаны в файлы данных.
Назначение и принцип работы
Роль в архитектуре Oracle
В архитектуре СУБД Oracle изменения данных сначала вносятся в буферный кэш данных (database buffer cache) в оперативной памяти. Параллельно с этим для каждого изменения генерируется запись redo — последовательность байт, описывающая, какое именно изменение было выполнено (например, изменение конкретного байта в блоке данных). Эти записи сначала помещаются в Redo Log Buffer, а затем, при наступлении определённых условий, записываются в файлы redo log на диске. Такой подход позволяет минимизировать количество операций ввода-вывода (I/O) на критическом пути транзакции: вместо того чтобы сразу писать на диск каждое изменение, система накапливает записи в памяти и сбрасывает их одной крупной порцией.
Связь с механизмом восстановления
Redo Log Buffer является частью механизма, обеспечивающего свойство durability (долговечность) транзакций. Если происходит сбой экземпляра Oracle (например, отключение питания), все изменения, которые были зафиксированы (committed) и чьи записи redo уже были записаны в файлы redo log, могут быть восстановлены при следующем запуске. Записи, которые остались только в буфере (не были сброшены на диск), теряются, и соответствующие незавершённые транзакции откатываются (rollback).
Размер и управление
Размер буфера
Размер Redo Log Buffer задаётся параметром инициализации LOG_BUFFER. Значение по умолчанию зависит от версии Oracle и размера оперативной памяти, но обычно составляет несколько мегабайт (например, от 512 КБ до 32 МБ). Размер буфера не может быть изменён динамически без перезапуска экземпляра.
Управление в памяти
Буфер представляет собой циклический массив (circular buffer) в общей глобальной области (Shared Global Area, SGA). Записи в буфере обрабатываются фоновым процессом LGWR (Log Writer). LGWR отвечает за сброс содержимого буфера в файлы redo log. Приоритеты сброса:
- По команде COMMIT: при выполнении оператора COMMIT LGWR немедленно записывает все накопленные записи redo для данной транзакции на диск. Только после успешной записи управление возвращается пользователю.
- При заполнении буфера на треть: если буфер заполняется на одну треть, LGWR инициирует сброс.
- Каждые три секунды: LGWR выполняет сброс по таймеру, даже если буфер заполнен незначительно.
- Перед записью блоков данных: если процесс DBWn (Database Writer) готовится записать изменённые блоки данных на диск, он сначала запрашивает LGWR сбросить соответствующие записи redo.
Структура записи redo
Формат записи
Каждая запись redo состоит из заголовка и тела. Заголовок содержит:
- SCN (System Change Number): номер системного изменения, уникальный идентификатор момента времени в базе данных.
- Идентификатор транзакции: связь с конкретной транзакцией.
- Тип изменения: вставка, обновление, удаление, изменение структуры таблицы и т.д.
Тело записи содержит информацию, необходимую для повторного применения изменения: номер файла данных, номер блока, смещение внутри блока, старое и новое значение (или только новое, в зависимости от режима).
Виды redo-записей
- Redo для изменений данных: записываются при любых DML-операциях (INSERT, UPDATE, DELETE).
- Redo для изменений словаря данных: генерируются при DDL-операциях (CREATE, ALTER, DROP).
- Redo для изменений отката (undo): сами изменения в таблицах отката (undo segments) также генерируют redo-записи, чтобы обеспечить восстановление и самих откатных сегментов.
Производительность и настройка
Влияние на быстродействие
Redo Log Buffer является узким местом при высокой интенсивности изменений. Если буфер слишком мал, LGWR будет сбрасывать его слишком часто, что приведёт к увеличению количества операций I/O и снижению пропускной способности. Если буфер слишком велик, записи будут задерживаться в памяти, и при сбое может быть потеряно больше незавершённых транзакций.
Признаки проблем
- Ожидания «log buffer space»: если сессии ожидают освобождения места в буфере из-за медленной записи LGWR, это указывает на то, что буфер слишком мал или диски redo log слишком медленные.
- Ожидания «log file sync»: возникают, когда процесс COMMIT ожидает завершения записи LGWR. Частая причина — слишком медленная подсистема ввода-вывода для redo log.
- Высокая активность LGWR: если LGWR работает практически непрерывно, это может быть признаком неоптимального размера буфера.
Рекомендации по настройке
- Размер
LOG_BUFFERобычно не требует ручной настройки, так как Oracle автоматически выбирает разумное значение. Однако в системах с очень высокой нагрузкой на запись (например, OLTP-системы с тысячами транзакций в секунду) может потребоваться увеличение буфера до 64–128 МБ. - Ключевым фактором производительности является не столько размер буфера, сколько скорость подсистемы ввода-вывода для файлов redo log. Рекомендуется размещать redo log на быстрых SSD-дисках или в отдельной файловой системе с низкой задержкой.
- Использование групповой фиксации (group commit): Oracle автоматически объединяет несколько операций COMMIT в одну запись, что снижает нагрузку на I/O.
Альтернативные механизмы в других СУБД
PostgreSQL: Write-Ahead Log (WAL)
В PostgreSQL аналогом Redo Log Buffer является буфер WAL (Write-Ahead Log). Записи сначала помещаются в буфер WAL в оперативной памяти, а затем сбрасываются на диск процессом WAL writer. Размер буфера задаётся параметром wal_buffers. Принцип работы схож: все изменения сначала фиксируются в WAL, и только после этого могут быть записаны в файлы данных.
MySQL (InnoDB): Redo Log Buffer
В движке InnoDB СУБД MySQL также существует redo log buffer. Он управляется параметром innodb_log_buffer_size. Размер по умолчанию — 16 МБ. Принцип работы аналогичен Oracle: записи redo накапливаются в буфере, а затем сбрасываются в файлы redo log (ib_logfile0, ib_logfile1) процессом log writer.
Microsoft SQL Server: Transaction Log Buffer
В SQL Server аналогом является буфер журнала транзакций (transaction log buffer). Записи помещаются в буфер и сбрасываются на диск процессом log writer. Размер буфера фиксирован и не настраивается напрямую (обычно 60 КБ на каждую базу данных).
Интересные факты
- В Oracle Redo Log Buffer является частью SGA и доступен всем процессам экземпляра. Это означает, что записи от разных сессий перемешиваются в буфере в порядке их поступления.
- Запись в Redo Log Buffer выполняется с использованием механизма «copy on write»: каждая сессия копирует свою redo-запись в буфер, а не создаёт её там с нуля.
- В случае сбоя экземпляра Oracle автоматически выполняет восстановление (instance recovery) при следующем запуске, считывая redo log и применяя изменения к файлам данных. Redo Log Buffer при этом не участвует, так как его содержимое теряется при сбое.
Источники
- Oracle Database Concepts, 19c (Oracle Corporation)
- Oracle Database Performance Tuning Guide, 19c (Oracle Corporation)
- PostgreSQL Documentation, Chapter 30: Reliability and the Write-Ahead Log (PostgreSQL Global Development Group)
- MySQL 8.0 Reference Manual, Chapter 15: InnoDB Redo Log (Oracle Corporation)
- Microsoft SQL Server Documentation: Transaction Log Architecture (Microsoft Corporation)
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →