PostgreSQL Streaming Replication — встроенный механизм репликации PostgreSQL, непрерывно копирующий WAL-поток (Write-Ahead Log) с primary-сервера на standby-реплики. Обеспечивает горячий резерв и масштабирование чтения.
Как работает
Primary-сервер записывает каждое изменение в WAL (журнал предзаписи) перед применением. WAL-receiver на standby подключается к primary и получает WAL-записи в реальном времени. Standby применяет WAL и всегда находится в состоянии, соответствующем primary с задержкой от миллисекунд до секунд.
Два режима: Asynchronous — primary не ждёт подтверждения от standby. Минимальная задержка, риск потери последних транзакций при аварии. Synchronous — primary ждёт подтверждения WAL от standby перед подтверждением транзакции клиенту. Нет потери данных, небольшое снижение производительности.
История
Streaming Replication появилась в PostgreSQL 9.0 (2010) — до этого репликация возможна только через WAL file shipping (с задержкой). В 9.0 же добавлены Hot Standby (чтение с реплики) и Synchronous replication. PostgreSQL 10 (2017) принёс логическую репликацию (Logical Replication) для репликации отдельных таблиц. Patroni (Zalando, 2016) автоматизировал failover — стандарт HA-кластеров PostgreSQL.
Настройка
# На PRIMARY (/etc/postgresql/15/main/postgresql.conf)
wal_level = replica
max_wal_senders = 5
wal_keep_size = 128MB
synchronous_standby_names = '' # или 'standby1' для sync
# pg_hba.conf на primary
host replication replicator standby-ip/32 scram-sha-256
# Создать пользователя репликации
CREATE USER replicator REPLICATION LOGIN PASSWORD 'securepass';
# На STANDBY — базовая копия
pg_basebackup -h primary-ip -U replicator -D /var/lib/postgresql/15/main -P -Xs -R
# Запустить standby
systemctl start postgresql
Мониторинг репликации
# Отставание реплики (lag) в байтах и секундах
SELECT client_addr,
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes,
write_lag, flush_lag, replay_lag
FROM pg_stat_replication;
# На standby: отставание от primary
SELECT now() - pg_last_xact_replay_timestamp() AS replication_delay;
Алерт в Grafana: replication_delay > 30 секунд — признак проблем с сетью или перегрузки standby.
Failover с Patroni
Patroni использует etcd, Consul или ZooKeeper для distributed locking и автоматически повышает standby до primary при недоступности основного. patronictl управляет кластером: patronictl -c /etc/patroni.yml list — статус узлов, patronictl failover cluster — ручное переключение.
На что обращать внимание
Primary с включённым synchronous replication без доступного standby «зависает» при транзакциях записи — настройте synchronous_commit = local как fallback. Временные метки репликации зависят от синхронизации NTP. При failover необходимо обновить строки подключения в приложениях — используйте Patroni со встроенным HAProxy-прокси или pgBouncer для прозрачного переключения без изменений в приложении.
Мониторинг и обслуживание репликации
Здоровье репликации нужно мониторить постоянно. Ключевые метрики: pg_stat_replication на мастере (показывает lag в байтах и времени), pg_is_in_recovery() на реплике (должна возвращать true), SELECT now() - pg_last_xact_replay_timestamp() — отставание по времени. Если lag растёт — нагрузка на мастер превышает пропускную способность репликации или сеть перегружена.
Для автоматического failover используются инструменты Patroni (в связке с etcd или Consul) или repmgr. Они следят за доступностью мастера и при его падении автоматически промоутируют реплику, обновляют конфигурацию клиентов через HAProxy или Nginx. Ручной failover без автоматизации — рискованная процедура: во время промоута возможна рассинхронизация, если реплика не догнала мастер. Point-in-Time Recovery (PITR) через WAL-архивы позволяет восстановить базу на любой момент времени до инцидента.