PostgreSQL ERROR: Abbruch der Anweisung aufgrund eines Konflikts mit der Wiederherstellung


138

Beim Ausführen einer Abfrage auf einer PostgreSQL-Datenbank im Standby-Modus wird die folgende Fehlermeldung angezeigt. Die Abfrage, die den Fehler verursacht, funktioniert 1 Monat lang einwandfrei. Wenn Sie jedoch länger als 1 Monat abfragen, tritt ein Fehler auf.

ERROR: canceling statement due to conflict with recovery
Detail: User query might have needed to see row versions that must be removed

Irgendwelche Vorschläge zur Lösung? Vielen Dank


Bitte finden Sie das AWS-Dokument, in dem dieser Fehler erwähnt wurde. Es enthält auch die Lösung aws.amazon.com/blogs/database/…
arunjos007

Antworten:


88

Das Ausführen von Abfragen auf einem Hot-Standby-Server ist etwas schwierig - es kann fehlschlagen, da während der Abfrage einige benötigte Zeilen möglicherweise auf dem primären Server aktualisiert oder gelöscht werden. Da eine Primärdatenbank nicht weiß, dass eine Abfrage auf einer Sekundärseite gestartet wird, glaubt sie, alte Versionen ihrer Zeilen bereinigen (staubsaugen) zu können. Dann muss Secondary diese Bereinigung erneut abspielen und alle Abfragen, die diese Zeilen verwenden können, zwangsweise abbrechen.

Längere Abfragen werden häufiger abgebrochen.

Sie können dies umgehen, indem Sie eine wiederholbare Lesetransaktion auf der Primärseite starten, die eine Dummy-Abfrage ausführt und dann inaktiv ist, während eine echte Abfrage auf der Sekundärseite ausgeführt wird. Sein Vorhandensein verhindert das Staubsaugen alter Zeilenversionen auf der Primärseite.

Weitere Informationen zu diesem Thema und andere Problemumgehungen finden Sie im Abschnitt Hot Standby - Behandlung von Abfragekonflikten in der Dokumentation.


10
Um Benutzer von PostgreSQL 9.1+: siehe eradman ‚s Antwort unten für eine praktische Lösung.
Zoltán

3
Für Benutzer von PostgreSQL 9.1+: Die Antwort von max-malysh ist viel vernünftiger. Machen Sie den Eradman-Vorschlag nur, wenn Sie die Risiken verstehen.
Davos

91

Keine Notwendigkeit zu berühren hot_standby_feedback. Wie andere bereits erwähnt haben, kann das Einstellen auf onMaster aufblähen. Stellen Sie sich vor, Sie öffnen eine Transaktion für einen Slave und schließen sie nicht.

Stattdessen legen max_standby_archive_delayund max_standby_streaming_delaybis zu einem gewissen vernünftigen Wert:

# /etc/postgresql/10/main/postgresql.conf on a slave
max_standby_archive_delay = 900s
max_standby_streaming_delay = 900s

Auf diese Weise werden Abfragen von Slaves mit einer Dauer von weniger als 900 Sekunden nicht abgebrochen. Wenn Ihre Workload längere Abfragen erfordert, setzen Sie diese Optionen einfach auf einen höheren Wert.


1
Dies ist die Lösung, die wir letztendlich verwendet haben. Scheint der beste Kompromiss zwischen allen hier vorgestellten Optionen zu sein.
Mohit6up

2
Dies ist die beste Antwort. Beachten Sie, dass diese gemäß den Dokumenten kumulativ sind. Wenn das Replikat mehrere Abfragen enthält, die die Replikation aufhalten, kann es sein, dass Sie 899 erreichen und eine weitere Abfrage von 2 Sekunden abgebrochen wird. Es ist am besten, nur ein exponentielles Back-Off in Ihren Code zu implementieren. Außerdem ist die Streaming-Verzögerung wirksam, während die Replikation gestreamt wird. Wenn die Replikation nicht mit dem Streaming Schritt halten kann, wird sie aus dem Archiv repliziert. Wenn Sie aus dem Archiv replizieren, sollten Sie es wahrscheinlich aufholen lassen, es muss max_standby_archive_delaymöglicherweise kleiner als das andere sein.
Davos

2
Dies ist hier immer noch die beste Lösung. Beachten Sie, dass Sie dies in Redshift über Parametergruppeneinstellungen einstellen können, nur dass es in sein sollte ms, dh 900s = 16 Minuten = 900000ms.
NullDev

