Акция Панель управления ispmanager для VDS — первый месяц бесплатно
до 31.07.2026 Подробнее
Выберите продукт

PostgreSQL streaming replication: wal_keep_size, replication slots и защита от WAL disk full

Практическое руководство по streaming replication в PostgreSQL: как wal_keep_size и replication slots удерживают WAL, зачем ограничивать их через max_slot_wal_keep_size, какие запросы покажут lag и удержание, и что делать при риске WAL disk full.
PostgreSQL streaming replication: wal_keep_size, replication slots и защита от WAL disk full

Streaming replication в PostgreSQL кажется простой: подняли standby, включили репликацию, и оно «как-то» работает. Проблемы обычно приходят позже — когда реплика отстаёт, сеть моргнула, бэкап-сервер завис, или кто-то забыл, что WAL нельзя хранить бесконечно. Итог бывает двух типов: либо standby перестаёт догонять и требует пересоздания, либо primary уходит в WAL disk full и начинает ошибиться на записи из‑за переполнения диска.

Ниже разложу по полочкам две ключевые техники удержания WAL для реплик: параметр wal_keep_size и replication slots. Покажу, как выставлять лимиты (max_slot_wal_keep_size), как читать pg_stat_replication и pg_replication_slots, и что делать, если место уже заканчивается.

Почему «пропадают» WAL и что значит WAL disk full

WAL (Write-Ahead Log) — это сегменты журнала, которые primary генерирует при любых изменениях данных. Реплика в streaming replication подтягивает эти записи и применяет у себя. Но PostgreSQL не хранит WAL вечно: он удаляет старые сегменты, когда считает их больше не нужными (для восстановления после сбоя и для всех потребителей WAL).

Если standby долго не забирает WAL (лаг, сеть, реплика выключена), у primary возникает дилемма:

  • либо удалить старый WAL и «сломать» реплику (ей больше неоткуда догонять);
  • либо удерживать WAL дольше — и рискнуть переполнить диск.

WAL disk full — это ситуация, когда каталог pg_wal разрастается так, что заполняет файловую систему. После этого база начинает получать ошибки записи, растёт риск сбоев фоновых процессов, а под нагрузкой инцидент развивается быстро: любые операции, генерирующие WAL, упираются в ENOSPC.

Если вы включаете механизм, который заставляет PostgreSQL удерживать WAL (slots или большой wal_keep_size), мониторинг роста pg_wal и отставания реплик обязателен. Иначе проблема «реплика отстала» превратится в «primary лёг».

wal_keep_size: простой буфер для кратковременного отставания

wal_keep_size — это «подушка безопасности»: PostgreSQL старается держать минимум указанного объёма WAL-сегментов, даже если они уже не нужны для crash recovery. Это помогает коротким отставаниям реплики, когда она вскоре догонит.

Что важно понимать про wal_keep_size

  • Это не гарантия «хватит на N часов». Это объём (МБ/ГБ), а скорость генерации WAL зависит от нагрузки.
  • Это минимальный объём удержания, но фактический объём WAL может быть больше из‑за других факторов (архивация, чекпоинты, слоты).
  • wal_keep_size не привязан к конкретной реплике: это общий параметр инстанса.

Типовой подход: выбрать значение, которое покрывает ожидаемое кратковременное окно «реплика отвалилась/перезапускается/есть сетевые потери» при пиковом профиле записи.

Как прикинуть значение на практике

В идеале вы знаете среднюю и пиковую скорость генерации WAL (метрики, статистика). В «полевых» условиях достаточно прикинуть: сколько времени реплика может быть недоступна без инцидента и сколько WAL вы генерируете в самые тяжёлые 10–15 минут. Подушка должна пережить именно пик, а не среднее.

Если база живёт на VPS/VDS, имеет смысл сразу закладывать диск под «плохой день» (пики записи плюс удержание WAL плюс место под VACUUM и временные файлы). Под это обычно удобнее VDS, где проще управлять диском, IOPS и мониторингом.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Replication slots: гарантия, что WAL не удалится «раньше времени»

Replication slots решают другую задачу: это механизм, который говорит primary «не удаляй WAL, пока конкретный потребитель не подтвердит, что забрал нужные позиции». Для streaming replication используются physical slots.

Плюс слотов: реплика не «сломается» из‑за того, что primary успел удалить WAL. Минус: если реплика зависла или выключена, слот продолжит удерживать WAL — и вы легко получите WAL disk full, если не поставили ограничения.

Когда слоты нужны, а когда опасны

  • Нужны, если реплика должна переживать краткосрочные/среднесрочные отказы связи без пересоздания из бэкапа.
  • Опасны, если реплика «периодическая» (включают раз в неделю) или если нет мониторинга: слот будет удерживать WAL весь период простоя.

Если у вас репликация строится вокруг резервного копирования и восстановления «по расписанию», отдельно проверьте, что у вас выстроен корректный цикл бэкап → восстановление. По теме PITR и WAL-архивации пригодится материал: PITR в PostgreSQL: WAL-архивация и восстановление до точки во времени.

Схема удержания WAL: wal_keep_size и replication slot, показывающая риск удаления или переполнения

Критически важный предохранитель: max_slot_wal_keep_size

max_slot_wal_keep_size — ремень безопасности против бесконечного роста WAL из-за слотов. Он ограничивает, сколько WAL может быть удержано для слота. При превышении лимита PostgreSQL перестаёт гарантировать, что реплика «догонит» без вмешательства: реплику придётся пересинхронизировать или переинициализировать.

На практике это компромисс:

  • без лимита — рискуете положить primary переполнением диска;
  • со слишком маленьким лимитом — рискуете получить «сломавшуюся» реплику при длительном простое.

Рабочая рекомендация: выставляйте max_slot_wal_keep_size так, чтобы он покрывал реально допустимое окно недоступности реплики (с запасом на пик WAL), но не превышал объём, который вы готовы держать на том же файловом разделе, что и pg_wal.

Диагностика: что смотреть в pg_stat_replication

pg_stat_replication показывает активные подключения реплик к primary и их состояние. Это самый быстрый способ понять: «реплика живая или нет» и насколько она отстаёт.

Быстрая проверка:

psql -X -c "SELECT pid, application_name, client_addr, state, sync_state, write_lag, flush_lag, replay_lag FROM pg_stat_replication ORDER BY application_name;"

Как читать результат:

  • state: если не streaming, уже повод разбираться.
  • sync_state: async/sync/quorum — напрямую влияет на то, ждёт ли коммит реплику.
  • write_lag, flush_lag, replay_lag: удобные подсказки, но иногда бывают NULL или «скачут»; для точной картины смотрите LSN.

Для LSN-диагностики:

psql -X -c "SELECT application_name, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication ORDER BY application_name;"

Диагностика слотов: pg_replication_slots и «кто удерживает WAL»

Когда растёт pg_wal, ключевой вопрос: что именно удерживает WAL. Для слотов ответ даёт pg_replication_slots.

psql -X -c "SELECT slot_name, slot_type, active, restart_lsn, confirmed_flush_lsn, wal_status FROM pg_replication_slots ORDER BY slot_name;"

Ориентиры:

  • active=false у physical slot — тревожный сигнал: реплика не подключена, но WAL удерживается.
  • restart_lsn показывает, начиная с какой позиции WAL ещё нужен слоту.
  • wal_status (если доступен в вашей версии) помогает понять, не упёрлись ли вы в лимиты удержания.

Чтобы оценить объём WAL, удерживаемый каждым слотом:

psql -X -c "SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained, active FROM pg_replication_slots ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC;"

Это один из самых прикладных запросов при расследовании WAL disk full: сразу видно, какой слот удерживает больше всего.

Пример диагностики репликации PostgreSQL: состояние реплик и объём WAL, удерживаемый слотами

Типовые сценарии аварий и что делать

Сценарий 1: реплика выключена, слот удерживает WAL, диск заканчивается

Симптомы: быстро растёт pg_wal, в pg_replication_slots слот active=false, а удерживаемый объём — десятки или сотни гигабайт.

План действий (в порядке минимизации риска для primary):

  1. Оцените свободное место и темп роста WAL (важен не только «сколько осталось», но и «на сколько минут хватит»).
  2. Если реплику реально быстро вернуть в строй — поднимайте её: восстановите сеть, проверьте доступ replication-пользователя, убедитесь, что standby стартует и подключается.
  3. Если реплику быстро поднять нельзя — примите решение, что важнее прямо сейчас: спасать primary или сохранять возможность догнать реплику без пересоздания.
  4. Если нужно срочно освобождать место — обычно приходится удалить слот. Это управляемая потеря: реплика, скорее всего, потребует пересоздания.

