# Full-page images и CRC _Буферный кеш и WAL · PostgreSQL Knowledge Base_ **TL;DR:** При первом изменении страницы после контрольной точки PostgreSQL пишет в журнал не дельту, а всю страницу целиком (FPI) - чтобы при восстановлении починить «рваную» страницу после сбоя. Каждая WAL-запись защищена CRC; битая запись считается концом журнала. ## Проблема рваной записи Страница PostgreSQL - 8 КБ, а диск или ОС пишут блоками поменьше (например, 4 КБ). Если сбой случится прямо во время записи 8-КБ страницы, на диск попадёт её половина: часть новая, часть старая. Это рваная запись (torn page). Обычная WAL-запись («измени байт X на Y») такую страницу не починит - она опирается на то, что страница целая. ## Решение: full-page image При первом изменении страницы после каждой контрольной точки PostgreSQL пишет в журнал полную копию страницы (FPI), а не дельту. При восстановлении эта копия кладётся поверх возможно рваной страницы целиком, и дальше применяются обычные мелкие записи. За это отвечает параметр `full_page_writes` (по умолчанию `on`). ## Следствие: всплеск WAL после контрольной точки Сразу после контрольной точки первые изменения каждой страницы тащат за собой полную копию - объём журнала подскакивает. Это видно в `pg_stat_wal`: ```sql SELECT wal_fpi, wal_bytes FROM pg_stat_wal; ``` `wal_fpi` - число full-page images; его рост коррелирует с частотой контрольных точек (см. [checkpoint](/courses/postgres/kb/checkpoint.md)). Слишком частые контрольные точки раздувают WAL именно через FPI. ## CRC: граница целого журнала Каждая WAL-запись несёт контрольную сумму (CRC). При восстановлении CRC проверяется перед применением записи. Битая или оборванная на полузаписи запись означает: журнал здесь и кончился. Всё до этой точки целостно и применяется, всё после отбрасывается - так восстановление никогда не применит полузапись. ## Когда отключают (почти никогда) `full_page_writes = off` уменьшает WAL, но при рваной записи оставляет повреждённую страницу без шансов на восстановление. Отключают только на хранилищах, гарантирующих атомарную запись страницы целиком, и только зная это точно. Сам принцип журнала - в [wal](/courses/postgres/kb/wal.md). ## Команды ```sql SELECT wal_fpi FROM pg_stat_wal; ``` Число full-page images — всплеск виден после контрольной точки ```sql SHOW full_page_writes; ``` Включена ли защита от рваной записи (должна быть on) ## См. также - [WAL: принцип write-ahead и LSN](/courses/postgres/kb/wal.md) - [Контрольные точки и восстановление](/courses/postgres/kb/checkpoint.md) - [Уровни журнала: minimal, replica, logical](/courses/postgres/kb/wal-level.md)