Um dies auf GCP zu aktualisieren, erfolgt dies auch unter ms cloud.google.com/sql/docs/postgres/…
howMuchCheeseIsTooMuchCheese

Vorausgesetzt, der Zweck von Standby ist beispielsweise die Berichterstellung und es handelt sich nicht um einen Hot-Standby-Modus, der für das Failover bereit sein muss, ist dies die absolut beste Antwort.
Suppenhund

77

Es ist nicht erforderlich, inaktive Transaktionen auf dem Master zu starten. In postgresql-9.1 können Sie dieses Problem am direktesten durch Festlegen lösen

hot_standby_feedback = on

Dadurch wird der Master auf lang laufende Abfragen aufmerksam. Aus den Dokumenten :

Die erste Option besteht darin, den Parameter hot_standby_feedback festzulegen, der verhindert, dass VACUUM kürzlich tote Zeilen entfernt, sodass keine Bereinigungskonflikte auftreten.

Warum ist das nicht die Standardeinstellung? Dieser Parameter wurde nach der ersten Implementierung hinzugefügt und ist die einzige Möglichkeit, wie ein Standby einen Master beeinflussen kann.


11
Dieser Parameter sollte im Standby-Modus eingestellt werden.
Steve Kehlet

3
Es gibt einige Nachteile für Master in diesem Fall Hot-Standby-Feedback
Evgeny Liskovets

50

Wie hier angegeben über hot_standby_feedback = on:

Nun, der Nachteil ist, dass der Standby den Master aufblähen kann, was auch für manche Leute überraschend sein könnte

Und hier :

Mit welcher Einstellung von max_standby_streaming_delay? Ich würde das lieber auf -1 setzen als auf hot_standby_feedback. Auf diese Weise wirkt sich das, was Sie im Standby-Modus tun, nur auf den Standby-Modus aus


Also habe ich hinzugefügt

max_standby_streaming_delay = -1

Und kein pg_dumpFehler mehr für uns, noch Meister aufblähen :)

Überprüfen Sie für eine AWS RDS-Instanz http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html


1
@ Lennard, das hat bei mir funktioniert. Ich habe diese Konfiguration in der postgresql.conf des Slaves hinzugefügt und dann den Slave neu gestartet.
Ardee Aram

13
Auf diese Weise können Sie natürlich eine unbegrenzte Verzögerung der Replik erhalten. Wenn Sie einen Replikationssteckplatz verwenden, um das Replikat mit dem Master zu verbinden, kann dies zu einer übermäßigen Xlog-Aufbewahrung auf dem Master führen. Dies ist also nur dann sinnvoll, wenn Sie die WAL-Archivierung verwenden.
Craig Ringer

7
Wie wird dies auf AWS RDS eingestellt?
Kris MP

1
@KrisMP Verwenden Sie psql
Yehonatan

4
@KrisMP in der Parametergruppe - docs.aws.amazon.com/AmazonRDS/latest/UserGuide/…
r3m0t

13

Die Tabellendaten auf dem Hot-Standby-Slave-Server werden geändert, während eine lange laufende Abfrage ausgeführt wird. Eine Lösung (PostgreSQL 9.1+), um sicherzustellen, dass die Tabellendaten nicht geändert werden, besteht darin, die Replikation anzuhalten und nach der Abfrage fortzufahren:

select pg_xlog_replay_pause(); -- suspend
select * from foo; -- your query
select pg_xlog_replay_resume(); --resume

1
Dies erfordert Superuser-Rechte. In einigen Fällen ist dies möglicherweise keine Lösung.
Joao Baltazar

1
In 10 PostgreSQL, xlogwurde mit ersetzt wal, so dass Sie anrufen möchten , pg_wal_replay_pause()und pg_wal_replay_resume().
Womble

2

Für die Antwort mag es zu spät sein, aber wir stehen bei der Produktion vor dem gleichen Problem. Früher hatten wir nur ein RDS und da die Anzahl der Benutzer auf der App-Seite zunimmt, haben wir beschlossen, Read Replica dafür hinzuzufügen. Das Lesereplikat funktioniert beim Staging ordnungsgemäß, aber sobald wir zur Produktion übergegangen sind, wird der gleiche Fehler angezeigt.

Wir lösen dieses Problem, indem wir die Eigenschaft hot_standby_feedback in den Postgres-Eigenschaften aktivieren . Wir haben auf den folgenden Link verwiesen

