Die PostgreSQL Streaming-Replikation bietet einen robusten Mechanismus zur Echtzeit-Pflege von Datenbankkopien ueber mehrere Server hinweg. Ob Sie Hochverfuegbarkeit, Disaster Recovery oder Lese-Skalierung benoetigen — die Streaming-Replikation liefert Byte-Level-Konsistenz mit minimalem Lag. Diese Anleitung fuehrt Sie durch die Einrichtung einer Primaer-Standby-Architektur von Grund auf, die Konfiguration der WAL-Archivierung, die Ueberwachung der Replikationsgesundheit und die Planung von Failover-Strategien.

Voraussetzungen

  • Zwei Linux-Server (Ubuntu 22.04+ oder RHEL 9+) mit Netzwerkverbindung
  • PostgreSQL 16 oder neuer auf beiden Servern installiert
  • Ausreichend Speicherplatz fuer WAL-Dateien und Basis-Backups
  • Root- oder Sudo-Zugriff auf beiden Maschinen
  • Port 5432 offen zwischen Primaer- und Standby-Server
  • Grundlegende Vertrautheit mit PostgreSQL-Konfigurationsdateien

PostgreSQL-Replikation verstehen

PostgreSQL unterstuetzt zwei Hauptreplikationsmodi: Streaming-Replikation und logische Replikation. Die Streaming-Replikation arbeitet auf WAL-Byte-Ebene (Write-Ahead Log) und sendet einen kontinuierlichen Strom von WAL-Records vom Primaerserver an die Standbys. Dies erzeugt eine exakte binaere Kopie des gesamten Clusters.

Der Replikationsprozess folgt diesem Ablauf:

  1. Der Primaerserver schreibt Aenderungen in WAL-Segmente
  2. Der WAL-Sender-Prozess uebertraegt Records an verbundene Standbys
  3. Der WAL-Receiver des Standby schreibt Records in das lokale WAL
  4. Der Startup-Prozess des Standby spielt WAL-Records ab um Datendateien zu aktualisieren

Die Streaming-Replikation kann im asynchronen (Standard) oder synchronen Modus arbeiten. Der asynchrone Modus bietet bessere Performance mit minimalem Lag, waehrend der synchrone Modus null Datenverlust auf Kosten der Schreiblatenz garantiert.

Konfiguration des Primaerservers

Bearbeiten Sie die postgresql.conf des Primaerservers um die Replikation zu aktivieren:

# /etc/postgresql/16/main/postgresql.conf

listen_addresses = '*'
wal_level = replica
max_wal_senders = 5
wal_keep_size = '1GB'
hot_standby = on

Der Parameter wal_level = replica stellt sicher, dass das WAL ausreichend Informationen fuer die Replikation enthaelt. max_wal_senders steuert, wie viele gleichzeitige Streaming-Verbindungen erlaubt sind. wal_keep_size verhindert, dass der Primaerserver WAL-Segmente recycelt, bevor der Standby sie verarbeitet hat.

Konfigurieren Sie als Naechstes pg_hba.conf, um dem Standby die Verbindung fuer die Replikation zu erlauben:

# /etc/postgresql/16/main/pg_hba.conf

# TYPE  DATABASE        USER            ADDRESS              METHOD
host    replication     replicator      10.0.1.20/32         scram-sha-256

Ersetzen Sie 10.0.1.20 durch die IP-Adresse Ihres Standby-Servers.

Erstellen Sie einen dedizierten Replikationsbenutzer:

CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'your_secure_password';

Starten Sie PostgreSQL neu um die Konfigurationsaenderungen zu uebernehmen:

sudo systemctl restart postgresql

Einrichtung des Standby-Servers

Stoppen Sie auf dem Standby-Server PostgreSQL und leeren Sie das bestehende Datenverzeichnis:

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

Fuehren Sie pg_basebackup aus, um die Daten des Primaerservers zu klonen:

sudo -u postgres pg_basebackup \
  -h 10.0.1.10 \
  -U replicator \
  -D /var/lib/postgresql/16/main \
  -Fp -Xs -P -R

Die Flags haben spezifische Zwecke:

  • -Fp: Ausgabe im Klartextformat
  • -Xs: WAL waehrend des Backups streamen um Luecken zu vermeiden
  • -P: Fortschritt anzeigen
  • -R: Erstellt automatisch standby.signal und schreibt primary_conninfo in postgresql.auto.conf

Wenn Sie manuelle Konfiguration bevorzugen, erstellen Sie das Standby-Signal und die Verbindungseinstellungen selbst:

touch /var/lib/postgresql/16/main/standby.signal

Fuegen Sie in postgresql.conf auf dem Standby hinzu:

primary_conninfo = 'host=10.0.1.10 port=5432 user=replicator password=your_secure_password application_name=standby1'
hot_standby = on

Starten Sie den Standby-Server:

sudo systemctl start postgresql

WAL-Archivierung

Die WAL-Archivierung bietet ein zusaetzliches Sicherheitsnetz, indem abgeschlossene WAL-Segmente an einen Archivierungsort kopiert werden. Dies ermoeglicht Point-in-Time-Recovery (PITR) und schuetzt vor Szenarien, in denen der Standby zu weit zurueckfaellt.

