← Back to notes

PostgreSQL replication: streaming,
synchronous commit, failover


Streaming replication

Основа — WAL (Write-Ahead Log): primary пишет каждое изменение в WAL до модификации страниц. Standby получает WAL через walsender/walreceiver и применяет redo. Это база warm/hot standby и failover.

Ключевые объекты:

  • WAL segments — файлы 16 MB в pg_wal/;
  • LSN (Log Sequence Number) — позиция в WAL;
  • timeline — увеличивается на 1 при promotion, защищает от ветвления истории;
  • replication slot — гарантирует, что primary не удалит WAL, пока standby не подтвердил приём (предотвращает разрыв репликации, но риск переполнения pg_wal при долгом отставании).

Asynchronous vs Synchronous

Поведение определяет synchronous_commit:

Sync standbys выбираются через synchronous_standby_names:

  • 'FIRST 2 (s1, s2, s3)' — первые два по порядку (priority);
  • 'ANY 2 (s1, s2, s3)' — кворум, любые два из трёх;
  • '*' — все упомянутые.

Если synchronous_standby_names требует подтверждение, а подходящих sync standby нет, commits с synchronous_commit != local/off будут ждать. Кворум-форма (ANY) обычно устойчивее при нескольких standby.


Failover и switchover

  • Failover — аварийное продвижение standby (pg_promote() или Patroni);
  • Switchover — плановое, обычно через Patroni или pg_ctl promote после остановки старого primary.

Главные риски: split-brain (старый primary вернулся и принимает записи) и потеря WAL без replication slot. Решения: fencing (STONITH/watchdog), replication slots, автоматизация через Patroni.


Мониторинг

pg_stat_replication на primary:

SELECT application_name, state, sync_state,
       write_lsn, flush_lsn, replay_lsn,
       write_lag, flush_lag, replay_lag
FROM pg_stat_replication;
  • statestreaming, catchup, backup;
  • sync_stateasync, potential, quorum, sync;
  • *_lag — интервалы между событиями на primary и подтверждениями со standby.

На standby:

SELECT pg_is_in_recovery();
SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn();

Replication slots:

SELECT slot_name, active, restart_lsn,
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained
FROM pg_replication_slots;

Типичные ошибки

  • считать async «без потерь»;
  • держать replication slot для упавшего standby и переполнить pg_wal;
  • единственный sync standby без кворума;
  • отсутствие fencing.

DR чеклист

  • регулярные backup + restore drills;
  • алерты на replay_lag, размер pg_wal, неактивные slots;
  • runbook failover/switchover с фактической репетицией.

Ссылки

PostgreSQL replication: streaming, synchronous commit, failover | Aleksandr Suprun