# Контрольные точки и восстановление _Буферный кеш и WAL · PostgreSQL Knowledge Base_ **TL;DR:** Контрольная точка сбрасывает все грязные буферы на диск и фиксирует redo point - позицию журнала, с которой начнётся восстановление. Crash recovery проигрывает WAL от redo point вперёд; незакоммиченные транзакции откатываются через clog. Запускается по checkpoint_timeout / max_wal_size. ## Зачем нужна Журнал растёт бесконечно, а без границы восстановление пришлось бы начинать с начала времён. Контрольная точка сбрасывает на диск все грязные буферы, накопленные к моменту, и записывает в `pg_control` redo point - позицию журнала, до которой все изменения уже в файлах данных. Дальше этой точки откатываться при восстановлении не нужно. ## Redo point - на начало, не на конец Сброс буферов не мгновенен (минуты), и база тем временем пишет новый журнал. Поэтому redo point берётся на **момент начала** контрольной точки: всё, что было грязным к её началу, она гарантированно запишет, и восстановление с этой позиции увидит в журнале всё ещё не попавшее на диск. ## Crash recovery При старте после некорректной остановки PostgreSQL: 1. читает redo point из `pg_control`; 2. проигрывает WAL от redo point вперёд, применяя записи к страницам; 3. full-page images чинят рваные страницы (см. [full-page-images](/courses/postgres/kb/full-page-images.md)); 4. доходит до обрыва CRC - конец журнала; 5. незакоммиченные транзакции невидимы через clog (фактически откачены). Redo накатывает и незакоммиченные изменения физически, но их статус в clog не «committed», поэтому MVCC их не показывает. ## Когда запускается - по таймеру `checkpoint_timeout` (5 мин по умолчанию); - по объёму журнала `max_wal_size` (1 ГБ); - вручную `CHECKPOINT` или перед остановкой сервера. `checkpoint_completion_target` (0.9) размазывает запись грязных буферов во времени, сглаживая всплеск нагрузки на диск. ## Наблюдать (PG17) ```sql SELECT num_timed, num_requested, buffers_written FROM pg_stat_checkpointer; ``` Здоровый признак - `num_timed` заметно больше `num_requested`. Перекос в сторону `num_requested` означает переполнение журнала по `max_wal_size` - сигнал поднять его. Сам журнал - в [wal](/courses/postgres/kb/wal.md). ## Команды ```sql CHECKPOINT; ``` Принудительная контрольная точка (тороплива — даёт всплеск записи) ```sql SELECT num_timed, num_requested FROM pg_stat_checkpointer; ``` Контрольные точки по таймеру против по объёму журнала (PG17) ```sql SHOW max_wal_size; ``` Порог журнала, при котором инициируется контрольная точка ## См. также - [WAL: принцип write-ahead и LSN](/courses/postgres/kb/wal.md) - [Full-page images и CRC](/courses/postgres/kb/full-page-images.md) - [Уровни журнала: minimal, replica, logical](/courses/postgres/kb/wal-level.md)