Wie man PostgreSQL Streaming Replikation mit Replikationsslots unter Debian 10 einrichtet

PostgreSQL ist ein leistungsfähiges und funktionsreiches relationales Datenbank-Management-System (RDBMS). Es ist frei und quelloffen und befindet sich seit 1996 in der Entwicklung. Postgres bietet verschiedene Möglichkeiten zur Archivierung und Replikation von Daten, eine davon ist die Streaming-Replikation. In diesem Modus verwaltet eine primäre (Master-)Instanz die aktive Hauptdatenbank und führt Operationen aus. Die sekundäre (Slave-)Instanz kopiert alle Änderungen von der primären, wobei eine identische Kopie der aktiven Datenbank beibehalten wird. Der sekundäre Server kann auch schreibgeschützte Abfragen akzeptieren. Wenn der primäre Server ausfällt, kann der sekundäre Server den Standby-Modus verlassen und als neuer Master-Server fungieren (dies wird als Failover bezeichnet).

Die PostgreSQL-Replikation beruht normalerweise auf WAL (write-ahead logging), dem Prozess der Protokollierung von Datenänderungen vor dem Schreiben auf die Festplatte. Diese WAL-Einträge werden dann entweder als Dateien auf einen zweiten Knoten kopiert (dateibasierter Protokollversand) oder direkt zwischen den Knoten gestreamt (Streaming-Replikation). Letzteres reduziert in den meisten Fällen die Verzögerung, mit der Änderungen auf dem Master-Knoten vom Standby-Knoten empfangen werden.

Das Problem bei der Verwendung der Streaming-Replikation ohne dateibasierten Log-Versand ist, dass der sekundäre Server einige WAL-Einträge verpassen könnte, wenn der primäre Server sie zu früh verwirft. Eine Reihe von Konfigurationsparametern kann dieses Risiko verringern, bringt aber oft unnötige Speicherkosten mit sich. Die Lösung sind Replikationsslots, eine von Postgres bereitgestellte Funktion, die sicherstellt, dass der primäre Server WAL-Einträge erst dann verwirft, wenn sie vom Standby-Knoten empfangen wurden.

Wir werden die Streaming-Replikation mit Replikationsslots auf zwei Debian-10-Knoten einrichten.

Anforderungen

  • Zwei identische Debian-10-Instanzen.
  • Root-Zugriff auf beide Instanzen.
  • Die Umgebungsvariable $EDITOR sollte auf beiden Instanzen gesetzt sein.

Schritt 1: Installieren von PostgreSQL

Aktualisieren und starten Sie beide Knoten neu:

apt update
apt upgrade -y
reboot

Installieren Sie Postgres auf beiden Knoten und stellen Sie sicher, dass PostgreSQL aktiviert ist und läuft:

apt install -y postgresql
systemctl enable --now [email protected]

ANMERKUNG: Bei der Aktualisierung von PostgreSQL ist die erste Aktualisierung des Standby-Modus laut ihrer Dokumentation die sicherere Option.

Schritt 2: Erstkonfiguration

Standardmäßig lauscht PostgreSQL nur auf der Loopback-Schnittstelle und ist von außen nicht zugänglich. Ändern Sie die Listen-Adresse auf beiden Knoten, indem Sie postgresql.conf editieren:

$EDITOR /etc/postgresql/11/main/postgresql.conf

Suchen Sie die folgende Zeile:

#listen_addresses = 'localhost'

Ändern Sie es auf:

listen_addresses = 'node_ip_address,127.0.0.1'

Wenn sich beide Knoten das gleiche lokale Netzwerk teilen, können Sie private Adressen für node_ip_address verwenden, obwohl Postgres nicht über das Internet erreichbar sein wird. Andernfalls verwenden Sie öffentliche Adressen.

Speichern Sie die Änderung und starten Sie dann beide Instanzen neu:

systemctl restart [email protected]

Schritt 3: Master-Konfiguration

Dieser Schritt bezieht sich nur auf den Primär-/Masterserver.

Öffnen Sie das Postgres-Terminal:

sudo -u postgres psql

Der Standby-Knoten verwendet einen Benutzer für die Verbindung mit dem Master. Erstellen Sie ihn:

postgres=# CREATE ROLE replicator LOGIN REPLICATION ENCRYPTED PASSWORD 'replicator_password';

Erstellen Sie dann einen Replikationsslot und beenden Sie den Vorgang:

postgres=# SELECT * FROM pg_create_physical_replication_slot('replicator');
postgres=# \q

Der Einfachheit halber werden die Replikationsrolle und der Slot beide „replicator“ genannt, obwohl sie nicht identisch sein müssen.

Erstellen Sie als nächstes einen Eintrag in pg_hba.conf, um dem Replikator-Benutzer die Verbindung vom Standby zum Master zu ermöglichen. Öffnen Sie ihn:

$EDITOR /etc/postgresql/11/main/pg_hba.conf

Fügen Sie die folgende Zeile an das Ende an:

host	replication	replicator	standby_ip_address/32		md5

Starten Sie die Master-Instanz neu:

systemctl restart [email protected]

Schritt 4: Basis-Sicherung

Die Befehle in diesem Schritt sollten auf dem Sekundär-/Slave-Server ausgeführt werden.

Stoppen Sie zunächst Postgres auf dem sekundären Knoten:

systemctl stop [email protected]

Sichern Sie das alte Datenverzeichnis:

mv /var/lib/postgresql/11/main/ /var/lib/postgresql/11/main.bak

