Как настроить WAL в PostgreSQL при высокой записи
При высокой записи PostgreSQL может упереться не в скорость INSERT, а в поток WAL и частые контрольные точки. Разбираем PostgreSQL 16: что измерить, какие настройки менять и как не купить производительность ценой потери подтверждённых данных.

Когда PostgreSQL принимает много записей, WAL может стать узким местом: растут задержки фиксации транзакций, накопитель постоянно пишет, а контрольные точки запускаются чаще ожидаемого. В PostgreSQL 16 настройка WAL — это не поиск одного волшебного параметра, а измерение потока записи и проверка, что именно ограничивает систему: генерация журнала, синхронизация диска или контрольные точки.
Сначала отделите проблему WAL от общей нехватки диска
WAL (write-ahead log) — журнал, куда PostgreSQL записывает изменения раньше, чем соответствующие страницы таблиц и индексов попадут в основные файлы данных. При сбое журнал помогает восстановить согласованное состояние. Поэтому высокая активность WAL сама по себе не ошибка: важно, успевает ли хранилище записывать журнал и не создаёт ли система контрольные точки слишком часто.
Дальше речь о PostgreSQL 16. Снимайте показатели в период обычной нагрузки и в пике, а не сразу после перезапуска: статистика накапливается, и одно значение без временного интервала мало что говорит. Если доступно, сравните два снимка с известным интервалом между ними.
SELECT wal_records, wal_fpi, wal_bytes, wal_buffers_full,
wal_write, wal_sync, wal_write_time, wal_sync_time
FROM pg_stat_wal;
Смотрите на разницу wal_bytes между снимками: так вы получите объём сгенерированного WAL за интервал. wal_fpi считает полностраничные образы — копии страниц, которые журнал может записывать после контрольной точки при первом изменении страницы. Время записи и синхронизации учитывается, если включён track_wal_io_timing; перед включением проверьте накладные расходы на своей системе.
Затем проверьте статистику контрольных точек и фоновой записи:
SELECT checkpoints_timed, checkpoints_req,
checkpoint_write_time, checkpoint_sync_time,
buffers_checkpoint, buffers_backend, buffers_backend_fsync
FROM pg_stat_bgwriter;
Сравнивайте не абсолютные счётчики, а их прирост за тот же интервал. Большой прирост checkpoints_req может означать, что контрольные точки чаще вызываются из-за исчерпания доступного объёма WAL, а не по таймеру. Высокое время синхронизации — повод проверить задержки хранилища и настройки файловой системы, а не просто увеличить лимит журнала.
Что меняют параметры WAL
| Параметр | Что регулирует | Цена изменения |
|---|---|---|
max_wal_size | Ориентир, после которого рост WAL может чаще запускать контрольную точку | Больший лимит допускает больше места под WAL и не гарантирует жёсткого потолка использования диска |
checkpoint_timeout | Максимальный интервал между контрольными точками по времени | Более редкие контрольные точки могут увеличить объём работы при восстановлении после сбоя |
checkpoint_completion_target | Распределяет запись страниц в течение интервала контрольной точки | Сглаживает пиковую нагрузку, но не устраняет нехватку пропускной способности диска |
wal_compression | Сжимает полностраничные образы в WAL | Может уменьшить объём записи, но расходует процессорное время |
synchronous_commit | Определяет, ждёт ли транзакция подтверждения записи WAL на устойчивое хранилище | Асинхронное подтверждение снижает ожидание, но при сбое может потеряться недавно подтверждённая транзакция |
Полностраничный образ (full-page image, FPI) — снимок изменяемой страницы, который помогает восстановить её после частичной записи при сбое. Параметр full_page_writes защищает от такого сценария; отключать его ради уменьшения WAL без отдельной оценки риска нельзя.
Настраивайте по одному ограничению
Если контрольные точки запускаются слишком часто
Проверьте прирост checkpoints_req, скорость генерации WAL и доступное место на диске. Если контрольные точки явно срабатывают из-за объёма журнала, увеличьте max_wal_size небольшим шагом и наблюдайте за частотой контрольных точек, задержками и заполнением диска. Это не универсальное лечение: размер, который подходит для одной скорости записи, на другом сервере лишь отложит момент нехватки места.
max_wal_size — не жёсткий предел. Фактическое использование может превышать его, например из-за нагрузки или удержания WAL репликационным слотом. Перед изменением оцените свободное место и проверьте, нет ли отстающих реплик и слотов, которые удерживают старые сегменты.
Если записи WAL создают резкие пики
Посмотрите на checkpoint_write_time и задержки диска. Повышение checkpoint_completion_target растягивает запись страниц контрольной точки; в PostgreSQL 16 значение по умолчанию — 0.9. Если диск и так загружен непрерывной записью, растягивание может не помочь: измеряйте задержки вместе с пропускной способностью, а не только общий объём операций.
Увеличивать checkpoint_timeout стоит только после оценки объёма восстановления и поведения при аварийном перезапуске. Реже запускаемые контрольные точки могут снизить их частоту, но не отменяют запись WAL и не гарантируют ускорения транзакций.
Если WAL слишком велик из-за образов страниц
Сопоставьте прирост wal_fpi и wal_bytes. Если доля полностраничных образов заметна, проверьте wal_compression. В PostgreSQL 16 доступны варианты сжатия, если соответствующая поддержка собрана в системе; конкретный доступный метод зависит от сборки. Сжатие может снизить поток записи, но увеличит нагрузку на CPU — сравнивайте показатели на одинаковом профиле запросов.
Не выключайте full_page_writes как способ «починить» большой WAL. Сначала выясните, что создаёт образы и как часто происходят контрольные точки. Инвалидация кешей, устройство репликации и настройка архивации — отдельные темы.
Самый спорный рычаг — подтверждение транзакции
При synchronous_commit = on PostgreSQL ждёт подтверждения устойчивой записи WAL перед тем, как считать транзакцию успешно зафиксированной. При асинхронном подтверждении приложение может получить успех раньше, чем WAL гарантированно попадёт на устойчивое хранилище. После сбоя последние подтверждённые транзакции могут потеряться, хотя база останется согласованной.
Это не настройка для включения вслепую на всём кластере. Если потеря небольшой части последних операций допустима, оцените асинхронный режим для конкретных транзакций или сессий и согласуйте поведение с владельцами данных. Не применяйте его к платежам, учёту или другим операциям, где подтверждение должно означать надёжное сохранение.
Увеличение лимита WAL покупает время до следующей контрольной точки. Оно не создаёт более быстрый диск и не делает безопасным подтверждение транзакции до надёжной записи.
Что может сломаться
- Диск заполнится раньше, чем сработает тревога. Увеличенный
max_wal_sizeне ограничивает максимальный расход места. Следите за свободным объёмом и ростом каталога WAL. - WAL удерживает слот репликации. Если потребитель отстаёт, журнал может накапливаться. Проверьте состояние реплик и слотов до того, как увеличивать доступный объём.
- Снижение задержки обернётся потерей последних операций. Это риск асинхронного
synchronous_commit, а не бесплатная оптимизация. - Сжатие перенесёт узкое место на процессор. Измерьте CPU и задержки запросов после включения, особенно если сервер уже близок к насыщению.
- Один удачный тест не повторится в проде. Скорость записи зависит от схемы, индексов, размера транзакций, оборудования и параллельности. Сравнивайте одинаковые интервалы и одинаковый профиль нагрузки.
Что делать дальше
Сохраните исходные показатели, меняйте только один параметр за раз и фиксируйте условия теста: версию PostgreSQL, тип накопителя, объём данных, число параллельных записывающих клиентов и длительность нагрузки. После каждого изменения сравнивайте скорость генерации WAL, прирост контрольных точек, задержку фиксации транзакций и свободное место. В проде настройте предупреждения на рост WAL и отставание реплик; только после этого переходите к следующему изменению.
Аналитик звонков: Разбор записи звонка по этапам сделки: где сорвалось, что упущено, три исправляемые рекомендации с цитатами.
Спросить за 90 ₽Источники: PostgreSQL 16: WAL Configuration, PostgreSQL 16: Monitoring Database Activity
Частые вопросы
С чего начать, если запись в PostgreSQL замедлилась?
Можно ли просто увеличить max_wal_size?
Опасно ли отключать full_page_writes?
Можно ли использовать synchronous_commit = off для всех транзакций?
Почему WAL занимает больше места, чем max_wal_size?
Нужно ли менять wal_buffers при высокой записи?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.