Das Log-Shipping-Verfahren in Postgres ist ein Ansatz zur Hochverfügbarkeit und Datenreplikation, bei dem kontinuierlich die WAL-Dateien (Write-Ahead Log) von der Primary-Datenbank auf eine oder mehrere Standby-Datenbanken übertragen werden. Diese Standby-Datenbanken wenden die empfangenen WAL-Dateien an, um sich mit der Primary-Datenbank zu synchronisieren und im Falle eines Ausfalls sofort einsatzbereit zu sein. Der Prozess beinhaltet das regelmäßige Kopieren der WAL-Dateien und deren Anwendung auf der Standby-Datenbank, um Datenverluste zu minimieren und eine schnelle Wiederherstellung zu gewährleisten. Zusätzlich kann ein automatisches Failover eingerichtet werden, um die Standby-Datenbank bei einem Ausfall der Primary-Datenbank automatisch als neue Primary-Datenbank zu aktivieren.

1. Konfiguration des Primary-Servers

1.1 .pgpass erstellen

Die Datei .pgpass, die im Home-Verzeichnis des Benutzers postgres aufbewahrt wird, bietet eine bequeme und sichere Methode zur Verwaltung von Anmeldeinformationen für Datenbankverbindungen und ermöglicht es Benutzern sich automatisch am PostgreSQL-Cluster zu authentifizieren.

Die Datei wird bei der Installation eines PostgreSQL-Clusters nicht mitinstalliert und muss händisch erstellt werden. Es darf ausschließlich der Benutzer postgres auf die Datei lesend und schreibend zugreifen, anderenfalls wird die Datei während der Authentifizierung ignoriert.

touch ~/.pgpass && chmod 0600 ~/.pgpass

Die Anmeldeinformationen werden nach folgendem Muster in der Datei gespeichert:

  • host:port:datenbank:user:passwort
echo '*:5432:*:postgres:postgres' >> ~/.pgpass

Der Stern (*) steht für alle möglichen Werte zulassen.

1.2 pg_hba.conf anpassen

Um den Zugriff auf die Datenbank zu erhalten, muss jeder Benutzer sich zunächst authentifizieren. Die Art der Authentifizierung wird in der Konfigurationsdatei pg_hba.conf festgelegt und geregelt.

Für den Zugriff mit psql und für den Einsatz des pg_basebackup über das Replikationsprotokoll von Postgres ist die Konfigurationsdatei entsprechend der eigenen Anforderungen und der Infrastruktur anzupassen.

Client-Zugriff für alle IP-Adressen aus demselben Subnetz:

  • host all all 192.168.178.0/24 scram-sha-256

Backup und Replikation für alle IP-Adressen aus demselben Subnetz:

  • host replication all 192.168.178.0/24 scram-sha-256

Damit die Konfigurationsänderungen wirksam werden, muss die Datei pg_hba.conf neu eingelesen werden.

pg_ctl -D $PGDATA reload

1.3 Archivierung der WAL-Segmente konfigurieren

Für den Fall, dass das Betriebssystem bzw. das Laufwerk, auf dem der PostgreSQL-Cluster läuft, ausfallen sollte, ist es empfehlenswert, die Archivierung von WAL (Write-Ahead Log) auf einen anderen Host auszulagern.

Zu Vorführzwecken wird ein lokales Verzeichnis zur Archivierung der WAL-Segemente namens pg_wal_archive erstellt:

mkdir /var/lib/pgsql/15/pg_wal_archive && chmod 0700 /var/lib/pgsql/15/pg_wal_archive

Nachfolgend wird über die beiden Parameter in postgresql.conf zum einen die Archivierung der WAL-Segmente aktiviert und zum anderen der Pfad zu deren Ablageort festgelegt:

  • archive_mode=on
  • archive_command=’test ! -f /var/lib/pgsql/15/pg_wal_archive/%f && cp %p /var/lib/pgsql/15/pg_wal_archive/%f’

Nach Anpassung der beiden Parameter ist ein Neustart des PostgreSQL-Clusters erforderlich:

pg_ctl -D $PGDATA restart

Die Archivierung eines WAL-Segments findet erst statt, wenn es vollgeschrieben wurde. Dessen Standardgröße beträgt 16MB. Ob der Archivierungsvorgang korrekt funktioniert, lässt sich vorab mit der SQL-Funktion pg_switch_wal() überprüfen. Durch den Funktionsaufaufruf wird das aktuelle WAL-Segment beendet und ein neues gestartet:

psql -c 'SELECT PG_SWITCH_WAL();'

Anschließend lässt sich im pg_wal_archive-Verzeichnis schnell überprüfen, ob das WAL-Segment erfolgreich archiviert wurde und das archive_command korrekt funktioniert:

ls -l /var/lib/pgsql/15/pg_wal_archive

1.4 Replikationsprotokoll für die Backup-Erstellung aktivieren

Zum Aufbau des Standby-Servers muss eine vollständige Kopie des PostgreSQL-Clusters, der auf dem Primary-Server läuft, erstellt werden. Diese Aufgabe wird mit pg_basebackup bewerkstelligt, dessen Funktionsweise auf dem Replikationsprotokoll von Postgres beruht.

