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:
- Der Primaerserver schreibt Aenderungen in WAL-Segmente
- Der WAL-Sender-Prozess uebertraegt Records an verbundene Standbys
- Der WAL-Receiver des Standby schreibt Records in das lokale WAL
- 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 automatischstandby.signalund schreibtprimary_conninfoinpostgresql.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
| Merkmal | Streaming-Replikation | Logische Replikation |
|---|---|---|
| Replikationsebene | Byte-Ebene (WAL) | Zeilenebene (dekodierte Aenderungen) |
| Cluster-Umfang | Gesamter Cluster | Pro Tabelle oder pro Datenbank |
| Versionsuebergreifend | Gleiche Hauptversion erforderlich | Verschiedene Hauptversionen unterstuetzt |
| Schreiben auf Standby | Nur Lesen (Hot Standby) | Lesen-Schreiben auf dem Subscriber |
| DDL-Replikation | Automatisch | Manuell (nicht repliziert) |
| Performance-Overhead | Sehr gering | Moderat (Dekodierungskosten) |
| Einrichtungskomplexitaet | Einfach | Moderat |
| Anwendungsfall | HA und Disaster Recovery | Selektive 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_sizeerlaubt, 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_slotsund 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 = onmit 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_rewindverwenden oder ihn vollstaendig neu aufbauen bevor Sie ihn als Standby wiedereinfuehren - Passwort in primary_conninfo: Speichern Sie Anmeldedaten in
.pgpassstatt 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_sendersund einen Replikationsbenutzer auf dem Primaerserver - Verwenden Sie
pg_basebackupmit 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_replicationundpg_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