Гайды

Потоковая репликация PostgreSQL: настройка и мониторинг

WAL, walsender/walreceiver, primary и standby, pg_basebackup, failover, слоты репликации и сравнение с логической репликацией.

~16 мин чтения

Потоковая репликация PostgreSQL

Потоковая репликация (streaming replication) создаёт побайтовую копию кластера в реальном времени через поток WAL. Это основа высокой доступности и типичный способ масштабировать чтение на репликах.

Важно: ниже — асинхронная репликация: коммит на мастере не ждёт подтверждения записи WAL на реплике. Это стандартный компромисс производительность / актуальность.


Физическая потоковая репликация

Standby подключается к primary и применяет (replay) записи из журнала предзаписи (WAL).

КомпонентРоль
walsenderНа мастере: отдаёт поток WAL каждой реплике
walreceiverНа реплике: принимает WAL
standby.signalМаркер режима реплики (hot standby)
primary_conninfoСтрока подключения реплики к мастеру (часто в postgresql.auto.conf после pg_basebackup -R)

Пример топологии (Ubuntu)

УзелIPРоль
pg-primary10.0.1.10Мастер
pg-replica10.0.1.20Реплика

Требования: PostgreSQL 12+ (гайд ориентирован на 15–17), сеть до порта 5432 (или вашего), sudo. В проде — фаервол только с IP реплики.


1. Мастер (primary)

postgresql.conf

ini
listen_addresses = '*'
wal_level = replica
max_wal_senders = 5
wal_keep_size = 1GB
synchronous_commit = off

wal_keep_size помогает пережить кратковременное отставание реплики без потери нужных сегментов WAL. На больших базах и слабой сети значение часто увеличивают.

pg_hba.conf

Разрешите репликацию с IP реплики:

conf
host    replication     repl_user       10.0.1.20/32        scram-sha-256

Пользователь репликации

bash
sudo -u postgres psql
sql
CREATE USER repl_user WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'secure_password_here';

Перезапуск:

bash
sudo systemctl restart postgresql

Фаервол (мастер)

bash
sudo ufw allow from 10.0.1.20 to any port 5432 proto tcp

2. Реплика (standby)

Остановите PostgreSQL и очистите каталог данных (осторожно: уничтожает локальные данные узла):

bash
sudo systemctl stop postgresql
sudo rm -rf /var/lib/postgresql/*/main/*

Базовый снимок с мастера (-R создаёт standby.signal и подключение):

bash
sudo -u postgres pg_basebackup -h 10.0.1.10 -U repl_user -D /var/lib/postgresql/17/main -P -v -R

postgresql.conf на реплике

hot_standby включён по умолчанию с PostgreSQL 12+ — на реплике можно выполнять SELECT (отчёты, дашборды), если бизнес допускает отставание от мастера.

При необходимости явно:

ini
hot_standby = on

Строка primary_conninfo после -R обычно попадает в postgresql.auto.conf. Ручной пример:

ini
primary_conninfo = 'host=10.0.1.10 port=5432 user=repl_user password=secure_password_here'

Запуск и логи:

bash
sudo systemctl start postgresql
sudo journalctl -u postgresql -f

Мониторинг

На мастере

sql
SELECT client_addr, state, sync_state,
       pg_wal_lsn_diff(pg_current_wal_lsn(), write_lsn) AS write_lag_bytes
FROM pg_stat_replication;

При нормальной работе: state = streaming. Интерпретация лага в «секундах» удобнее на реплике через pg_stat_wal_receiver.

На реплике

sql
SELECT pg_is_in_recovery();

Должно быть true — узел в режиме восстановления (реплика), запись недоступна.


Failover и пересборка

Ручной promote реплики

bash
sudo -u postgres pg_ctl promote -D /var/lib/postgresql/17/main

Узел становится новым мастером. Старый мастер после починки часто пересобирают как реплику через новый pg_basebackup.

Rebuild реплики (пример)

bash
sudo systemctl stop postgresql
sudo rm -rf /var/lib/postgresql/*/main/*
sudo -u postgres pg_basebackup -h 10.0.1.20 -U repl_user -D /var/lib/postgresql/17/main -R -P -v
sudo systemctl start postgresql

Альтернатива при включённом wal_log_hints и корректном сценарии — pg_rewind, чтобы не копировать весь объём данных.

Авто-failover

В ядре PostgreSQL нет встроенного auto-failover. Обычно используют Patroni, repmgr, иногда Pgpool-II — выбор зависит от размера инфраструктуры; для production Patroni часто считается стандартом.


Физическая vs логическая репликация

Физическая (streaming)Логическая
Что копируетсяВесь кластер на уровне WALВыбранные объекты / изменения
СхемаИдентична мастеруМожет отличаться
ПрименениеHA, чтение с репликМиграции, витрины, кросс-версии
СложностьВстроена в ядроПубликации / подписки

Частые проблемы

  • Реплика отстаёт или не подключается — логи реплики, DNS/IP в primary_conninfo, max_wal_senders, строка в pg_hba.conf, пароль.
  • WAL раздувается на мастере — отставшая или отключённая реплика, слоты репликации. В PostgreSQL 13+ смотрите max_slot_wal_keep_size, чтобы отсутствие потребителя не забило диск.
  • Слоты «держат» WALpg_replication_slots: неактивный потребитель, restart_lsn далеко. Реанимируйте потребителя или осознанно pg_drop_replication_slot('...').

Итог

  1. На мастере: wal_level = replica, слоты/лимиты WAL, пользователь REPLICATION, pg_hba.conf, фаервол.
  2. На реплике: чистый data directory, pg_basebackup -R, запуск, проверка pg_is_in_recovery().
  3. Мониторинг: pg_stat_replication, лаг, алерты на рост WAL и на pg_up-аналог для репликации.
  4. Failover — отдельный операционный процесс; для автоматизации нужны внешние оркестраторы.