Wie behebe ich den Fehler „canceling statement due to conflict with recovery“ (Anweisung wird aufgrund eines Konflikts mit der Wiederherstellung abgebrochen) beim Abfragen des Lesereplikats für meine DB-Instance in RDS für PostgreSQL?

Zuletzt aktualisiert: 23.06.2022

Ich habe ein Lesereplikat für meine Instance im Amazon Relational Database Service (Amazon RDS) für PostgreSQL eingerichtet. Ich erhalte die Fehlermeldung „canceling statement due to conflict with recovery“ (Anweisung wird aufgrund eines Konflikts mit der Wiederherstellung abgebrochen), wenn ich das Lesereplikat abfrage.

Kurzbeschreibung

Dieser Fehler kann auftreten, weil die primäre Instance keine Transparenz über die Aktivitäten hat, die auf dem Lesereplikat ausgeführt werden. Der Konflikt mit der Wiederherstellung tritt auf, wenn WAL-Informationen nicht auf das Lesereplikat angewendet werden können, da die Änderungen eine Aktivität behindern könnten, die auf dem Lesereplikat ausgeführt wird.

Angenommen, Sie führen eine DROP-Anweisung auf der primären Instance aus, wenn eine SELECT-Anweisung mit langer Laufzeit auf dem Lesereplikat der Tabelle ausgeführt wird, die auf der primären Instance abgelegt wurde. Dann hat das Lesereplikat zwei Optionen:

  • Warten, bis die SELECT-Anweisung abgeschlossen ist, bevor der WAL-Eintrag anwendet wird. In diesem Fall erhöht sich die Replikationsverzögerung.
  • Den WAL-Eintrag anwenden und dann die SELECT-Anweisung abbrechen. In diesem Fall erhalten Sie die Fehlermeldung „canceling statement due to conflict with recovery“ (Anweisung wird aufgrund eines Konflikts mit der Wiederherstellung abgebrochen).

Das Lesereplikat löst diese Replikationskonflikte basierend auf dem Wert der Parameter max_standby_streaming_delay und max_standby_archive_delay. Der Parameter max_standby_streaming_delay legt fest, wie lange das Lesereplikat warten muss, bevor Standby-Abfragen abgebrochen werden, die mit WAL-Einträgen in Konflikt stehen, die gerade angewendet werden sollen. Wenn die widersprüchliche Anweisung nach diesem Zeitraum noch ausgeführt wird, bricht PostgreSQL die Anweisung ab und gibt die folgende Fehlermeldung aus:

ERROR: canceling statement due to conflict with recovery

Dieser Fehler tritt in der Regel aufgrund von lang laufenden Abfragen im Lesereplikat auf.

Im vorherigen Beispiel mit der DROP-Anweisung wird die DROP-Anforderung aus Konsistenzgründen in der WAL-Datei gespeichert, um sie später auf dem Lesereplikat anzuwenden. Angenommen, auf dem Lesereplikat wird bereits eine SELECT-Anweisung ausgeführt, die versucht, Daten aus dem gelöschten Objekt mit einer Laufzeit abzurufen, die den Wert in max_standby_streaming_delay überschreitet. Anschließend wird die SELECT-Anweisung abgebrochen, sodass die DROP-Anweisung angewendet werden kann.

Sitzung 1 (Lesereplikat) Ausführen einer SELECT-Anweisung für example_table:

postgres=> SELECT * from example_table;

Sitzung 2 (primär) Ausführen einer DROP-Anweisung für example_table:

postgres=> DROP TABLE example_table;

Die folgende Fehlermeldung wird angezeigt:

postgres@postgres:[27544]:ERROR:  canceling statement due to conflict with recovery
postgres@postgres:[27544]:DETAIL:  User was holding a relation lock for too long.
postgres@postgres:[27544]:STATEMENT:  select * from example_table;

Außerdem kann ein Abfragekonflikt auftreten, wenn eine Transaktion auf dem Lesereplikat Tupel liest, die auf der primären Instance zum Löschen festgelegt sind. Das Löschen von Tupeln, gefolgt von einer Bereinigung auf der primären Instance, führt zu einem Konflikt mit der SELECT-Abfrage, die noch auf dem Replikat ausgeführt wird. In diesem Fall wird die SELECT-Abfrage auf dem Replikat mit der folgenden Fehlermeldung beendet:

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

Lösung

