Wie behebe ich den Fehler "canceling statement due to conflict with recovery" („Anweisung wird aufgrund eines Konflikts mit der Wiederherstellung storniert“), wenn ich das Lesereplikat für meine Amazon RDS für PostgreSQL-DB-Instance abfrage?

Lesedauer: 3 Minute
0

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

Lösung

Wenn ein Replikationskonflikt zwischen der primären Instance und dem Lesereplikat besteht, erhältst du den Fehler Anweisung stornieren. PostgreSQL kann die WAL-Informationen nicht auf das Lesereplikat anwenden, da die Änderungen möglicherweise eine Aktivität blockieren, die auf dem Lesereplikat stattfindet. Du führst beispielsweise eine DROP-Anweisung auf der primären Instance aus, wenn eine SELECT-Anweisung für die gelöschte Tabelle im Lesereplikat ausgeführt wird. Wenn das Lesereplikat den WAL-Datensatz anwendet und die SELECT-Anweisung storniert, erhältst du den Fehler Anweisung stornieren.

Um den Fehler Anweisung stornieren zu beheben, lege benutzerdefinierte Parameter für das Lesereplikat fest, die auf den Details der Fehlermeldung basieren.

Du kannst auch die Ansicht pg_stat_database_conflicts auf dem Lesereplikat auf Statistiken über Anweisungen verwenden, die aufgrund von Konflikten mit der Wiederherstellung abgebrochen wurden. Weitere Informationen findest du unter 27.2.18 pg_stat_database_conflicts auf der PostgreSQL-Website.

Details zur Fehlermeldung: "User was holding a relation lock for too long" („Der Benutzer hat eine Beziehungssperre zu lange aufrechterhalten“)

Um dieses Problem zu beheben, ändere den Parameter max_standby_streaming_delay oder max_standby_archive_delay, sodass mehr Zeit verbleibt, bis das Lesereplikat eine widersprüchliche Standby-Anweisung storniert. Wenn das Lesereplikat die WAL-Daten aus der Streaming-Replikation liest, ändere den Parameter max_standby_streaming_delay. Wenn das Lesereplikat die WAL-Daten vom Archivspeicherort in Amazon Simple Storage Service (Amazon S3) liest, ändere den Parameter max_standby_archive_delay.

Weitere Informationen zu diesen Parametern findest du unter max_standby_streaming_delay (integer) und max_standby_archive_delay (integer) auf der PostgreSQL-Website.

Wenn du den Parameterwert auf 0 setzt, storniert das Lesereplikat die widersprüchlichen Abfragen und wendet die WAL-Einträge auf die Replikat-Instance an. Wenn du den Wert auf –1 setzt, lässt du die Replikat-Instance für immer auf widersprüchliche Abfragen warten, und die Replikationsverzögerung nimmt zu. Passe die Werte dieser Parameter an, um Abfrageabbruch oder Replikationsverzögerung je nach Anwendungsfall auszugleichen.

Hinweis: Wenn du max_standby_archive_delay erhöhst, um Abfragen beizubehalten, die mit dem Lesen von WAL-Archiveinträgen in Konflikt stehen, empfiehlt es sich, auch max_standby_streaming_delay zu erhöhen, um Stornierungen zu verhindern.

Details zur Fehlermeldung: "User query might have needed to see row versions that must be removed" („Die Benutzerabfrage musste möglicherweise Zeilenversionen sehen, die entfernt werden müssen“)

Dieses Problem tritt in der Regel auf, wenn eine Transaktion auf dem Lesereplikat Tupel liest, die auf der primären Instance zum Löschen festgelegt sind. Um dieses Problem zu beheben, musst du möglicherweise den Parameter hot_standby_feedback aktivieren.

Wenn du hot_standby_feedback aktivierst, sendet das Lesereplikat Feedback-Nachrichten mit Informationen über die älteste aktive Transaktion an die primäre Instance. Daher entfernt die primäre Instance keine Datensätze, die die Transaktion möglicherweise benötigt. Weitere Informationen zu diesem Parameter findest du unter hot_standby_feedback (boolean) auf der PostgreSQL-Website.

Wichtig: Der Parameter hot_standby_feedback ist standardmäßig deaktiviert. Wenn du hot_standby_feedback für das Lesereplikat aktivierst, können Abfragen mit langer Laufzeit auf dem Lesereplikat zu einem Bloat der Tabelle auf der primären Instance führen. Vakuumvorgänge entfernen nicht die toten Tupel (Bloat), die bei Abfragen mit langer Laufzeit erforderlich sein könnten. Um das Risiko von Bloats zu verringern, empfiehlt es sich, auch autovacuum_threshold und autovacuum_vacuum_scale_factor zu reduzieren und autovacuum_cost_limit zu erhöhen.