PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Physische Replikationsmechanismen in PostgreSQL

Postgres verfügt über physische und logische Replikationsfunktionen. Lesen Sie weiter, um mehr über verschiedene Aspekte der physischen Replikation zu erfahren.

Physische Replikation

Physische Replikationsmethoden werden verwendet, um eine vollständige Kopie der gesamten Daten eines einzelnen Clusters (in Postgres ein Cluster ist eine Reihe von Datenbanken, die von einem einzelnen Postgres-Serverprozess namens Postmaster verwaltet werden ), normalerweise auf einem anderen Computer. Der Quellcomputer wird als primärer bezeichnet im Postgres-Jargon, und das Ziel heißt Standby .

Hot, Warm und „Cold“ Standbys

Ein Standby-Server, der so aktuell wie möglich mit dem primären Server in Echtzeit gehalten wird und es Clients ermöglicht, Nur-Lese-Transaktionen auszuführen, wird als Hot bezeichnet Standby oder besser bekannt eine Read Replica . Hot Standbys wurden in Version 9 zu Postgres hinzugefügt, davor gab es nur warm Bereitschaften. Ein Warm-Standby ähnelt einem Hot-Standby, außer dass Clients sich nicht damit verbinden können.

(Nebenbei:Hot-Standbys können keine Abfragen ausführen, die temporäre Tabellen erstellen. Dies ist eine Einschränkung von Postgres.)

Ein „Cold“-Standby (kein offizieller Begriff) ist normalerweise ein Standby-Server, der erst bei einem Failover startet. Da der Cold-Standby nicht aktiv ist und ausgeführt wird, ist es möglich, dass er beim Start zunächst ausstehende Änderungen anwenden muss, bevor er mit der Annahme von Client-Verbindungen beginnen kann.

WAL-Dateien

Im normalen Betriebsablauf generiert ein PostgreSQL-Server eine geordnete Reihe von WAL-Einträgen (Write Ahead Log). Dies ist im Grunde ein Änderungsprotokoll, ähnlich dem AOF von Redis oder dem Binlog von MySQL. Im Kern besteht die physische Replikation darin, diese Datensätze auf eine andere Maschine zu übertragen und den anderen Postmaster, der dort läuft, dazu zu bringen, diese Datensätze zu akzeptieren und in seine lokale Datenbank zu übernehmen.

WAL-Einträge werden in Dateien gleicher Größe (normalerweise 16 MB) unterteilt, die als WAL-Segmente bezeichnet werden oder nur WAL-Dateien . Diese Dateien werden in einem Verzeichnis namens pg_wal erstellt im Clusterdatenverzeichnis (pg_wal hieß pg_xlog in Postgres-Versionen vor 10). Alte WAL-Dateien werden verworfen, wenn sie nicht mehr benötigt werden (und auch basierend auf einigen Konfigurationsparametern).

Wiederherstellungsmodus

Der Postmaster kann in einem Modus namens Wiederherstellungsmodus gestartet werden , indem Sie eine gültige Konfigurationsdatei namens recovery.conf platzieren im Cluster-Datenverzeichnis. Im Wiederherstellungsmodus importiert und wendet Postgres nur WAL-Dateien an, die von einem primären Server generiert wurden, und generiert selbst keine WAL-Dateien. Warm- und Hot-Standby-Server laufen im Wiederherstellungsmodus.

Beim Start im Wiederherstellungsmodus versucht Postgres zunächst, alle in einem Archiv verfügbaren WAL-Dateien zu importieren (mehr dazu weiter unten). Wenn das Archiv keine WAL-Dateien mehr anzubieten hat, versucht es, alle Dateien zu importieren, die in pg_wal von init herumliegen Verzeichnis. Wenn auch diese erledigt sind, wenn eine primäre Verbindung konfiguriert ist und standby_mode auf on gesetzt ist in recovery.conf stellt Postgres eine Verbindung zum primären Server her und ruft neue WAL-Einträge ab und wendet sie an, wenn sie auf dem primären Server erstellt werden.

Protokollversand

Stellen Sie sich vor, Sie hätten einen Trigger, der auf dem primären Server aufgerufen wird, wenn eine neue WAL-Datei erstellt wird. Dieser Trigger kann dann die neue WAL-Datei auf eine andere Maschine kopieren, indem er zum Beispiel rsync verwendet , und platzieren Sie es im pg_wal Verzeichnis eines Postmasters, der im Wiederherstellungsmodus läuft. Kannst du so einen Standby machen?

Die Antwort ist ja, und tatsächlich war dies die Standardpraxis, bevor die Streamingreplikation in Postgres v9 hinzugefügt wurde. Diese Vorgehensweise wird als Protokollversand bezeichnet .

Der Auslöser ist ein Shell-Skript, das mit archive_command konfiguriert werden kann. Dem Skript kann der Name und der Pfad der WAL-Datei übergeben werden.

WAL-Archivierung