Das Verhalten von Postgres wird über dessen Konfigurationsdatei postgresql.conf gesteuert. Die Replikation ist in der Standardkonfiguration mit den beiden folgenden Parameteren bereits aktiviert:

  • wal_level=replica
  • max_wal_senders=10

Die Konfigurationsänderung erfordert einen Neustart des PostgreSQL-Clusters.

2. Konfiguration des Standby-Servers

2.1 Aufbau des Standby-Servers

Auf dem Standby-Server muss bereits ein PostgreSQL-Cluster installiert sein.

Für den Standby-Aufbau ist eine exakte Kopie des PostgreSQL-Clusters vom Primary-Server erforderlich, d.h. beide PostgreSQL-Cluster müssen zueinander binärkompatibel sein und ein und dieselbe Major-Version aufweisen.

Ein mit pg_basebackup erstelltes Backup enthält eine vollständige Kopie des data-Verzeichnisses des PostgreSQL-Servers:

  • Datenbankdateien
  • Konfigurationsdateien
  • WAL-Dateien (Write-Ahead Log)
  • Backup Label und Tablespace Map

Bevor das erstellte Backup auf dem Standby-Server eingespielt werden kann, muss der PostgreSQL-Cluster zunächst angehalten werden:

pg_ctl -D $PGDATA stop

Als Nächstes wird der Inhalt seines data-Verzeichnisses gelöscht:

rm -rf $PGDATA/*

Das Erstellen und Einspielen des Backups auf dem Standby-Server resultiert in einem einzigen Aufruf vonpg_basebackup. Hierbei werden an den pg_basebackup-Aufruf folgende Argumente übergeben:

  • -h: Hostname bzw. IP-Adresse des Primary-Servers
  • -p: Port des PostgreSQL-Clusters auf dem Primary-Server
  • -U: Benutzername des Replikationsbenutzers
  • -D: data-Zielverzeichnis auf dem Standby-Server
pg_basebackup -h 192.168.178.54 -p 5432 -U postgres -D $PGDATA

Der Replikationsbenutzer muss das REPLICATION-Attribut besitzen.

2.2 standby.signal erstellen

Um als Standby zu fungieren, muss der PostgreSQL-Cluster in einen sogenannten permanenten Recovery-Modus überführt werden. Dies wird beim ersten Hochfahren des PostgreSQL-Clusters über die Datei standby.signal initiiert. Hierfür muss die besagte Datei manuell im data-Verzeichnis erstellt werden:

touch $PGDATA/standby.signal

2.3 Abholung der WAL-Segmente konfigurieren

Des Weiteren muss dem Standby-Server bekanntgegeben werden, wo und wie er die archivierten WAL-Segmente des Primary abholen kann. Dies wird in postgresql.conf mit dem Parameter restore_command festgelegt:

  • restore_command = ‘scp postgres@192.168.178.54:/var/lib/pgsql/15/pg_wal_archive/%f %p’

Eine funktionierende SSH-Verbindung zwischen Primary- und Standby-Server muss für die Dateiübertragung konfiguriert sein.

2.4 Aktivierung des hot_standby-Parameters

Der hot_standby=on sorgt dafür, dass auf den Standby-Server lesend zugegriffen werden kann. Ist die Einstellung off, wird das Lesen unterbunden.

3. Standby-Server in Betrieb nehmen

Nach Abschluss der Konfiguration und der Erstellung einer Kopie des PostgreSQL-Clusters vom Primary-Server, kann der Standby-Server hochgefahren werden.

pg_ctl -D $PGDATA start

Der neue Standby-Server befindet sich im Recovery-Modus, wenn folgende Funktion ein true als Wert zurückliefert.

psql -c 'SELECT PG_IS_IN_RECOVERY();'

Auf dem Primary-Server lässt sich über eine System-View namens pg_stat_archiver die Statistiken über die Archivierung von WAL-Dateien ermitteln:

psql -c 'SELECT * FROM pg_stat_archiver;'

Weitere Auskunft zum Archivierungs- und Übermittlungsstatus der WAL-Segmente zum Standby-Server liefern Log-Dateien von PostgreSQL.

Die Log-Shipping-Methode in PostgreSQL bietet eine zuverlässige und einfache Möglichkeit, Daten zwischen einem Primary- und einem Standby-Server zu replizieren, indem WAL-Dateien periodisch übertragen und angewendet werden. Diese Methode eignet sich besonders für Umgebungen mit hohen Latenzen oder begrenzter Netzwerkbandbreite, da sie nicht auf eine kontinuierliche Verbindung angewiesen ist.

Blog Mykola Kumanikin

Mykola Kumanikin

Mykola Kumanikin arbeitet als Consultant für die Proventa AG. Sein Tätigkeitsumfeld umfasst Software-Testing, Ticketmanagement und seit Kurzem Datenbankarchitekturen mit PostgreSQL. Seine fachlichen Erfahrungen sammelte er in den unterschiedlichen Projekten in der Telekommunikationsbranche.