DBAtlas · Атлас эксплуатации баз данных

PostgreSQL: потоковая репликация + автоматическая отработка отказа

Симптом

Цель: настроить hot standby для PostgreSQL с потоковой репликацией и добавить Patroni/repmgr для автоматической отработки отказа.

1. Задайте параметры WAL и подключений на primary

Для потоковой репликации wal_level должен быть не ниже 'replica'. max_wal_senders должен покрывать число реплик + подключений для бэкапа, а преждевременное удаление WAL нужно предотвратить с помощью wal_keep_size или слота репликации. Изменения требуют перезапуска.

PostgreSQL

ALTER SYSTEM SET wal_level = 'replica';
ALTER SYSTEM SET max_wal_senders = 10;
ALTER SYSTEM SET max_replication_slots = 10;
ALTER SYSTEM SET hot_standby = on;
-- To apply the postgresql.conf change:
-- systemctl restart postgresql

2. Определите роль репликации и доступ в pg_hba

Создайте роль с атрибутом REPLICATION для подключения standby. Добавьте в pg_hba.conf строку, разрешающую доступ к базе 'replication' с IP standby, и перезагрузите конфигурацию через pg_reload_conf().

PostgreSQL

CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'secret';
-- Add to pg_hba.conf:
-- host replication replicator 10.0.0.20/32 scram-sha-256
SELECT pg_reload_conf();

3. Создайте постоянный слот репликации на primary

Физический слот репликации не даёт primary удалять нужные WAL, даже когда standby отстаёт; управление через слоты безопаснее, чем wal_keep_size. Имя слота будет использовано в конфигурации standby.

PostgreSQL

SELECT pg_create_physical_replication_slot('standby1_slot');
SELECT slot_name, active, restart_lsn FROM pg_replication_slots;

4. Сделайте базовый бэкап на сервере standby с помощью pg_basebackup

При пустом каталоге данных standby снимите полную копию с primary. Флаг -R автоматически записывает файл standby.signal и primary_conninfo; -C может также создать слот. Имя слота передаётся через -S.

PostgreSQL

pg_basebackup -h 10.0.0.10 -U replicator -D /var/lib/pgsql/data \
  -R -X stream -S standby1_slot -P -v

5. Проверьте primary_conninfo и hot_standby, запустите standby

Проверьте primary_conninfo (host, user, slot) в postgresql.auto.conf, записанном флагом -R; наличие файла standby.signal определяет режим standby. При hot_standby=on standby принимает запросы только на чтение. Запустите службу.

PostgreSQL

-- Expected in postgresql.auto.conf:
-- primary_conninfo = 'host=10.0.0.10 user=replicator password=secret'
-- primary_slot_name = 'standby1_slot'
-- systemctl start postgresql
SELECT pg_is_in_recovery();  -- should return true on the standby

6. Отслеживайте отставание репликации с primary

На primary pg_stat_replication показывает отправленный/применённый LSN и отставание для каждого standby. write/flush/replay lag должны оставаться небольшими; sync_state равен 'sync', если используется синхронная реплика.

PostgreSQL

SELECT client_addr, state, sync_state,
       pg_wal_lsn_diff(sent_lsn, replay_lsn) AS replay_lag_bytes,
       write_lag, flush_lag, replay_lag
FROM pg_stat_replication;

7. Добавьте Patroni или repmgr для автоматической отработки отказа

Голая потоковая репликация требует ручного promote. Для автоматической отработки отказа нужен менеджер кластера: Patroni (выбор лидера на etcd/Consul + автоматический promote) или repmgr (мониторинг/отработка отказа с repmgrd). На стороне приложения предоставьте единую точку подключения через HAProxy/pgBouncer. Если нужен ручной promote: pg_ctl promote. Перед promote убедитесь, что старый primary действительно остановлен и приложения не могут в него писать (риск split-brain). Для возврата старого primary в качестве standby нового primary нужен pg_rewind; для этого должны быть включены wal_log_hints = on или контрольные суммы данных.

PostgreSQL

-- Manual promote (if there is no cluster manager):
pg_ctl promote -D /var/lib/pgsql/data
-- or via SQL:
SELECT pg_promote();
-- With Patroni: patronictl -c /etc/patroni.yml switchover mycluster
Открыть в DBAtlas →