Wenn bei einem Lesereplikat ein Konflikt auftritt und im Fehlerprotokoll die Fehlermeldung „canceling statement due to conflict with recovery“ (Anweisung wird aufgrund eines Konflikts mit der Wiederherstellung abgebrochen) angezeigt wird, können Sie bestimmte benutzerdefinierte Parameter basierend auf der Fehlermeldung festlegen, um die Auswirkungen des Konflikts zu verringern. Beachten Sie, dass die benutzerdefinierten Parameter für das Lesereplikat festgelegt werden müssen.

Sie erhalten die Fehlermeldung „canceling statement due to conflict with recovery“ (Anweisung wird aufgrund eines Konflikts mit der Wiederherstellung abgebrochen) mit „DETAIL: User was holding a relation lock for too long“ (DETAIL: Benutzer hat eine Beziehungssperre zu lange gedrückt gehalten)

max_standby_streaming_delay/max_standby_archive_delay: Mit diesen Parametern können Sie mehr Zeit einplanen, bevor Standby-Anweisungen abgebrochen werden, die mit den zu verwendenden WAL-Einträgen in Konflikt stehen. Diese Werte stellen die Gesamtzeit dar, die für das Anwenden von WAL-Daten nach dem Empfang der Daten von der primären Instance zulässig ist. Diese Parameter werden abhängig davon angegeben, von wo aus die WAL-Daten gelesen werden. Wenn WAL-Daten aus der Streaming-Replikation gelesen werden, verwenden Sie den Parameter max_standby_streaming_delay. Wenn WAL-Daten vom Archivspeicherort im Amazon Simple Storage Service (Amazon S3) gelesen werden, verwenden Sie den Parameter max_standby_archive_delay.

Beachten Sie bei der Einstellung dieser Parameter Folgendes:

  • Wenn Sie die Werte dieser Parameter auf -1 festlegen, darf die Replikat-Instance ewig warten, bis widersprüchliche Abfragen abgeschlossen sind, wodurch sich die Replikationsverzögerung erhöht.
  • Wenn Sie die Werte dieser Parameter auf 0 festlegen, werden die widersprüchlichen Abfragen abgebrochen und die WAL-Einträge werden auf die Replikat-Instance angewendet.
  • Der Standardwert für diese Parameter ist auf 30 Sekunden festgelegt.
  • Wenn Sie bei der Einstellung dieser Parameter keine Einheit angeben, wird Millisekunde als Einheit betrachtet.

Passen Sie die Werte dieser Parameter an, um Abfrageabbruch oder Replikationsverzögerung basierend auf Ihrem Anwendungsfall auszugleichen.

Hinweis: Wenn Sie max_standby_archive_delay erhöhen, um das Abbrechen von Abfragen zu vermeiden, die mit dem Lesen von WAL-Archiveinträgen in Konflikt stehen, sollten Sie auch max_standby_streaming_delay erhöhen, um Abbrüche im Zusammenhang mit Konflikten mit Streaming-WAL-Einträgen zu vermeiden.

Sie erhalten die Fehlermeldung „canceling statement due to conflict with recover“ (Anweisung wird aufgrund eines Konflikts mit der Wiederherstellung abgebrochen) mit „DETAIL: User query might have needed to see row versions that must be removed“ (DETAIL: Benutzerabfrage musste möglicherweise Zeilenversionen sehen, die entfernt werden müssen)

hot_standby_feedback: Wenn Sie diesen Parameter aktivieren, werden Feedback-Meldungen vom Lesereplikat mit Informationen über die älteste aktive Transaktion an die primäre Instance gesendet. Daher entfernt die primäre Instance keine Datensätze, die für die Transaktion möglicherweise benötigt werden.

Wenn Sie diesen Parameter für das Lesereplikat aktivieren, können lang andauernde Abfragen im Lesereplikat zu einem Aufblähen der Tabelle auf der primären Instance führen. Dies liegt daran, dass Bereinigungsvorgänge nicht die toten Tupel entfernen, die möglicherweise für Abfragen erforderlich sind, die auf dem Lesereplikat ausgeführt werden. Dieser Parameter ist standardmäßig deaktiviert. Seien Sie daher vorsichtig, wenn Sie diesen Parameter aktivieren.

Sie können auch die Ansicht pg_stat_database_conflicts auf dem Lesereplikat auf Statistiken zu Anweisungen überprüfen, die aufgrund von Konflikten mit der Wiederherstellung auf dem Lesereplikat abgebrochen wurden.


War dieser Artikel hilfreich?


Benötigen Sie Hilfe zur Fakturierung oder technischen Support?