Каскадный отказ PostgreSQL Patroni из-за WAL: разбор инцидента и роль PGLens.

Каскадный отказ PostgreSQL (Patroni) из-за переполнения дисков и настроек WAL

Суть инцидента

Произошел полный отказ трехузлового кластера PostgreSQL под управлением Patroni. Авария носила каскадный характер: падение мастера по причине исчерпания дискового пространства спровоцировало failover, после чего новый мастер также исчерпал место на диске из-за агрессивных настроек удержания WAL-файлов для отставшей реплики.

Хронология каскадного отказа

На основе логов восстановлена следующая цепочка событий:

  • Смерть первого мастера: Нода 1 исчерпала свободное место на диске и аварийно остановилась. Перед падением она не успела отправить на реплики WAL-файл 000000070000013300000087.
  • Отработка Failover: Patroni переключил роль лидера на Ноду 2.
  • Блокировка репликации: Нода 3 запросила у нового мастера (Ноды 2) недостающий WAL-файл, но передать его было невозможно.
  • Удушение нового мастера: Из-за наличия активного слота репликации и настройки max_slot_wal_keep_size = -1 (неограниченное хранение WAL), Нода 2 начала бесконечно копить новые WAL-файлы, пытаясь сохранить их для отстающей Ноды 3.
  • Смерть второго мастера: Диск на Ноде 2 переполнился скопившимися WAL-файлами, и она также упала.
  • Распад кластера: Нода 3 не могла стать мастером (потерян кворум etcd, т.к. они находились на тех же хостах). Кластер полностью остановил работу.

Как восстанавливали

  • Работоспособность Ноды 2 была восстановлена путем расширения места на диске.
  • Нода 1 была реинициализирована.
  • Нода 3 так и не смогла получить запрошенный WAL …87, из-за чего была также выполнена её полная реинициализация.

Анализ причин инцидента

Авария стала возможной из-за комбинации отсутствующего мониторинга и фатальных ошибок в конфигурации PostgreSQL:

  • max_slot_wal_keep_size = -1 — критическая ошибка. При такой настройке мастер никогда не удаляет WAL-файлы, если отставшая реплика их не подтвердила. Мастер жертвует собой (своим диском) ради реплики.
  • checkpoint_timeout = 30 — экстремально низкое значение (30 секунд вместо дефолтных 5 минут). Это заставляет базу непрерывно сбрасывать данные на диск, генерируя гигантский объем WAL-трафика, что моментально забивает дисковое пространство.
  • Отсутствие мониторинга свободного места и задержки репликации (lag) привело к тому, что проблема развивалась несколько часов, но была замечена только при полном разрушении кластера.
  • Нахождение БД etcd на тех же хостах что и PostgreSQL. Когда на ноде 1, а затем и на ноде 2 закончилось свободное дисковое пространство из-за накопления WAL-файлов базы данных, служба etcd на этих серверах также потеряла возможность осуществлять запись.

План по предотвращению подобных сбоев

Конфигурация PostgreSQL

  • Установить max_slot_wal_keep_size = 16GB (или иное разумное значение в зависимости от диска). Мастер должен отбрасывать безнадежно отставшую реплику, чтобы выжить самому.
  • Вернуть checkpoint_timeout к значению по умолчанию 300 (5 минут) или выше, чтобы снизить генерацию WAL.

Архитектура и дисковая подсистема

  • Вынести логи из PGDATA: Директория с логами PostgreSQL должна находиться вне каталога данных. Это спасет логи от удаления при выполнении реинициализации ноды.
  • Разнести ОС и данные PostgreSQL на разные физические или логические диски.
  • Унифицировать размер дисков на всех узлах кластера.
  • Вынести кластер etcd на отдельные хосты.

Работа с логами и мониторинг

  • Внедрить систему мониторинга (например, Zabbix) с обязательными алертами на: свободное место на дисках, статус репликации и отставание слотов.
  • Настроить ротацию логов PostgreSQL с глубиной хранения не менее 2 недель.
  • Настроить ротацию системного лога messages (logrotate). Сейчас файлы весят более 6 ГБ, что делает их оперативный анализ затруднительным.

Роль PGLens и Zabbix

В данном инциденте критически важно использовать комплексный подход: инфраструктурный мониторинг (Zabbix) для своевременного оповещения и глубокую аналитику профиля нагрузки (PGLens) для поиска первопричины. Совместная работа этих инструментов могла бы помочь на трех ключевых этапах.

1. Раннее выявление аномальной генерации WAL

  • Роль Zabbix: Система зафиксировала бы резкое сокращение свободного места на дисках и отправила экстренное уведомление инженерам.
  • Роль PGLens: Получив сигнал, администратор смог бы быстро найти причину аномалии. Инструмент непрерывно собирает статистику фоновых процессов, и на его графиках был бы отчетливо виден всплеск записи и зашкаливающее количество контрольных точек

2. Контроль «бесконечного» слота репликации

  • Роль Zabbix: Настроеные триггеры просигнализировали бы об опасном отставании третьего узла от мастера.
  • Роль PGLens: PGLens позволяет детально контролировать поток WAL и отслеживать состояние слотов репликации в реальном времени.

3. Независимый «черный ящик» при расследовании

При полном отказе кластера и потере данных Zabbix лишь констатирует факт недоступности серверов. Так как PGLens обычно хранит собранную статистику в отдельной независимой базе данных, все исторические метрики производительности сохранились бы даже после полного уничтожения каталога PGDATA на упавших узлах (при выполнении реинициализации). Это позволило бы с точностью до минуты восстановить картину нагрузки и состояние первого узла перед его аварийной остановкой, чтобы провести качественный разбор сбоя.

Бесплатный 7‑дневный аудит PostgreSQL с PGLens

PGLens остается у вас для полноценного тестирования еще до 90 дней БЕСПЛАТНО