Anstatt rsync über die WAL-Datei zu kopieren, sagen wir, wir kopieren sie in einen S3-Bucket oder ein NFS-gemountetes Verzeichnis, auf das auch von der Standby-Maschine aus zugegriffen werden kann. Dieser freigegebene Speicherort enthält jetzt alle WAL-Dateien, die von der primären Maschine generiert wurden. Dies jetzt wird zu einem Archiv , und der Vorgang des Speicherns von WAL-Dateien im Archiv wird als kontinuierliche Archivierung bezeichnet oder einfach WAL-Archivierung .

Die Umkehrung dieser Operation – das Abrufen von WAL-Dateien aus dem Archiv in Postgres im Wiederherstellungsmodus – kann mit dem Befehl „restore_command“ konfiguriert werden. Ähnlich wie bei archive_command , dies ist auch der Pfad zu einem Shell-Skript. Der Postmaster, der im Wiederherstellungsmodus läuft, weiß, welche WAL-Datei er haben möchte. Der Name der Datei kann dem Skript übergeben werden.

Hier sind als Beispiel die Archivierungs- und Wiederherstellungsbefehle zum Speichern und Abrufen von WAL-Dateien in und aus einem S3-Bucket:

archive_command = 's3cmd put %p s3://BUCKET/path/%f' # in postgresql.conf
restore_command = 's3cmd get s3://BUCKET/path/%f %p' # in recovery.conf

Beim Starten im Wiederherstellungsmodus, wenn restore_command konfiguriert ist, wird Postgres zuerst versuchen, WAL-Dateien aus dem Archiv zu holen.

pg_standby

Im Wiederherstellungsmodus weiß und kann Postgres nicht im Voraus wissen, wie viele WAL-Dateien bisher generiert wurden. Wenn der Befehl restore_command konfiguriert ist, ruft Postgres ihn wiederholt mit progressiven WAL-Dateinamen auf (die Namen befinden sich in einer vorhersehbaren Reihenfolge), bis der Befehl einen Fehler zurückgibt.

Beispielsweise konnte der Wiederherstellungsbefehl die Anforderungen für WAL-Dateien 000000010000000000000001 erfüllen bis 00000001000000000000001A aber schlägt fehl für 00000001000000000000001B da es nicht am Speicherort des Archivs gefunden wurde. In Ermangelung von WAL-Dateien aus anderen Quellen geht Postgres davon aus, dass die WAL-Datei 00000001000000000000001B muss noch vom Primärserver generiert werden und wird die Wiederherstellung nach Anwendung von 00000001000000000000001A abschließen .

Überlegen Sie, was passiert, wenn der Wiederherstellungsbefehl auf die Datei 00000001000000000000001B warten würde verfügbar sein, anstatt mit Fehler zu beenden, da es nicht gefunden wurde. Postgres wartet weiterhin auf den Wiederherstellungsbefehl und befindet sich daher weiterhin im Wiederherstellungsmodus.

Dies ist eine gültige Konfiguration und eine gültige Methode zum Einrichten eines Warm-Standby.

Postgres wird mit einem Befehl namens pg_standby ausgeliefert, der verwendet werden kann, um auf diese Weise einen Warm-Standby einzurichten, solange das Archiv ein Verzeichnis ist.pg_standby wartet darauf, dass eine Datei verfügbar wird, wenn sie nicht gefunden werden kann.

Archivierungs- und Wiederherstellungsbefehle mit pg_standby sehen folgendermaßen aus:

archive_command = 'cp %p /some/path/%f'         # in postgresql.conf
restore_command = 'pg_standby /some/path %f %p' # in recovery.conf

Streaming-Replikation

Nach der Verarbeitung archivierter WAL-Dateien sowie Dateien im pg_wal Verzeichnis kann Postgres über das Netzwerk eine Verbindung zu einem primären Server herstellen und wiederholt neue WAL-Dateien abrufen und anwenden, wenn sie erstellt werden. Diese in Postgres 9 hinzugefügte Funktion heißt Streaming-Replikation .

Der primäre Server, zu dem eine Verbindung hergestellt werden soll, kann in der Datei recovery.conf angegeben werden:

# recovery.conf
standby_mode = on
primary_conninfo = 'host=10.0.1.10 user=repl password=p@ssw0rd'

Hot-Standby

Standardmäßig akzeptiert Postgres im Wiederherstellungsmodus keine Client-Verbindungen und lehnt sie mit der Fehlermeldung „Datenbanksystem befindet sich im Wiederherstellungsmodus“ ab. Durch Hinzufügen der Zeile hot_standby = on in recovery.conf können Sie Postgres dazu bringen, Client-Verbindungen zu akzeptieren und ihnen zu erlauben, schreibgeschützte Transaktionen auszuführen:

# recovery.conf
hot_standby = on

Normalerweise gibt es keinen Grund, hot_standby auszuschalten.

Die PostgreSQL-Dokumentation enthält weitere Informationen zum Einrichten und Ausführen eines Standby-Modus im „Hot Standby“-Modus.

Replikationsslots

