wake-up-neo.com

Wie kann ich einen PostgreSQL 9.3-Slave reparieren, der nicht mit dem Master mithalten kann?

Wir haben eine Master-Slave-Replikationskonfiguration wie folgt.

Auf dem Meister:

postgresql.conf hat die Replikation wie folgt konfiguriert (kommentierte Zeile aus Gründen der Kürze):

max_wal_senders = 1            
wal_keep_segments = 8          

Auf dem Sklaven:

Gleicher postgresql.conf wie beim Master. recovery.conf sieht so aus:

standby_mode = 'on'
primary_conninfo = 'Host=master1 port=5432 user=replication password=replication'
trigger_file = '/tmp/postgresql.trigger.5432'

Bei der ersten Einrichtung haben wir einige einfache Tests durchgeführt und festgestellt, dass die Replikation funktioniert. Beim ersten Laden der Daten gelangten jedoch nur einige Daten zum Slave.

Das Protokoll des Slave ist jetzt mit Nachrichten gefüllt, die folgendermaßen aussehen:

< 2015-01-23 23:59:47.241 EST >LOG:  started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:47.241 EST >FATAL:  could not receive data from WAL stream: ERROR:  requested WAL segment 000000010000000F00000052 has already been removed

< 2015-01-23 23:59:52.259 EST >LOG:  started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:52.260 EST >FATAL:  could not receive data from WAL stream: ERROR:  requested WAL segment 000000010000000F00000052 has already been removed

< 2015-01-23 23:59:57.270 EST >LOG:  started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:57.270 EST >FATAL:  could not receive data from WAL stream: ERROR:  requested WAL segment 000000010000000F00000052 has already been removed

Nach etwas Analyse und Hilfe auf dem Kanal #postgresql IRC bin ich zu dem Schluss gekommen, dass der Slave nicht mit dem Master mithalten kann. Meine vorgeschlagene Lösung lautet wie folgt.

Auf dem Meister:

  1. max_wal_senders=5 einstellen
  2. Setze wal_keep_segments=4000. Ja, ich weiß, dass es sehr hoch ist, aber ich möchte die Situation überwachen und sehen, was passiert. Ich habe Platz beim Meister.

Auf dem Sklaven:

  1. Konfigurationsdateien im Datenverzeichnis speichern (d. H. pg_hba.conf pg_ident.conf postgresql.conf recovery.conf)
  2. Löschen Sie das Datenverzeichnis (rm -rf /var/lib/pgsql/9.3/data/*). Dies scheint von pg_basebackup erforderlich zu sein.
  3. Führen Sie den folgenden Befehl aus: pg_basebackup -h master -D /var/lib/pgsql/9.3/data --username=replication --password

Fehlt mir etwas? Gibt es eine bessere Möglichkeit, den Slave auf den neuesten Stand zu bringen, ohne alle Daten neu laden zu müssen?

Jede Hilfe wird sehr geschätzt.

14
Oleg Dulin

Die zwei wichtigen Optionen für den Umgang mit der WAL for Streaming-Replikation :

  • wal_keep_segments sollte hoch genug eingestellt sein, damit ein Slave nach einer angemessenen Verzögerung aufholen kann (z. B. hohes Update-Volumen, Slave ist offline usw.).

  • archive_mode aktiviert die WAL-Archivierung, mit der Dateien wiederhergestellt werden können, die älter sind als wal_keep_segments. Die Slave-Server benötigen lediglich eine Methode, um die WAL-Segmente abzurufen. NFS ist die einfachste Methode, aber von scp über http bis zu Bändern funktioniert alles, solange es skriptfähig ist. 

    # on master
    archive_mode = on
    archive_command = 'cp %p /path_to/archive/%f' 
    
    # on slave
    restore_command = 'cp /path_to/archive/%f "%p"'
    

    Wenn der Slave das WAL-Segment nicht direkt vom Master abziehen kann, versucht er, den restore_command zum Laden zu verwenden. Sie können den Slave so konfigurieren, dass Segmente automatisch mit der Einstellung archive_cleanup_command entfernt werden. 

Wenn der Slave in eine Situation gerät, in der das nächste benötigte WAL-Segment sowohl im Master als auch im Archiv fehlt, gibt es keine Möglichkeit, die Datenbank konsistent wiederherzustellen. Die sinnvolle Option von only besteht darin, den Server zu scrubben und von einem neuen pg_basebackup zu starten. 

22
Ben Grimm

um sich zu erholen, müssen Sie nicht die gesamte Datenbank löschen und von vorne beginnen. Da der Master über ein aktuelles Binärprogramm verfügt, können Sie den Slave wie folgt wiederherstellen und wieder in Synchronisation bringen:

psql -c "select pg_start_backup('initial_backup');"
rsync -cva --inplace --exclude=*pg_xlog* <data_dir> slave_IP_address:<data_dir>
psql -c "select pg_stop_backup();"

Hinweis:
1. Slave muss von service stop abgelehnt werden
2. Master wird aufgrund der Abfrage pg_start_backup schreibgeschützt.
3. master kann weiterhin schreibgeschützte Abfragen bereitstellen
4. Sklave am Ende der Schritte zurückbringen 

Ich habe das in prod gemacht, es funktioniert perfekt für mich. Slave und Master sind synchron und es gibt keinen Datenverlust. 

0
linehrr

Wie Ben Grimm in den Kommentaren angedeutet hat, ist es eine Frage, ob Segmente auf den maximal möglichen Wert eingestellt werden, damit der Slave aufholen kann. 

0
Oleg Dulin