Кейс восстановления репликации PostgreSQL | PGLens.

Восстановление репликации PostgreSQL после длительного отключения мастера

Ситуация

В PostgreSQL-кластере на базе Patroni потребовалось обеспечить восстановление репликации после длительного отключения бывшего мастера.

Архитектура включала Patroni, etcd, HAProxy и Keepalived. PostgreSQL был вынесен на отдельный диск. Основная задача заключалась в том, чтобы после failover или switchover и последующего длительного отключения ноды восстановление выполнялось с помощью pg_rewind, без полной реинициализации ноды.

При этом требовалось обеспечить возможность такого восстановления в течение нескольких суток.

Симптомы

Для проверки сценария нода была отключена на продолжительное время, после чего её вернули в кластер.

После включения PostgreSQL не смог продолжить получение WAL. В журнале появилась ошибка вида requested WAL segment <…> has already been removed – необходимый WAL-сегмент на новом мастере уже отсутствовал.

На что обратили внимание

Первоначально предполагалось, что для решения достаточно увеличить максимальный объем WAL, который PostgreSQL сохраняет для слотов репликации.

Однако повторный тест показал, что одного увеличения max_slot_wal_keep_size недостаточно.

При дальнейшем анализе специалисты обратили внимание на работу Patroni и replication slots.

Было установлено, что Patroni удалил слот репликации, относящийся к старому мастеру. После этого новый мастер перестал удерживать WAL, необходимые отключённой ноде для восстановления.

Причина

Причиной стало штатное поведение Patroni: слот репликации отсутствующего члена кластера удаляется по истечении member_slots_ttl (значение по умолчанию – 30 минут). Отключённая нода простаивала дольше этого порога, поэтому Patroni удалил её слот, и новый мастер перестал удерживать соответствующий WAL.

Когда нода вернулась в кластер, нужного WAL-сегмента на мастере уже не было. Это блокировало и pg_rewind, и последующий догон по стримингу: pg_rewind требует WAL начиная с точки расхождения, а при его отсутствии остаётся только полная реинициализация ноды – ровно то, чего требовалось избежать.

Для решения увеличили member_slots_ttl до 5 дней — максимального ожидаемого времени простоя. Одновременно проверили, что max_slot_wal_keep_size допускает удержание нужного объема WAL, а на диске достаточно места под накопление.

После изменения настроек провели повторный тест с длительным отключением ноды – восстановление прошло успешно.

Также для длительных простоев как более надёжную стратегию предложили реализацию непрерывного архивирование WAL (archive_command + restore_command): это снимает нагрузку с диска мастера и позволяет ноде забрать недостающие сегменты из архива.

Выводы

Кейс показал, что при использовании Patroni недостаточно контролировать только объем хранимых WAL.

При проектировании сценария восстановления после длительного отключения ноды необходимо учитывать сразу несколько факторов:

  • жизненный цикл replication slots;
  • срок возможного отключения ноды;
  • скорость генерации WAL;
  • объём дискового пространства;
  • механизм восстановления реплики после failover или switchover.

Особенно важно учитывать, что рост базы данных и объем генерируемого WAL – не одно и то же. Объем WAL напрямую зависит от характера нагрузки и выполняемых операций и может существенно меняться со временем.

Если требуется хранить WAL в течение длительного периода, одного локального хранения может быть недостаточно – стоит рассматривать дополнительное архивирование WAL.

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

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

    Напишите нам
    Удобнее с телефона?
    Сканируйте QR