Восстановление после сбоя
Две разные истории, которые новички смешивают
Фраза «восстановить базу» в разговоре означает две разные задачи. Их путают — и тогда ждут от pg_dump того, что делает WAL при перезагрузке, или наоборот.
| Задача | Типичный вопрос | Кто решает | Где в энциклопедии |
|---|---|---|---|
| Восстановление после сбоя | Сервер упал / выдернули питание — поднимется ли БД сама? | Движок СУБД (WAL, redo/undo) | эта глава |
| Восстановление из резервной копии | Удалили таблицу / сгорел диск — как вернуть данные? | DBA, pg_dump, PITR | 106, Управление РСУБД |
Аналогия. Crash recovery — как если вы выключили Word без сохранения, а программа при следующем запуске сама подтянула автосохранение из служебного журнала. Бэкап — как копия всего документа на флешке вчера: если сгорел ноутбук, журнал Word уже не поможет.
Обе темы важны. Бэкап без понимания WAL — неясно, до какого момента времени можно откатиться (RPO). WAL без бэкапа — после уничтожения диска журнал на том же диске тоже пропал.
В теоретических основах мы уже упоминали Write-Ahead Logging (WAL): сначала запись в журнал, потом — в файлы таблиц. Здесь развернём цепочку: checkpoint → redo → undo и пройдём сценарий «упал сервер — подняли снова».
Термины главы
| Термин | Простыми словами |
|---|---|
| WAL | Журнал «что изменилось» — пишется раньше, чем данные на диске в файлах таблиц. |
| Страница | Кусок файла таблицы (часто 8 КБ в PostgreSQL) — единица чтения/записи с диска. |
| Dirty page | Страница в RAM изменена, на диске ещё старая копия. |
| Checkpoint | Точка, с которой при старте проигрывают меньший хвост WAL. |
| Redo | «Докатить» закоммиченные изменения на диск. |
| Undo | «Откатить» незавершённые транзакции. |
| PITR | Восстановление на момент времени из бэкапа + архив WAL (уже работа DBA). |
Что может пойти не так
- обрыв питания на сервере БД;
- падение процесса
postgres/mysqld/sqlservr; - «жёсткий» kill -9 во время активной записи;
- сбой диска после записи в WAL, но до сброса «грязных» страниц в файл таблицы.
Цель восстановления: при старте СУБД приводит базу к согласованному состоянию — либо все эффекты закоммиченных транзакций на месте, либо незавершённые откатаны, как будто их не было.
WAL — журнал опережающей записи
Принцип WAL (Write-Ahead Logging): любое изменение, которое должно пережить сбой, сначала записывается в журнал (последовательный файл, только дописывание в конец), и потом (может быть через секунды) отражается в файлах таблиц на диске.
Зачем так делают:
- Скорость — дописать в конец одного файла журнала дешевле, чем искать случайные страницы по всем таблицам.
- Надёжность — при обрыве питания на диске в журнале уже есть «мы списали 100 ₽ со счёта 1»; при старте СУБД повторит это на странице счёта (redo).
В PostgreSQL журнал лежит в каталоге pg_wal (раньше называли pg_xlog). В Oracle — redo log, в SQL Server — transaction log. Имена разные, роль одна.
Связь с COMMIT (разбор для новичка):
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;
После COMMIT клиент видит «OK». Внутри PostgreSQL (упрощённо):
- В WAL записано: «изменение balance на счёте 1».
- В WAL записано: «COMMIT транзакции № 12345».
- WAL сброшен на диск (
fsync) — буква D (Durability) из ACID. - Страница таблицы
accountsможет ещё жить только в RAM — это нормально.
Значит: commit ≠ «всё уже на диске в файле таблицы». Commit = «запись о результате не потеряется при сбое, потому что она в WAL».
Подробнее про транзакции: 77.md.
Страницы в памяти и на диске
Данные в таблицах лежат страницами (часто 8 КБ) — см. 4.md и 3.md. Активная работа идёт в буферном пуле (RAM):
- транзакция меняет строку → меняется копия страницы в RAM;
- в WAL пишется запись «что изменилось»;
- страница помечается «грязной» (dirty);
- позже фоновый процесс сбрасывает грязные страницы на диск — не обязательно до
COMMIT.
При сбое в RAM всё теряется. На диске остаются старые версии страниц + полный WAL с момента последней контрольной точки.
Контрольная точка (checkpoint)
Checkpoint — момент, когда СУБД гарантирует: все грязные страницы, изменённые до этой точки, записаны в файлы данных, а соответствующие записи WAL можно считать «уже отражёнными» в файлах (упрощённо — для понимания; детали зависят от СУБД).
Зачем: при старте после сбоя не нужно проигрывать WAL с начала времени — только с последнего checkpoint.
В PostgreSQL параметры checkpoint_timeout, checkpoint_completion_target — в справочнике администрирования.
Частая ошибка: думать, что checkpoint «заменяет» commit. Нет: commit фиксирует транзакцию в WAL; checkpoint разгружает объём redo при recovery.
Redo и undo — две стороны recovery
При старте после аварии движок выполняет crash recovery — автоматически, до того как пустит клиентов.
Redo (повтор, «докатить вперёд»)
Задача: применить к страницам на диске изменения из WAL, которые уже закоммичены, но не успели попасть в файлы таблиц до сбоя.
Пример. В WAL есть: «счёт 1: balance = 900» и «COMMIT». На диске в файле таблицы всё ещё balance = 1000 (страница не сбросили из RAM). Redo перепишет страницу так, чтобы на диске стало 900.
Undo (откат, «убрать лишнее»)
Задача: отменить эффекты транзакций без COMMIT в WAL — они оборвались при падении.
Пример. В WAL есть «UPDATE счёт 2: balance = 5000», но нет COMMIT для этой транзакции. Пользователь не должен видеть 5000 — undo (или эквивалент в MVCC) возвращает согласованное состояние, как до начала этой транзакции.
| Фаза | Вопрос | Действие |
|---|---|---|
| Redo | Что успели зафиксировать? | Применить закоммиченное из WAL на диск |
| Undo | Что не зафиксировали? | Стереть следы незавершённого |
В Oracle явно говорят про undo tablespace; в PostgreSQL многое завязано на MVCC и статусы транзакций в WAL — для экзамена и архитектуры пара redo/undo остаётся полезной моделью.
Durability — что именно обещает COMMIT
Буква D в ACID — долговечность: после успешного COMMIT результат переживёт сбой при принятых настройках СУБД.
Цепочка в PostgreSQL (упрощённо):
- Изменения записаны в WAL-буфер.
- При
COMMIT— сброс WAL на диск (wal_write,fsyncв зависимости отsynchronous_commit). - Клиент получает «OK».
- Страницы таблиц могут всё ещё быть только в RAM — это нормально.
Параметр synchronous_commit влияет на баланс скорость / надёжность:
| Значение (идея) | Поведение |
|---|---|
on (типично) | Commit ждёт устойчивой записи WAL |
off / локальные варианты | Быстрее, но при сбое питания последние commits могут «откатиться» |
Разработчик думает «commit = навсегда», DBA проверяет, какой уровень durability настроен на prod. Подробнее параметры — справочник PostgreSQL.
Три вида «восстановления» (не путать)
| Вид | Когда | Инструмент |
|---|---|---|
| Crash recovery | Перезапуск после падения процесса / питания | Автоматически, redo/undo из WAL |
| Media recovery | Повреждён или утерян файл данных / диск | Бэкап + WAL (PITR), восстановление кластера |
| Logical recovery | Удалили таблицу, нужна одна БД или старая версия схемы | pg_dump / pg_restore |
Эта глава — про первый вид. 106.md — про второй и третий.
Репликация и WAL (соседняя тема)
Физическая реплика в PostgreSQL стримит WAL на standby. Primary и standby разделяют одну историю изменений в журнале — поэтому понимание WAL нужно и для «аварийного» recovery, и для отставания реплики (replication lag).
Реплика не заменяет бэкап: при DROP DATABASE на primary ошибка часто повторится на replica. Нужны snapshot + периодический pg_dump и drill восстановления — администрирование.
Сценарий по шагам (упрощённо)
- Транзакция списала 100 ₽ — WAL записан,
COMMITв WAL есть. - Страница
accountsвсё ещё только в RAM. - Сбой — RAM пуста, на диске старая страница без списания.
- Старт PostgreSQL — redo проигрывает WAL → страница на диске с списанием.
- Другая транзакция без
COMMIT— undo / откат её эффектов.
Пользователь после рестарта видит согласованные данные; приложение может переподключиться.
Point-in-Time Recovery (PITR) — мост к администрированию
PITR — восстановление на момент времени между бэкапом и «сейчас», используя архив WAL + базовую копию. Это уже административное восстановление (удалили данные час назад — откатимся на 10:58), но опирается на тот же WAL, что и crash recovery.
Практика: Резервное копирование PostgreSQL, раздел про PITR в 3-08/2.
Что должен знать разработчик (не только DBA)
- Короткие транзакции — меньше окно «висящих» незавершённых изменений.
- Не глотать ошибки после
BEGIN— иначе соединение вернётся в пул с незавершённой транзакцией. - Идемпотентность при повторе запроса после сбоя сети — клиент мог на сервере commit уже в WAL.
- Понимать, что реплика и бэкап — дополнение, а не замена WAL на primary.
Повреждение данных и сбой процесса
Crash recovery предполагает, что файлы на диске целы, а RAM потеряна. Если повреждена страница на диске (битый сектор, ручная правка файла), движок может не подняться — нужны бэкап, реплика, иногда pg_checksums и восстановление из копии. Это снова аргумент в пользу правила 12 Кодда: не субвертировать файлы БД в обход СУБД.
Сколько длится recovery и от чего зависит
После аварии администратор видит в логе «database system was not properly shut down; automatic recovery in progress». Время зависит от:
- объёма WAL с момента последнего checkpoint;
- скорости диска (random I/O при redo);
- числа затронутых страниц.
Профилактика: регулярные checkpoint, мониторинг размера WAL, не копить гигантские незакоммиченные транзакции (раздувают undo/MVCC и окно recovery).
Контрольные вопросы
- Почему
COMMITне означает «все страницы таблицы уже записаны на диск»? - Чем redo отличается от undo при старте после сбоя?
- Зачем нужен checkpoint, если WAL всё равно есть?
- Чем crash recovery отличается от восстановления из
pg_dump? - Что настраивает
synchronous_commitи почему это важно для бизнеса? - Почему реплика не спасает от случайного
DROP TABLE?
См. также
- Теоретические основы реляционных данных — WAL и страницы
- Конкурентный доступ — durability и транзакции
- Резервное копирование PostgreSQL
- Управление реляционными СУБД — стратегии бэкапа и RPO/RTO
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). База данных и СУБД, схемы данных, реляционная и нереляционная модели — вводная глава с разбором терминов relation и relationship. ERD (Entity-Relationship Diagram) — это визуальное представление структуры базы данных. Диаграмма сущность-связь показывает сущности, их атрибуты и отношения между ними. Data governance - роли, правила и процессы, чтобы данные были учтены, защищены и использовались согласованно в организации. Совокупность программных и лингвистических средств, обеспечивающих управление созданием и использованием баз данных. База данных - это ящик с данными, который лежит в архиве - хранилище. СУБД как программный комплекс - хранение, извлечение и изменение данных с гарантиями целостности и безопасности в реляционной модели. Критерии «настоящей» реляционной СУБД по Эдгару Кодду — что означает каждое правило и насколько современный SQL им соответствует. Зачем компании централизуют данные, жизненный цикл модели от требований до эксплуатации, роли людей и человеческий фактор в среде БД. Параллельные транзакции — блокировки, MVCC, упорядочение по меткам времени и оптимистичный контроль; когда какой подход выбирать. Краткие итоги раздела «Основы баз данных». Чек-лист раздела Основы баз данных — вопросы для самопроверки в энциклопедии Вселенная IT.Знакомство с базами данных
Entity Relationship
Управление данными - Data Governance
Системы управления базами данных (СУБД)
Внутреннее устройство баз данных
Теоретические основы реляционных данных
Двенадцать правил Кодда
Роль базы данных в организации
Конкурентный доступ к данным
Итоги
Чек-лист самопроверки