https://aws.amazon.com/blogs/database/best-practices-for-amazon-rds-postgresql-replication/

Ich hoffe es wird helfen.


1

Ich werde einige aktualisierte Informationen und Verweise auf @ max-malyshs ausgezeichnete Antwort oben hinzufügen.

Kurz gesagt, wenn Sie etwas auf dem Master tun, muss es auf dem Slave repliziert werden. Postgres verwendet hierfür WAL-Datensätze, die nach jeder protokollierten Aktion auf dem Master an den Slave gesendet werden. Der Slave führt dann die Aktion aus und die beiden sind wieder synchron. In einem von mehreren Szenarien kann es auf dem Slave zu Konflikten mit dem kommen, was in einer WAL-Aktion vom Master eingeht. In den meisten von ihnen findet auf dem Slave eine Transaktion statt, die im Widerspruch zu dem steht, was die WAL-Aktion ändern möchte. In diesem Fall haben Sie zwei Möglichkeiten:

  1. Verzögern Sie die Anwendung der WAL-Aktion ein wenig, damit der Slave seine widersprüchliche Transaktion beenden kann, und wenden Sie dann die Aktion an.
  2. Brechen Sie die widersprüchliche Abfrage auf dem Slave ab.

Wir beschäftigen uns mit # 1 und zwei Werten:

  • max_standby_archive_delay - Dies ist die Verzögerung, die nach einer langen Trennung zwischen Master und Slave verwendet wird, wenn die Daten aus einem WAL-Archiv gelesen werden, bei dem es sich nicht um aktuelle Daten handelt.
  • max_standby_streaming_delay - Verzögerung zum Abbrechen von Abfragen, wenn WAL-Einträge über die Streaming-Replikation empfangen werden.

Wenn Ihr Server für die Hochverfügbarkeitsreplikation vorgesehen ist, möchten Sie diese Zahlen im Allgemeinen kurz halten. Hierfür ist die Standardeinstellung 30000(Millisekunden, wenn keine Einheiten angegeben sind) ausreichend. Wenn Sie jedoch so etwas wie ein Archiv-, Berichts- oder Lesereplikat einrichten möchten, das möglicherweise sehr lange Abfragen enthält, sollten Sie dies auf einen höheren Wert einstellen, um abgebrochene Abfragen zu vermeiden. Die oben empfohlene 900sEinstellung scheint ein guter Ausgangspunkt zu sein. Ich bin mit den offiziellen Dokumenten nicht einverstanden, einen unendlichen Wert -1als gute Idee festzulegen - das könnte fehlerhaften Code maskieren und viele Probleme verursachen.

Die einzige Einschränkung bei lang laufenden Abfragen und beim Erhöhen dieser Werte besteht darin, dass andere Abfragen, die parallel zu der lang laufenden Abfrage auf dem Slave ausgeführt werden und die Verzögerung der WAL-Aktion verursachen, alte Daten sehen, bis die lange Abfrage abgeschlossen ist. Entwickler müssen dies verstehen und Abfragen serialisieren, die nicht gleichzeitig ausgeführt werden sollen.

Die vollständige Erklärung, wie max_standby_archive_delayund max_standby_streaming_delayarbeiten und warum, finden Sie hier .


0

Ebenso hier eine zweite Einschränkung zu @ Artif3x Ausarbeitung von @ max-malyshs ausgezeichneter Antwort, beide oben.

Bei verspäteter Anwendung von Transaktionen vom Master haben die Follower eine ältere, veraltete Ansicht der Daten. Beachten Sie daher Folgendes, während Sie Zeit für die Beendigung der Abfrage für den Follower bereitstellen, indem Sie max_standby_archive_delay und max_standby_streaming_delay festlegen. Beachten Sie Folgendes:

Wenn der Wert des Followers für die Sicherung zu stark im Widerspruch zu Hosting-Abfragen steht, besteht eine Lösung aus mehreren Followern, die jeweils für den einen oder anderen optimiert sind.

Beachten Sie außerdem, dass mehrere Abfragen hintereinander dazu führen können, dass die Anwendung von Wal-Einträgen immer wieder verzögert wird. Wenn Sie also die neuen Werte auswählen, ist es nicht nur die Zeit für eine einzelne Abfrage, sondern ein sich bewegendes Fenster, das beginnt, wenn eine widersprüchliche Abfrage beginnt, und endet, wenn der Wal-Eintrag endgültig angewendet wird.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.