Какие данные берет БД из WAL журнала при восстановлении прерванной транзакции?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Восстановление прерванных транзакций из WAL в PostgreSQL
При восстановлении прерванной транзакции из Write-Ahead Logging (WAL) база данных (в контексте PostgreSQL) опирается на несколько ключевых типов данных, записанных в журнал. WAL — это механизм обеспечения ACID (Atomicity, Consistency, Isolation, Durability) свойств, особенно атомарности и долговечности.
Ключевые данные, извлекаемые из WAL для восстановления
Основные записи в WAL, участвующие в восстановлении прерванной транзакции:
-
Записи о начале и завершении транзакции
BEGINили аналогичная запись, идентифицирующая старт транзакции с уникальным Transaction ID (XID).COMMITилиROLLBACKзапись, отмечающая завершение. Если транзакция прервана (например, из-за сбоя), такая запись отсутствует.
-
Записи изменений данных (Heap Operations)
INSERT,UPDATE,DELETE— логические изменения в таблицах, включая:
- Старые и новые значения строк (для `UPDATE` и `DELETE` особенно важны старые значения для возможного отката).
- Идентификаторы блоков данных и смещения в них.
- Пример записи в WAL для UPDATE:
UPDATE accounts SET balance = balance + 100 WHERE id = 5;
В WAL сохраняются старый баланс (для возможного восстановления) и новый.
-
Записи о метаданных и структуре
- Изменения в индексах (индексные операции также журналируются).
- Изменения в системных таблицах (например, при создании таблицы в транзакции).
-
Записи контрольных точек (Checkpoint Records)
- Контрольные точки в WAL обозначают момент, когда все данные до этой точки гарантированно записаны в основное хранилище. При восстановлении система знает, от какой точки начинать анализ WAL.
Процесс восстановления прерванной транзакции
При аварийном завершении работы (например, сбой сервера) база данных запускает процесс восстановления при следующем старте:
Шаг 1: Определение точки начала восстановления
- Система читает последнюю успешную контрольную точку из WAL. Все данные до нее уже в основном хранилище.
Шаг 2: Проход по записям WAL после контрольной точки
- Считываются все записи, включая незавершенные транзакции. Для каждой транзакции анализируется:
- Если есть `COMMIT` — изменения применяются к данным.
- Если `COMMIT` отсутствует (транзакция прервана) — изменения **откатываются** с использованием старых значений из WAL.
Шаг 3: Откат прерванной транзакции
- Для каждой операции
INSERT,UPDATE,DELETEв прерванной транзакции:
- `INSERT`: запись удаляется (используется информация о расположении строки).
- `UPDATE`: новое значение заменяется старым (старое значение хранится в WAL).
- `DELETE`: запись восстанавливается из старых данных.
Пример логического отката UPDATE из кода:
// Пример логики восстановления (не реальный код PostgreSQL)
func rollbackUpdate(walRecord WalRecord) {
oldData := walRecord.OldRowData
blockId := walRecord.BlockId
offset := walRecord.RowOffset
// Восстанавливаем старые данные в основное хранилище
writeToHeap(blockId, offset, oldData)
}
Технические особенности в PostgreSQL
- Физический и логический уровень WAL: PostgreSQL использует преимущественно физиологический журнал (хранит изменения на уровне блоков), но с логической информацией (например, для HOT-updates). Это позволяет эффективно восстанавливать/откатывать.
- Неполные записи: Если сама запись в WAL повреждена или неполна (например, сбой во время записи WAL), восстановление может остановиться на последней целой записи.
Роль параметров и механизмов
- wal_level: параметр, определяющий детальность журналирования (
replica,minimal,logical). Для полного восстановления транзакций необходим хотя быreplica. - Двойная запись: В некоторых случаях (например, при использовании
full_page_writes) в WAL записываются целые страницы данных после контрольной точки, что помогает восстановиться при повреждении страниц в основном хранилище.
Итог: Для восстановления прерванной транзакции БД извлекает из WAL полный след транзакции — ее начало, все изменения данных с необходимыми старыми/новыми значениями, и отсутствие записи о завершении. Это позволяет атомарно откатить все изменения, обеспечивая Atomicity. Без WAL гарантированное восстановление после сбоя было бы невозможно.