Удаление слота — это не «починка», а осознанное действие: вы прекращаете удержание WAL ради живучести primary. Зафиксируйте решение и причину в инциденте.

Удаление слота на primary:

psql -X -c "SELECT pg_drop_replication_slot('standby1');"

Сценарий 2: слотов нет, но pg_wal всё равно раздувается

Если слотов нет, рост pg_wal чаще связан с чекпоинтами, архивацией (если включена), либо с тем, что реплика постоянно «на грани» и держится только за счёт wal_keep_size. Проверьте:

  • не включено ли архивирование, которое не успевает (например, архивная команда падает или упирается в место);
  • настройки чекпоинтов и общую «WAL-экономику» (это отдельная тема);
  • фактическое отставание реплики и стабильность канала (потери пакетов, MTU, QoS).

Сценарий 3: сработал max_slot_wal_keep_size, реплика больше не догоняет

Это «правильная» авария: лучше потерять реплику, чем primary. Тактика обычно такая:

  • пересоздать реплику из свежего basebackup или бэкапа;
  • переоценить лимит max_slot_wal_keep_size и причины простоя реплики;
  • настроить мониторинг, чтобы узнавать о проблеме до момента срабатывания лимита.

Если вы используете pgBackRest, имеет смысл держать понятный регламент восстановления и регулярные тесты восстановления на отдельной машине. См. практический разбор: pgBackRest: бэкапы и восстановление PostgreSQL.

Для публичных сервисов и админок не забывайте про TLS: корректный сертификат упрощает жизнь и пользователям, и автоматизации. По теме — SSL-сертификаты для продакшена.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Практический чек-лист настроек для production

Ниже — набор практик, которые обычно предотвращают и «битые реплики», и WAL disk full.

  • Определитесь, нужны ли слоты. Для постоянно включённых реплик — да, почти всегда. Для «редко включаемых» — чаще нет.
  • Ставьте max_slot_wal_keep_size. Без него любая поломка реплики может превратиться в поломку primary.
  • Держите умеренный wal_keep_size. Он полезен даже со слотами как небольшой буфер на краткие сбои.
  • Мониторьте: размер pg_wal, удержание WAL по слотам, появление active=false у слотов, lag репликации (LSN и/или время).
  • Пропишите план инцидента заранее: кто принимает решение «дропаем слот», как пересоздаёте реплику, где лежит актуальный бэкап.

Мини-набор команд для дежурного: быстро понять ситуацию

Когда места на диске осталось мало, времени на долгое расследование нет. Сохраните себе минимальный набор запросов.

1) Кто подключен и в каком состоянии

psql -X -c "SELECT application_name, client_addr, state, sync_state FROM pg_stat_replication ORDER BY application_name;"

2) Какие слоты есть и активны ли они

psql -X -c "SELECT slot_name, slot_type, active, restart_lsn FROM pg_replication_slots ORDER BY slot_name;"

3) Кто удерживает больше всего WAL

psql -X -c "SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained, active FROM pg_replication_slots ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC;"

Вывод: как не наступать на WAL disk full

Если упростить до одной фразы: wal_keep_size — это мягкая подушка, а replication slots — жёсткая гарантия. И именно жёсткая гарантия чаще всего приводит к переполнению диска, если её не ограничить.

Устойчивый вариант для продакшена обычно такой: используете physical slots для постоянных реплик, обязательно ограничиваете удержание через max_slot_wal_keep_size, держите умеренный wal_keep_size на случай коротких сбоев, и регулярно смотрите pg_stat_replication вместе с pg_replication_slots. Тогда даже при поломке реплики вы получите управляемый инцидент (пересоздать standby), а не катастрофу на primary из‑за раздувшегося pg_wal.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину

Ошибка mount: wrong fs type, bad option, bad superblock в Debian/Ubuntu может означать и простую опечатку в имени раздела, и пробл ...
Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление

Если XFS-раздел внезапно стал доступен только для чтения, а сервер ушёл в emergency mode, главное — не спешить. Разберём безопасны ...
Debian/Ubuntu: как исправить Failed to fetch при apt update OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Failed to fetch при apt update

Ошибка Failed to fetch при apt update в Debian и Ubuntu обычно связана не с самим APT, а с DNS, сетью, зеркалом, прокси, временем ...