Настройка WAL в PostgreSQL: как измерять эффект в цифрах
Частые контрольные точки в PostgreSQL могут замедлять запись, но просто увеличить лимит WAL — не универсальное решение. Разбираем настройки PostgreSQL 16, метрики для диагностики и цену изменений: место на диске, нагрузку и время восстановления.

В PostgreSQL 16 частые контрольные точки могут добавить запись на диск и вызвать скачки задержек, но увеличение max_wal_size не гарантирует ускорения: при этом растут объём WAL и потенциальное время восстановления. Ниже — как измерить скорость генерации журнала, понять, что ограничивает систему, и менять параметры без гадания на конфигурации.
Сначала выясните, что именно замедляет запись
WAL — журнал предварительной записи: PostgreSQL фиксирует изменения в журнале раньше, чем соответствующие страницы данных попадают в основные файлы. Это помогает восстановить согласованное состояние после сбоя. Контрольная точка синхронизирует накопленные изменения с файлами данных и отмечает позицию, от которой понадобится восстановление.
Настройка WAL — не один ползунок «скорость». Если диск уже упёрся в предел записи, более редкие контрольные точки могут сгладить пики, но не создадут пропускную способность. Если WAL удерживает слот репликации или архиватор, поднятый max_wal_size сам по себе не освободит место.
Для воспроизводимых выводов ниже используются параметры и представления PostgreSQL 16. В других версиях состав статистики может отличаться: перед запуском запросов сверьтесь с документацией именно вашей версии.
Снимите исходные показатели
Сначала проверьте активные значения и контекст применения параметров:
SELECT name, setting, unit, context, pending_restart
FROM pg_settings
WHERE name IN (
'max_wal_size',
'min_wal_size',
'checkpoint_timeout',
'checkpoint_completion_target',
'wal_buffers',
'wal_compression',
'track_wal_io_timing'
)
ORDER BY name;
Затем зафиксируйте статистику WAL и контрольных точек. Сохраните результат, подождите известный интервал под обычной нагрузкой и выполните запросы повторно. Именно разность между снимками, а не сумма с момента запуска сервера, нужна для оценки эффекта.
SELECT wal_records, wal_fpi, wal_bytes, wal_buffers_full,
wal_write, wal_sync, wal_write_time, wal_sync_time,
stats_reset
FROM pg_stat_wal;
SELECT checkpoints_timed, checkpoints_req,
checkpoint_write_time, checkpoint_sync_time,
buffers_checkpoint, stats_reset
FROM pg_stat_bgwriter;
В PostgreSQL 16 время записи WAL в pg_stat_wal учитывается, когда включён track_wal_io_timing. Включение измерения само по себе может иметь накладные расходы; проверяйте их на вашей системе, а не включайте вслепую на всех узлах.
- Посчитайте прирост wal_bytes за интервал и разделите на секунды. Это скорость генерации WAL, а не скорость диска.
- Сравните прирост checkpoints_req с checkpoints_timed. Частые запросы контрольных точек могут указывать, что лимит WAL достигается раньше таймера.
- Смотрите на checkpoint_write_time и checkpoint_sync_time вместе с задержками приложения и нагрузкой на диск. Рост счётчика без ухудшения задержек не доказывает проблему.
- Проверьте свободное место в pg_wal и состояние архивирования и репликации. Удерживаемый WAL может расти независимо от того, насколько редко проходят контрольные точки.
Счётчики накопительные. Если между снимками перезапустили сервер или сбросили статистику, сравнение недействительно: проверьте stats_reset.
Какие параметры менять и чем за это платить
| Параметр | Что меняет | Цена и ограничение |
|---|---|---|
| max_wal_size | Ориентир, после которого PostgreSQL может запросить контрольную точку из-за объёма WAL | Это не жёсткий потолок. Большое значение может увеличить объём WAL на диске и время восстановления |
| checkpoint_timeout | Максимальный интервал между автоматическими контрольными точками по времени | Длинный интервал не отменяет контрольную точку по объёму WAL и может удлинить восстановление после сбоя |
| checkpoint_completion_target | Распределяет запись страниц контрольной точки по её интервалу | Сглаживает нагрузку, но не уменьшает суммарный объём работы |
| wal_compression | Сжимает полностраничные образы в WAL | Может уменьшить запись и объём журнала ценой процессорного времени; доступные варианты зависят от сборки |
В PostgreSQL 16 базовое значение checkpoint_completion_target — 0,9. Обычно его не стоит снижать ради «быстрого завершения» контрольной точки: это может сосредоточить запись в более коротком окне. Значение max_wal_size выбирайте по наблюдаемой генерации WAL, доступному месту и приемлемому времени восстановления, а не по размеру базы данных в вакууме.
Настройка WAL обменивает пики записи на диске на больший запас журнала и потенциально более долгий recovery. Считать нужно обе стороны этого обмена.
Как прикинуть лимит WAL по нагрузке
Допустим, на конкретном сервере за десять минут под типичной нагрузкой wal_bytes вырос на 12 ГБ. Это условный пример, не бенчмарк и не рекомендация для любого проекта. Средняя генерация составляет примерно 20 МБ/с. Если рассматривать интервал в 15 минут, за это время при той же скорости накопится около 18 ГБ WAL.
Эти 18 ГБ — оценка объёма, а не готовое значение max_wal_size. Нагрузка меняется, контрольную точку может вызвать и временной лимит, а репликация или архивирование могут задержать повторное использование файлов. Сопоставьте расчёт с пиками генерации, запасом диска и временем восстановления на тестовом стенде. Для оценки recovery измеряйте длительность запуска после остановки с объёмом WAL, характерным для выбранных настроек.
В PostgreSQL 16 при max_wal_size нет гарантии, что pg_wal никогда не превысит указанную величину: параметр задаёт мягкий ориентир. Поэтому свободное место мониторят отдельно, особенно если есть архивирование WAL или слоты репликации.
Меняйте по одному фактору
- Зафиксируйте базу. Снимите настройки и статистику на обычном интервале нагрузки. Запишите также задержки записи, дисковую загрузку и свободное место. Проверка: вы можете повторить тот же интервал после изменения.
- Проверьте причину частых контрольных точек. Сопоставьте прирост checkpoints_req и checkpoints_timed. Если преобладают запросы, связанные с объёмом WAL, проверьте скорость его генерации и текущее ограничение. Проверка: понятно, какой сигнал вы собираетесь изменить.
- Измените один подходящий параметр. Например, увеличение max_wal_size тестируйте только при наличии дискового запаса. Не снижайте full_page_writes и fsync ради красивых цифр: это затрагивает защиту данных. Проверка: новое значение видно в pg_settings, а pending_restart не указывает на необходимость перезапуска.
- Повторите замер в сопоставимых условиях. Используйте тот же тип нагрузки и интервал, сравните скорости WAL, контрольные точки, задержки и остаток диска. Проверка: эффект виден в нескольких метриках, а не только в одном счётчике.
- Проверьте восстановление и репликацию. Убедитесь, что архиватор успевает, реплики не отстают сверх допустимого, а восстановление укладывается в требование сервиса. Проверка: запас WAL и время recovery приемлемы для эксплуатации.
Где настройка ломается
Большой лимит маскирует проблему диска
Редкие контрольные точки не устраняют нехватку IOPS или пропускной способности. Если задержки записи остаются высокими, измерьте диск, WAL-синхронизацию и нагрузку приложения. Увеличение max_wal_size в этом случае может лишь отодвинуть пик и увеличить объём журнала.
WAL растёт, хотя контрольных точек мало
Проверьте архивирование и слоты репликации: отстающий потребитель может удерживать старые сегменты. Удалять их вручную из pg_wal нельзя — можно повредить возможность восстановления или работу реплики. Сначала найдите удерживающую причину и устраните её штатно.
Сжатие переносит нагрузку на процессор
wal_compression стоит проверять на нагрузке, где важен объём полностраничных образов. Сравните прирост wal_bytes, загрузку CPU и задержки транзакций. Если процессор уже перегружен, экономия дисковой записи может оказаться невыгодной.
Отключение ожидания синхронной записи — отдельный риск
Параметр synchronous_commit влияет на то, когда клиент получает подтверждение транзакции, и не заменяет настройку контрольных точек. При отключении ожидания подтверждённые клиенту последние транзакции могут потеряться при аварии сервера. Это осознанный компромисс для конкретных операций, а не безопасная общая оптимизация WAL.
Термин: полностраничный образ, или FPI, — запись полной изменённой страницы в WAL после контрольной точки; она помогает защититься от частичной записи страницы при сбое. Счётчик wal_fpi показывает число таких записей, но сам по себе не говорит, насколько они дороги именно вашему диску.
Что измерить дальше
Сначала соберите базовые снимки pg_stat_wal и pg_stat_bgwriter на репрезентативной нагрузке. Затем меняйте один параметр и наблюдайте за четырьмя вещами: приростом WAL, частотой контрольных точек, задержками записи и запасом места. Если вы увеличили интервал или лимит, отдельно проверьте время восстановления и поведение реплик: это цена оптимизации, которую обычный тест записи не показывает.
Универсальный ассистент: Обычный чат: тексты, идеи, разбор, перевод, расчёты.
Спросить за 8 ₽Источники: PostgreSQL 16: WAL Configuration, PostgreSQL 16: WAL Settings
Частые вопросы
Какое значение max_wal_size поставить для PostgreSQL 16?
Почему размер pg_wal превышает max_wal_size?
Можно ли увеличить max_wal_size без перезапуска?
Опасно ли отключить synchronous_commit ради скорости?
Что делать, если у меня другая версия PostgreSQL?
Как понять, что настройка помогла в проде?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.