Открыть сервис

Write-Ahead Logging

Write-Ahead Logging (WAL, упреждающая запись журнала) — это техника обеспечения атомарности и долговечности транзакций в системах управления базами данных (СУБД) и других системах хранения данных. Основной принцип WAL заключается в том, что любые изменения данных сначала записываются в журнал (лог), и только после этого применяются к основному хранилищу. Этот подход позволяет гарантировать, что даже в случае сбоя системы (отключение питания, крах процесса) можно восстановить согласованное состояние данных, либо откатив незавершённые транзакции, либо завершив их на основе записей в журнале.

История и происхождение

Концепция WAL была разработана в 1970-х годах в рамках исследований в области транзакционных систем, в частности, в проекте System R компании IBM. Идея заключалась в том, чтобы отделить запись изменений от их непосредственного применения к страницам данных на диске. Это позволило решить проблему «грязной записи» (dirty write), когда частично записанная страница данных могла оказаться в неконсистентном состоянии после сбоя.

Ключевой вклад в формализацию WAL внесли работы Джима Грея (Jim Gray) и других исследователей. В 1992 году Грей опубликовал фундаментальную статью «The Transaction Concept: Virtues and Limitations», где подробно описал требования к журналированию. С тех пор WAL стал стандартом де-факто для большинства реляционных СУБД (PostgreSQL, MySQL, Oracle, SQL Server) и многих NoSQL-систем.

Основные принципы

Атомарность и долговечность

WAL обеспечивает два ключевых свойства ACID-транзакций:

Правило WAL

Фундаментальное правило WAL гласит: запись в журнал должна быть произведена до того, как соответствующее изменение будет записано в основное хранилище данных. Это означает, что журнал всегда содержит достаточно информации для восстановления состояния на любой момент времени.

Структура журнала

Журнал WAL представляет собой последовательный файл (или набор файлов), в который записываются логические или физические записи об изменениях. Каждая запись обычно содержит:

Контрольные точки (Checkpoints)

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

Виды журналирования

Физическое журналирование

Каждая запись в журнале содержит полный образ изменяемой страницы данных (до и/или после операции). Этот подход прост в реализации, но генерирует большой объём данных, так как даже изменение одного байта приводит к записи целой страницы (обычно 4–16 КБ).

Логическое журналирование

Журнал содержит только описание операции (например, «обновить поле X в строке Y на значение Z»). Это значительно уменьшает объём журнала, но усложняет восстановление, так как требуется повторное выполнение операций, что может быть медленнее.

Физиологическое журналирование (Physiological Logging)

Комбинация физического и логического подходов. Изменения записываются на уровне страниц (физически), но внутри страницы операции описываются логически. Этот метод используется в большинстве современных СУБД (например, в PostgreSQL и Oracle), так как он обеспечивает баланс между объёмом журнала и скоростью восстановления.

Процесс восстановления

При запуске после сбоя система выполняет три фазы восстановления:

  1. Фаза анализа (Analysis): система читает журнал, начиная с последней контрольной точки, и определяет, какие транзакции были зафиксированы (committed), а какие остались незавершёнными (in-flight).
  2. Фаза REDO (Redo): для всех зафиксированных транзакций, изменения которых ещё не были записаны в основное хранилище, повторно применяются записи из журнала. Это гарантирует долговечность.
  3. Фаза UNDO (Undo): для всех незавершённых транзакций отменяются их изменения на основе записей в журнале. Это гарантирует атомарность.

Применение

Реляционные СУБД

WAL является основой транзакционной системы во всех крупных реляционных СУБД:

NoSQL-системы

Многие NoSQL-системы также применяют WAL для обеспечения долговечности:

Файловые системы

Некоторые файловые системы, такие как ZFS и ext4 (в режиме журналирования), используют принципы WAL для обеспечения целостности метаданных. В этом случае журнал называется «журнал файловой системы» (journal).

Преимущества и недостатки

Преимущества

Недостатки

Интересные факты

Критика и альтернативы

Основная критика WAL связана с накладными расходами на ввод-вывод. В системах с очень высокой частотой транзакций (миллионы операций в секунду) запись каждого изменения в журнал может стать узким местом. Для решения этой проблемы используются:

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

Источники

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →