Траблшутинг разрастания WAL файлов в PostgreSQL: max_slot_wal_keep_size
- Каталог
pg_wal(илиpg_xlog) занимает 100% свободного места на диске, приводя к аварийной остановке PostgreSQL (Panic/Shutdown). - Репликация остановлена или одна из реплик отключилась от сети.
- Слоты логической или физической репликации удерживают старые сегменты WAL.
- В логах фиксируется ошибка:
PANIC: could not write to log file: No space left on device.
1. Поиск причины удержания WAL-сегментов
-- Проверка статуса слотов репликации и объема удерживаемого WAL
SELECT slot_name, slot_type, active,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal,
wal_status
FROM pg_replication_slots;2. Удаление зависшего или неактивного слота
Если реплика была удалена, а слот остался активным на Master:
SELECT pg_drop_replication_slot('problematic_replica_slot');3. Ограничение максимального объема WAL для слотов
Для предотвращения падения сервера из-за отставшей реплики добавьте в postgresql.conf:
# Максимальный объем WAL, удерживаемый слотами репликации (например, 32GB)
max_slot_wal_keep_size = 32GB
# Базовый объем для прямых подключений без слотов
wal_keep_size = 4GBSELECT pg_reload_conf();4. Проверка зависших архивных команд
Если настроен archive_command, проверьте, не зависла ли отправка WAL:
SELECT * FROM pg_stat_archiver;Если last_failed_time свежее last_archived_time, исправьте права или доступность хранилища бэкапов.
Частые вопросы (FAQ)
Что произойдет, если слот превысит лимит max_slot_wal_keep_size?
PostgreSQL пометит статус слота как 'unreserved' или 'lost' и удалит старые WAL для спасения диска Master. Отставшая реплика разорвет репликацию и потребует пересоздания через pg_basebackup.
Можно ли вручную удалять файлы из каталога pg_wal командой rm?
Категорически запрещено. Ручное удаление нужного ядру WAL-сегмента гарантированно приведет к повреждению базы данных и невозможности перезапуска. Удалять слоты и чистить архивы нужно штатно через SQL и pg_archivecleanup.