# WAL: принцип write-ahead и LSN _Буферный кеш и WAL · PostgreSQL Knowledge Base_ **TL;DR:** WAL - последовательный журнал изменений. Правило write-ahead: запись об изменении попадает на диск раньше самой страницы данных, поэтому сбой не теряет подтверждённые данные. LSN - смещение в потоке журнала. COMMIT при synchronous_commit=on ждёт сброса журнала на диск. ## Правило write-ahead Любое изменение делается в два приёма: сначала запись об изменении дописывается в журнал и попадает на диск, и только потом (позже) изменённая страница данных. Журнал опережает данные - отсюда «запись с опережением». Это спасает при сбое: если упали после журнальной записи, но до записи страницы - изменение доиграют из журнала; если до журнальной записи - транзакция не подтверждена, терять нечего. ## Почему дёшево Журнал пишется последовательно, дозаписью в конец одного потока. Последовательная запись на порядки быстрее случайной записи разбросанных по диску страниц. WAL превращает множество мелких случайных записей в одну последовательную, а запись страниц данных откладывает (bgwriter, контрольная точка - см. [checkpoint](/courses/postgres/kb/checkpoint.md)). ## LSN LSN (Log Sequence Number) - смещение в байтах в потоке WAL, тип `pg_lsn`, печатается как `16/B374D848`. Каждая страница помнит LSN последнего отражённого в ней изменения (`pd_lsn`); страницу нельзя записать на диск, пока журнал не сброшен до её `pd_lsn`. Разница двух LSN - объём журнала в байтах. ```sql SELECT pg_current_wal_lsn(); SELECT pg_current_wal_lsn() - '0/0'; -- сколько байт WAL сгенерировано ``` ## Durability и synchronous_commit COMMIT дописывает запись о коммите и ждёт сброса журнала на диск (fsync) до неё - это буква D в ACID. `synchronous_commit = on` (по умолчанию) включает это ожидание; `off` ускоряет коммит ценой потери хвоста подтверждённых транзакций при сбое (данные остаются согласованными). ## Что пишут и где Журнал живёт в сегментах `pg_wal/` (16 МБ). Пишут бэкенды и walwriter. Темп виден в `pg_stat_wal`. Защита от рваной записи - [full-page-images](/courses/postgres/kb/full-page-images.md); уровень детализации - [wal-level](/courses/postgres/kb/wal-level.md). ## Команды ```sql SELECT pg_current_wal_lsn(); ``` Текущая позиция записи в журнал ```sql SELECT wal_records, wal_bytes, wal_fpi FROM pg_stat_wal; ``` Темп и состав генерации WAL ```sql SHOW synchronous_commit; ``` Ждёт ли COMMIT сброса журнала на диск ## См. также - [Full-page images и CRC](/courses/postgres/kb/full-page-images.md) - [Контрольные точки и восстановление](/courses/postgres/kb/checkpoint.md) - [Уровни журнала: minimal, replica, logical](/courses/postgres/kb/wal-level.md)