Wie kann ich eine AWS-DMS-Aufgabe beheben, die mit der Fehlermeldung „ERROR: canceling statement due to statement timeout“ fehlschlägt?
Ich migriere Daten zu oder von meiner On-Premises-PostgreSQL-Datenbank mit AWS Database Migration Service (AWS DMS). Die AWS-DMS-Aufgabe läuft eine Zeit lang normal, dann schlägt die Aufgabe mit einem Fehler fehl. Wie kann ich diese Fehler beheben?
Kurzbeschreibung
Wenn die PostgreSQL-Datenbank die Quelle für Ihre Migrationsaufgabe ist, ruft AWS DMS während der Volllastphase Daten aus der Tabelle ab. Anschließend liest AWS DMS aus den Write-Ahead-Protokollen (WALs), die während der Change Data Capture (CDC)-Phase vom Replikations-Slot aufbewahrt werden.
Wenn die PostgreSQL-Datenbank das Ziel ist, ruft AWS DMS die Daten von der Quelle ab und erstellt CSV-Dateien in der Replikations-Instance. Anschließend führt AWS DMS einen COPY-Befehl aus, um diese Datensätze während der Volllastphase in das Ziel einzufügen.
Während der CDC-Phase führt AWS DMS jedoch genau die DML-Anweisungen aus den WAL-Quellprotokollen im Transaktions-Anwendungsmodus aus. Im Batch-Anwendungsmodus erstellt AWS DMS während der CDC-Phase zudem CSV-Dateien. Anschließend führt es einen COPY-Befehl aus, um die Nettoveränderungen in das Ziel einzufügen.
Wenn AWS DMS versucht, Daten von der Quelle abzurufen oder im Ziel abzulegen, verwendet es die Standard-Timeout-Einstellung von 60 Sekunden. Wenn die Quelle oder das Ziel stark belastet ist oder Sperren in den Tabellen vorhanden sind, kann AWS DMS die Ausführung dieser Befehle nicht innerhalb von 60 Sekunden beenden. Die Aufgabe schlägt also mit der Fehlermeldung „canceling statement due to statement timeout“ fehl und Sie sehen einen dieser Einträge im Protokoll:
Nachrichten:
„]E: RetCode: SQL_ERROR SqlState: 57014 NativeError: 1 Message: ERROR: canceling statement due to statement timeout; Error while executing the query [1022502] (ar_odbc_stmt.c:2738)“
„]E: test_decoding_create_replication_slot(...) - Unable to create slot 'lrcyli7hfxcwkair_00016402_8917165c_29f0_4070_97dd_26e78336e01b' (on execute(...) phase) [1022506] (postgres_test_decoding.c:392))“
Gehen Sie wie folgt vor, um diese Fehler zu beheben:
- Identifizieren Sie die Ursache für lange Laufzeiten von Befehlen.
- Erhöhen Sie den Timeout-Wert und überprüfen Sie den Timeout-Wert für die Slot-Erstellung.
- Beheben Sie Probleme bei der Erstellung von Slots.
Lösung
Die Ursache für lange Laufzeiten von Befehlen identifizieren
Um den Befehl zu finden, der während des Timeouts nicht ausgeführt werden konnte, überprüfen Sie das AWS-DMS-Aufgabenprotokoll und den Abschnitt mit den Tabellenstatistiken der Aufgabe. Sie finden diese Informationen auch in der PostgreSQL-Fehlerprotokolldatei, wenn der Parameter log_min_error_statement auf ERROR oder einen niedrigeren Schweregrad gesetzt ist. Nachdem Sie den fehlgeschlagenen Befehl identifiziert haben, können Sie die fehlgeschlagenen Tabellennamen finden. Sehen Sie sich diese Beispielfehlermeldung aus dem PostgreSQL-Fehlerprotokoll an:
ERROR: canceling statement due to statement timeout STATEMENT: <The statement executed>"
Um Sperren in den zugehörigen Tabellen zu finden, führen Sie diesen Befehl in der Quelle oder im Ziel aus (je nachdem, wo der Fehler auftritt):
SELECT blocked_locks.pid AS blocked_pid, blocked_activity.usename AS blocked_user, blocking_locks.pid AS blocking_pid, blocking_activity.usename AS blocking_user, blocked_activity.query AS blocked_statement, blocking_activity.query AS current_statement_in_blocking_process FROM pg_catalog.pg_locks blocked_locks JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid JOIN pg_catalog.pg_locks blocking_locks ON blocking_locks.locktype = blocked_locks.locktype AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid AND blocking_locks.pid != blocked_locks.pid JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid WHERE NOT blocked_locks.GRANTED;
Wenn Sie blockierte PIDs finden, halten Sie die blockierte PID an oder beenden Sie sie, indem Sie diesen Befehl ausführen:
SELECT pg_terminate_backend(blocking_pid);
Da tote Zeilen oder „Tupel“ die SELECT-Zeit erhöhen können, suchen Sie in den Quelltabellen nach einer großen Anzahl toter Zeilen, indem Sie diesen Befehl ausführen:
select * from pg_stat_user_tables where relname= 'table_name';
Prüfen Sie, ob die fehlgeschlagene Zieltabelle Primärschlüssel oder eindeutige Indizes enthält. Wenn die Tabelle keine Primärschlüssel oder eindeutigen Indizes enthält, wird während der Ausführung einer UPDATE-Anweisung ein vollständiger Tabellenscan durchgeführt. Dieser Tabellenscan kann sehr lange dauern.
Den Timeout-Wert erhöhen
AWS DMS verwendet das zusätzliche Verbindungsattribut executeTimeout sowohl auf dem Quell- als auch auf dem Zielendpunkt. Der Standardwert für executeTimeout ist 60 Sekunden, sodass AWS DMS ein Timeout durchführt, wenn die Ausführung einer Abfrage länger als 60 Sekunden dauert.
Wenn der Fehler bei Source_Unload oder Source_Capture auftritt, legen Sie den Timeout-Wert für executeTimeout in der Quelle fest. Wenn der Fehler bei Target_Load oder Target_Apply auftritt, legen Sie den Timeout-Wert für executeTimeout im Ziel fest. Erhöhen Sie die Einstellung für den Timeout-Wert, indem Sie die folgenden Schritte ausführen:
1.Öffnen Sie die AWS-DMS-Konsole.
2.Wählen Sie im Navigationsbereich Endpunkte aus.
3.Wählen Sie den PostgreSQL-Endpunkt aus.
4.Wählen Sie Aktionen und anschließend Ändern aus.
5.Erweitern Sie den Abschnitt Endpunktspezifische Einstellungen.
6.Geben Sie in das Feld für Zusätzliche Verbindungsattribute den folgenden Wert ein:
executeTimeout=3600;
7.Wählen Sie Speichern aus.
8.Wählen Sie im Bereich Endpunkte den Namen Ihres PostgreSQL-Endpunkts aus.
9.Im Abschnitt Verbindungen ändert sich der Status des Endpunkts von Testing zu Successful.
Sie können den Parameter statement_timeout in der PostgreSQL-DB-Instance erhöhen (in Millisekunden). Der Standardwert ist 0, wodurch Timeouts für sämtliche Abfragen deaktiviert werden. Sie können ebenfalls den Parameter lock_timeout erhöhen. Der Standardwert ist 0, wodurch Timeouts für Sperren deaktiviert werden.
Probleme bei der Slot-Erstellung beheben
Wenn das Timeout aufgetreten ist, als Sie den Replikationsslot in der PostgreSQL-Datenbank erstellt haben, werden Protokolleinträge angezeigt, die den folgenden ähneln:
Nachrichten
]E: test_decoding_create_replication_slot(...) - Unable to create slot 'lrcyli7hfxcwkair_00016402_8917165c_29f0_4070_97dd_26e78336e01b' (on execute(...) phase) [1022506] (postgres_test_decoding.c:392)“
Sie können dieses Timeout erhöhen, indem Sie den Parameter TransactionConsistencyTimeout im Abschnitt Aufgabeneinstellungen konfigurieren. Der Standardwert ist 600 Sekunden.
PostgreSQL kann den Replikationsslot nicht erstellen, wenn die Datenbank-Benutzertabellen aktive Sperren enthalten. Überprüfen Sie, ob Sperren vorhanden sind, indem Sie diesen Befehl ausführen:
select * from pg_locks;
Führen Sie anschließend, um zu testen, ob der Fehler behoben wurde, diesen Befehl aus, um den Replikationsslot in der PostgreSQL-Quelldatenbank manuell zu erstellen:
select xlog_position FROM pg_create_logical_replication_slot('<Slot name as per the task log>', 'test_decoding');
Wenn der Befehl den Slot immer noch nicht erstellen kann, müssen Sie möglicherweise mit einem PostgreSQL-DBA arbeiten, um den Engpass zu identifizieren und Ihre Datenbank zu konfigurieren. Wenn der Befehl erfolgreich ist, löschen Sie den Slot, den Sie gerade zu Testzwecken erstellt haben:
select pg_drop_replication_slot(‘<slot name>');
Starten Sie abschließend Ihre Migrationsaufgabe neu.
Ähnliche Informationen
PostgreSQL-Dokumentation zu Standardeinstellungen für Client-Verbindungen
Zusätzliche Verbindungsattribute bei Verwendung von PostgreSQL als Ziel für AWS DMS
Zusätzliche Verbindungsattribute bei Verwendung von PostgreSQL als DMS-Quelle
Ähnliche Videos
Relevanter Inhalt
- AWS OFFICIALAktualisiert vor 2 Jahren
- AWS OFFICIALAktualisiert vor 3 Jahren