Verwenden Sie den folgenden Befehl, um das Datenverzeichnis des Masters auf den Slave zu klonen:

pg_basebackup -h master_ip_address -U replicator -D /var/lib/postgresql/11/main/ -P --password --slot replicator

Sie werden zur Eingabe eines Passworts aufgefordert. Geben Sie das Passwort ein, das Sie bei der Erstellung der Replikatorrolle auf dem Master für diese Rolle gewählt haben. Sobald die Übertragung abgeschlossen ist, übertragen Sie das Eigentum am Datenverzeichnis auf den Postgres-Benutzer:

chown -R postgres:postgres /var/lib/postgresql/11/main

Schritt 5: Standby-Konfiguration

Dieser Schritt bezieht sich nur auf den Sekundär-/Slave-Server.

Aktivieren Sie den Hot-Standby-Modus in postgresql.conf:

$EDITOR /etc/postgresql/11/main/postgresql.conf

Suchen Sie die folgende Zeile und entfernen Sie den Kommentar:

#hot_standby = on

Erstellen Sie die Datei recovery.conf im Postgres-Datenverzeichnis:

$EDITOR /var/lib/postgresql/11/main/recovery.conf

Aktivieren Sie den Standby-Modus:

standby_mode = 'on'

Setzen Sie die Replikationsverbindungsparameter unter Verwendung der auf dem Master erstellten Anmeldeinformationen:

primary_conninfo = 'host=master_ip_address port=5432 user=replicator password=replicator_password'

Setzen Sie den Namen des Replikationsslots, den Sie auf dem Master angelegt haben:

primary_slot_name = 'replicator'

Legen Sie den Pfad zu einer Failover-Trigger-Datei fest:

trigger_file = '/var/lib/postgresql/11/main/failover.trigger'

Wenn der Parameter trigger_file gesetzt ist, wird Postgres den Standby-Modus verlassen und den normalen Betrieb als Primärserver aufnehmen, wenn diese Trigger-Datei erstellt wird. Dieser Parameter ist nicht erforderlich.

Nachdem Sie recovery.conf erstellt haben, gewähren Sie dem Postgres-Benutzer das Eigentum:

chown postgres:postgres /var/lib/postgresql/11/main/recovery.conf

Sie können jetzt Postgres starten:

systemctl start [email protected]

Sie befindet sich jetzt im Bereitschaftsmodus und sollte jede neue Transaktion replizieren.

Prüfung

Testen der Replikation

Um die Replikation zu testen, führen Sie eine beliebige Schreibaktion auf dem Master aus. Erstellen Sie zum Beispiel eine neue Datenbank auf dem Master:

sudo -u postgres psql -c "CREATE DATABASE replitest"

Warten Sie einige Sekunden und listen Sie dann die Datenbanken auf dem Slave auf:

sudo -u postgres psql -c "\l"

Sie sollten sehen, dass die replitest Datenbank tatsächlich durch den Standby-Server repliziert wurde:

List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 replitest | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(4 rows)

Ausfallsicherung testen

HINWEIS: Das Testen der Ausfallsicherung, wie hier gezeigt, erfordert ein Zurücksetzen des Standby-Servers nach der Ausfallsicherung.

Da sich Postgres im Standby-Modus befindet, sollten Sie vor dem Failover keine Schreiboperationen auf dem sekundären Knoten durchführen können. Führen Sie beispielsweise den folgenden Befehl aus:

sudo -u postgres psql -c "CREATE DATABASE test"

Der Befehl sollte fehlschlagen:

ERROR:  cannot execute CREATE DATABASE in a read-only transaction

Um ein Failover zu signalisieren, erstellen Sie die in recovery.conf angegebene Trigger-Datei.

touch /var/lib/postgresql/11/main/failover.trigger

Warten Sie ein paar Sekunden und versuchen Sie dann, eine Schreiboperation durchzuführen. Zum Beispiel:

sudo -u postgres psql -c "CREATE DATABASE test2"

Da Postgres nicht mehr als Standby-Server arbeitet, wird die Operation erfolgreich sein. Postgres wird auch Ihre Datei recovery.conf in recovery.done umbenennen und die Trigger-Datei löschen.

Um in den Standby-Modus zurückzukehren, stoppen Sie Postgres auf dem (ehemaligen) sekundären Knoten:

systemctl stop [email protected]

Setzen Sie das Datenverzeichnis zurück:

mv /var/lib/postgresql/11/main/ /var/lib/postgresql/11/main.2.bak
pg_basebackup -h master_ip_address -U replicator -D /var/lib/postgresql/11/main/ -P --password --slot replicator
chown -R postgres:postgres /var/lib/postgresql/11/main

Und erstellen Sie recovery.conf neu:

cp /var/lib/postgresql/11/main.2.bak/recovery.done /var/lib/postgresql/11/main/recovery.conf

Starten Sie schließlich Postgres neu:

systemctl start [email protected]

Die sekundäre Instanz befindet sich nun wieder im Standby-Modus. Möglicherweise möchten Sie die Replikation zu diesem Zeitpunkt erneut testen.

Beenden

Entfernen Sie z.B. alle unnötigen Datenbanken auf dem Masterknoten:

sudo -u postgres psql
postgres=# DROP DATABASE replitest;

Und löschen Sie die alten Datenverzeichnisse auf Ihrem Standby-Knoten:

rm /var/lib/postgresql/11/main.bak -r
rm /var/lib/postgresql/11/main.2.bak -r

Das könnte Dich auch interessieren …