Konfigurieren Sie die Archivierung auf dem Primaerserver:

# /etc/postgresql/16/main/postgresql.conf

archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/wal_archive/%f'

Erstellen Sie das Archivverzeichnis:

sudo mkdir -p /var/lib/postgresql/wal_archive
sudo chown postgres:postgres /var/lib/postgresql/wal_archive

Fuer Produktionsumgebungen verwenden Sie rsync oder eine Cloud-Speicherloesung anstelle von lokalem cp:

archive_command = 'rsync -a %p backup-server:/wal_archive/%f'

Konfigurieren Sie den Standby, um archiviertes WAL als Fallback mit restore_command zu verwenden:

# In postgresql.conf des Standby
restore_command = 'cp /mnt/wal_archive/%f %p'

Dies ermoeglicht dem Standby, WAL-Segmente aus dem Archiv wiederherzustellen, wenn das Streaming in Rueckstand geraet.

Ueberwachung des Replikations-Lag

Die Ueberwachung des Replikations-Lag ist entscheidend, um sicherzustellen, dass Ihr Standby aktuell bleibt. Auf dem Primaerserver fragen Sie pg_stat_replication ab:

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

Auf dem Standby-Server ueberpruefen Sie den Receiver-Status und berechnen den Lag:

SELECT
  status,
  received_lsn,
  latest_end_lsn,
  last_msg_send_time,
  last_msg_receipt_time
FROM pg_stat_wal_receiver;

-- Zeitbasierte Lag-Schaetzung
SELECT
  now() - pg_last_xact_replay_timestamp() AS replication_delay;

Richten Sie einen Alarm ein, wenn der Lag Ihren Schwellenwert ueberschreitet:

#!/bin/bash
LAG_BYTES=$(psql -h primary -U monitor -t -c \
  "SELECT pg_wal_lsn_diff(sent_lsn, replay_lsn) FROM pg_stat_replication WHERE application_name='standby1';")

if [ "$LAG_BYTES" -gt 104857600 ]; then
  echo "ALARM: Replikations-Lag ueberschreitet 100MB ($LAG_BYTES Bytes)" | mail -s "PG Replication Alert" admin@example.com
fi

Failover-Strategien

Wenn der Primaerserver ausfaellt, benoetigen Sie einen klaren Failover-Plan. PostgreSQL bietet mehrere Promotion-Methoden:

Manuelle Promotion:

# Mit pg_ctl
sudo -u postgres pg_ctl promote -D /var/lib/postgresql/16/main

# Mit SQL (PostgreSQL 12+)
SELECT pg_promote(wait := true, wait_seconds := 60);

Promotion per Trigger-Datei:

Konfigurieren Sie promote_trigger_file in der postgresql.conf des Standby:

promote_trigger_file = '/tmp/postgresql.trigger'

Erstellen Sie die Datei um die Promotion auszuloesen:

touch /tmp/postgresql.trigger

Automatisiertes Failover mit Patroni:

Fuer Produktionsumgebungen verwenden Sie ein Tool wie Patroni mit etcd:

# /etc/patroni/patroni.yml (Auszug)
scope: pg-cluster
namespace: /db/
name: node1

restapi:
  listen: 0.0.0.0:8008

etcd:
  hosts: 10.0.1.100:2379

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    maximum_lag_on_failover: 1048576

postgresql:
  listen: 0.0.0.0:5432
  data_dir: /var/lib/postgresql/16/main
  authentication:
    replication:
      username: replicator
      password: your_secure_password

Nach dem Failover muss der alte Primaerserver als Standby mit pg_rewind wiedereingefuehrt werden:

sudo -u postgres pg_rewind \
  --target-pgdata=/var/lib/postgresql/16/main \
  --source-server="host=10.0.1.20 port=5432 user=postgres"

Vergleich: Streaming vs Logische Replikation

MerkmalStreaming-ReplikationLogische Replikation
ReplikationsebeneByte-Ebene (WAL)Zeilenebene (dekodierte Aenderungen)
Cluster-UmfangGesamter ClusterPro Tabelle oder pro Datenbank
VersionsuebergreifendGleiche Hauptversion erforderlichVerschiedene Hauptversionen unterstuetzt
Schreiben auf StandbyNur Lesen (Hot Standby)Lesen-Schreiben auf dem Subscriber
DDL-ReplikationAutomatischManuell (nicht repliziert)
Performance-OverheadSehr geringModerat (Dekodierungskosten)
EinrichtungskomplexitaetEinfachModerat
AnwendungsfallHA und Disaster RecoverySelektive Replikation und Migrationen

Waehlen Sie Streaming-Replikation fuer vollstaendige Cluster-Hochverfuegbarkeit. Waehlen Sie logische Replikation, wenn Sie selektive Tabellenreplikation, versionsuebergreifende Upgrades oder schreibbare Subscriber benoetigen.

Praxisbeispiel

