DBAtlas · Atlas für Datenbankbetrieb

PostgreSQL Streaming Replication + automatisches Failover

Symptom

Ziel: eine Hot Standby für PostgreSQL mit Streaming Replication einrichten und Patroni/repmgr für automatisches Failover ergänzen.

1. WAL- und Verbindungsparameter auf der Primary setzen

Für Streaming Replication muss wal_level mindestens 'replica' sein. max_wal_senders muss die Anzahl der Replicas + Backup-Verbindungen abdecken, und ein vorzeitiges Entfernen von WAL muss mit wal_keep_size oder einem Replication Slot verhindert werden. Die Änderungen erfordern einen Neustart.

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. Replikationsrolle und pg_hba-Zugriff definieren

Lege eine Rolle mit dem Attribut REPLICATION an, mit der sich die Standby verbindet. Füge in pg_hba.conf eine Zeile hinzu, die den Zugriff auf die Datenbank 'replication' von der Standby-IP erlaubt, und lade mit pg_reload_conf() neu.

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. Persistenten Replication Slot auf der Primary anlegen

Ein physischer Replication Slot verhindert, dass die Primary benötigtes WAL entfernt, auch wenn die Standby zurückfällt; die Slot-Verwaltung ist sicherer als wal_keep_size. Den Slot-Namen verwenden wir in der Standby-Konfiguration.

PostgreSQL

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

4. Base Backup auf dem Standby-Server mit pg_basebackup erstellen

Erstelle bei leerem Datenverzeichnis der Standby eine vollständige Kopie von der Primary. Das Flag -R schreibt automatisch die Datei standby.signal und primary_conninfo; -C kann zusätzlich den Slot anlegen. Der Slot-Name wird mit -S übergeben.

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 und hot_standby prüfen, Standby starten

Prüfe primary_conninfo (host, user, slot) in der von -R geschriebenen postgresql.auto.conf; das Vorhandensein der Datei standby.signal bestimmt den Standby-Modus. Mit hot_standby=on nimmt die Standby Read-only-Abfragen an. Starte den Dienst.

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. Replikations-Lag von der Primary aus überwachen

Auf der Primary zeigt pg_stat_replication für jede Standby die gesendete/wiedergegebene LSN und den Lag. write/flush/replay lag sollten klein bleiben; sync_state ist 'sync', wenn eine synchrone Replica verwendet wird.

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 oder repmgr für automatisches Failover ergänzen

Reine Streaming Replication erfordert ein manuelles Promote. Automatisches Failover braucht einen Cluster-Manager: Patroni (Leader-Wahl über etcd/Consul + automatisches Promote) oder repmgr (Überwachung/Failover mit repmgrd). Stelle auf Anwendungsseite mit HAProxy/pgBouncer einen einzigen Endpoint bereit. Ist ein manuelles Promote nötig: pg_ctl promote. Stelle vor dem Promote sicher, dass die alte Primary wirklich gestoppt ist und Anwendungen nicht auf sie schreiben können (Split-Brain-Risiko). Um die alte Primary als Standby der neuen Primary wieder einzubinden, ist pg_rewind nötig; dafür müssen wal_log_hints = on oder Daten-Checksummen aktiviert sein.

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
In DBAtlas öffnen →