Replikationsslots wurden in Postgres 9.4 eingeführt. Sie sind ein Mechanismus, um genau und dauerhaft zu verfolgen, wie weit ein Standby hinter dem primären zurückbleibt. Dadurch kann der Primary sicherstellen, dass WAL-Dateien, die noch zum Aufholen des Standby benötigt werden, nicht gelöscht werden.

Vor Replikationsslots war es dem Primärserver nicht möglich, dies festzustellen, und es kam zu Situationen, in denen ein Standby-Server gestrandet war, weil eine benötigte WAL-Datei vom Primärserver gelöscht worden war. Natürlich können WAL-Archive dieses Problem beheben. Ohne ein WAL-Archiv blieb jedoch nur die Möglichkeit, den Standby aus einem frischen Backup neu zu erstellen.

Weitere Informationen zu Replikationsslots finden Sie hier.

Schritte zum Einrichten eines Hot-Standby

Sehen wir uns die Schritte an, die zum Einrichten eines Hot-Standby für eine vorhandene Primärdatenbank erforderlich sind.

1. Replikationsbenutzer erstellen

Zuerst brauchen wir einen Benutzer für die Standby-Verbindung als:

$ psql -p 6000
psql (11.2 (Debian 11.2-1.pgdg90+1))
Type "help" for help.

postgres=# CREATE USER repluser REPLICATION PASSWORD 'p@ssw0rd';
CREATE USER

Und die entsprechenden Änderungen in pg_hba.conf :

# TYPE  DATABASE        USER          ADDRESS        METHOD
host    replication     repluser      standby-ip/32  md5
# (replace standby-ip)

Sie können natürlich jeden Standard-Authentifizierungsmechanismus von PostgreSQL verwenden. Der Benutzer muss über Replikations- und Anmeldeberechtigungen verfügen und benötigt keinen Zugriff auf eine bestimmte Datenbank.

Stellen Sie sicher, dass Sie den primären Server neu laden, damit die Änderungen an pg_hba.conf wirksam werden.

2. Erstellen Sie eine Sicherungskopie

Der Standby muss von einem Backup des primären gestartet werden. Sie können und sollten dies mit pg_basebackup tun mit einem neuen Replikationsslot:

pg_basebackup -h primary-ip -p 6000 -U repluser -C -S slot_standby1 -R -D standby

Dies verbindet sich mit dem primären unter primary-ip:6000 mit dem gerade erstellten Benutzer und legt ein Backup davon in das Verzeichnis standby . Ein neuer Replikationsslotslot_standby1 erstellt.

3. recovery.conf im Standbymodus hinzufügen

Wir verwenden diesen Steckplatz als Standby-Replikationssteckplatz, sodass Kontinuität von der Sicherung besteht.

Wir haben pg_basebackup gefragt um eine recovery.conf zu erstellen für uns oben („-R“-Option). Schauen wir uns das mal an:

$ cat standby/recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=repluser password=''p@ssw0rd'' host=primary-ip port=6000 sslmode=prefer sslcompression=0 krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'slot_standby1'

Das ist eigentlich ziemlich gut, und wir müssen es nicht weiter ändern. Rufen wir jetzt einfach den Standby auf:

o$ pg_ctl -D standby -l log_standby -o --port=6001 start
waiting for server to start.... done
server started
postgres@stg1:/tmp/demo$ cat log_standby
2019-06-19 09:17:50.032 UTC [21733] LOG:  listening on IPv4 address "127.0.0.1", port 6001
2019-06-19 09:17:50.034 UTC [21733] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.6001"
2019-06-19 09:17:50.067 UTC [21734] LOG:  database system was interrupted; last known up at 2019-06-19 09:12:05 UTC
2019-06-19 09:17:50.111 UTC [21734] LOG:  entering standby mode
2019-06-19 09:17:50.119 UTC [21734] LOG:  redo starts at 0/2000028
2019-06-19 09:17:50.120 UTC [21734] LOG:  consistent recovery state reached at 0/20000F8
2019-06-19 09:17:50.120 UTC [21733] LOG:  database system is ready to accept read only connections
2019-06-19 09:17:50.138 UTC [21739] LOG:  started streaming WAL from primary at 0/3000000 on timeline 1

Und das ist es! Die Protokolldatei gibt an, dass die Streaming-Replikation aktiv ist und ausgeführt wird. Sie sollten jetzt in der Lage sein, sich mit dem Standby-Server an Port 6001 zu verbinden, schreibgeschützte Abfragen auszuführen und zu sehen, wie Änderungen mehr oder weniger in Echtzeit vom primären Server repliziert werden.

Nächste Schritte

Die PostgreSQL-Dokumente sind ein großartiger Ort, um weiter in alle replikationsbezogenen Funktionen von Postgres einzutauchen. Sie sollten sich mit Themen wie verzögerter Replikation, kaskadierender Replikation, synchronen Standbys und mehr befassen.

Obwohl Postgres mit einer beeindruckenden Reihe von Funktionen ausgestattet ist, gibt es immer noch Anwendungsfälle, die nicht unterstützt werden. Diese Postgres-Wikiseite enthält eine Liste von Tools von Drittanbietern, die zusätzliche replikationsbezogene Funktionen bereitstellen.