Sie verwalten eine E-Commerce-Produktionsdatenbank, die 5.000 Transaktionen pro Sekunde verarbeitet. Das Unternehmen verlangt weniger als 30 Sekunden Ausfallzeit bei jedem Fehler. So gestalten Sie die Loesung:

Der Primaerserver (10.0.1.10) verarbeitet alle Schreibvorgaenge. Der synchrone Standby (10.0.1.20) im selben Rechenzentrum gewaehrleistet null Datenverlust. Der asynchrone Standby (10.0.2.10) in einem entfernten Rechenzentrum bietet Disaster Recovery.

Konfigurieren Sie die synchrone Replikation auf dem Primaerserver:

synchronous_standby_names = 'FIRST 1 (standby_dc1, standby_dc2)'
synchronous_commit = on

Leiten Sie Leseabfragen an die Standbys mit PgBouncer oder HAProxy weiter:

# /etc/haproxy/haproxy.cfg (Auszug)
listen pg-read
    bind *:5433
    mode tcp
    balance roundrobin
    option pgsql-check user haproxy
    server standby1 10.0.1.20:5432 check
    server standby2 10.0.2.10:5432 check

Diese Architektur bietet null Datenverlust bei lokalen Ausfaellen und minimalen Datenverlust bei Rechenzentrums-Events, waehrend der Leseverkehr auf die Standbys verlagert wird.

Stolperfallen und Sonderfaelle

  • WAL-Segment-Entfernung: Wenn sich der Standby laenger trennt als wal_keep_size erlaubt, kann er sich nicht per Streaming aktualisieren. Konfigurieren Sie immer WAL-Archivierung als Sicherheitsnetz oder verwenden Sie Replikationsslots: SELECT pg_create_physical_replication_slot('standby1_slot');
  • Replikationsslots und Festplattennutzung: Unbenutzte Replikationsslots verhindern die WAL-Bereinigung und koennen die Festplatte fuellen. Ueberwachen Sie pg_replication_slots und entfernen Sie inaktive Slots
  • Grosse Transaktionen: Eine einzelne massive Transaktion (Massenimport) erzeugt enorme WAL-Volumen die den Standby oder das Netzwerk ueberlasten koennen. Teilen Sie grosse Operationen in Batches auf
  • Synchrone Commit-Latenz: Das Aktivieren von synchronous_commit = on mit synchronen Standbys fuegt jedem Commit die Netzwerk-Umlaufzeit hinzu. Testen Sie den Schreibdurchsatz vor der Aktivierung
  • Timeline-Divergenz: Nach der Promotion eines Standby befindet sich der alte Primaerserver auf einer anderen Timeline. Sie muessen pg_rewind verwenden oder ihn vollstaendig neu aufbauen bevor Sie ihn als Standby wiedereinfuehren
  • Passwort in primary_conninfo: Speichern Sie Anmeldedaten in .pgpass statt als Klartext in Konfigurationsdateien

Fehlerbehebung

Standby verbindet sich nicht:

# Standby-Logs pruefen
sudo tail -f /var/log/postgresql/postgresql-16-main.log

# Replikationsverbindungen auf dem Primaerserver pruefen
sudo -u postgres psql -c "SELECT * FROM pg_stat_replication;"

# Konnektivitaet vom Standby testen
psql -h 10.0.1.10 -U replicator -d postgres -c "IDENTIFY_SYSTEM;"

Replikations-Lag waechst:

-- Pruefen ob der Standby abspielt
SELECT pg_is_in_recovery(), pg_last_wal_replay_lsn();

-- Langlaeufer-Abfragen pruefen die das Abspielen blockieren
SELECT pid, query, state, wait_event FROM pg_stat_activity
WHERE state != 'idle' AND backend_type = 'client backend';

WAL-Archiv fuellt sich:

# Archivierungsstatus pruefen
sudo -u postgres psql -c "SELECT * FROM pg_stat_archiver;"

# Alte Dateien manuell bereinigen (mindestens 1 Tag behalten)
find /var/lib/postgresql/wal_archive -mtime +1 -delete

Zusammenfassung

  • PostgreSQL Streaming-Replikation erstellt binaere Echtzeit-Kopien Ihres gesamten Datenbank-Clusters
  • Konfigurieren Sie wal_level = replica, max_wal_senders und einen Replikationsbenutzer auf dem Primaerserver
  • Verwenden Sie pg_basebackup mit dem -R-Flag um Standbys mit automatischer Konfiguration zu initialisieren
  • WAL-Archivierung bietet ein Sicherheitsnetz fuer Standbys die beim Streaming in Rueckstand geraten
  • Ueberwachen Sie den Replikations-Lag ueber pg_stat_replication und pg_stat_wal_receiver
  • Verwenden Sie Patroni oder aehnliche Tools fuer automatisiertes Failover in der Produktion
  • Replikationsslots verhindern WAL-Entfernung, erfordern aber Ueberwachung um Festplattenerschoepfung zu vermeiden
  • Testen Sie Ihr Failover-Verfahren immer bevor Sie es im Notfall benoetigen

Verwandte Artikel