如何疑難排解失敗並顯示錯誤訊息「錯誤:因陳述式逾時而取消陳述式」的 AWS DMS 任務?

3 分的閱讀內容
0

我正在使用 AWS Database Migration Service (AWS DMS) 將資料遷移至內部部署的 PostgreSQL 資料庫或從該處將資料遷移出來。AWS DMS 任務會正常執行一段時間,然後任務失敗並顯示錯誤。如何疑難排解和解決這些錯誤?

簡短說明

如果 PostgreSQL 資料庫是遷移任務的來源,則 AWS DMS 會在完整載入階段從表格取得資料。然後,在變更資料擷取 (CDC) 階段期間,AWS DMS 會從複寫插槽所保留的預寫日誌 (WAL) 讀取。

如果 PostgreSQL 資料庫為目標,則 AWS DMS 會從來源取得資料,並在複寫執行個體中建立 CSV 檔案。然後,AWS DMS 會執行 COPY 命令,在滿載階段期間將這些記錄插入目標。

但是,在 CDC 階段期間,AWS DMS 會在交易式套用模式下從來源 WAL 日誌執行精確的 DML 陳述式。針對批次套用模式,AWS DMS 也會在 CDC 階段期間建立 CSV 檔案。然後,它會執行 COPY 命令,將網路變更插入目標。

當 AWS DMS 嘗試從來源取得資料或將資料放入目標時,即會使用預設逾時設定 60 秒。如果來源或目標負載過重或表格中有鎖定,則 AWS DMS 無法在 60 秒內完成執行這些命令。因此,任務失敗並顯示「由於陳述式逾時而取消陳述式」的錯誤,而且您會在日誌中看到下列其中一項:

訊息:

「]E: RetCode: SQL_ERROR SqlState: 57014 NativeError: 1 則訊息: 錯誤:由於陳述式逾時而取消陳述式;執行查詢時發生錯誤 [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))」

若要疑難排解並解決這些錯誤,請遵循下列步驟:

  • 確定命令長時間執行的原因。
  • 增加逾時值並檢查插槽建立逾時值。
  • 疑難排解插槽建立問題。

解決方案

確定命令長時間執行的原因

若要尋找逾時期間執行失敗的命令,請檢閱 AWS DMS 任務日誌和任務的表格統計資料區段。如果參數 log_min_error_statement 設為 ERROR 或較低的嚴重性,您也可以在 PostgreSQL 錯誤日誌中找到此資訊。識別失敗的命令後,您可以找到失敗的表格名稱。請參閱 PostgreSQL 錯誤日誌中的此範例錯誤訊息:

ERROR: canceling statement due to statement timeout
STATEMENT: <The statement executed>"

若要尋找相關聯表格上的鎖定,請在來源或目標中執行此命令 (視錯誤出現的位置而定):

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;

如果您發現任何遭封鎖的 PID,請透過執行以下命令停止或終止封鎖的 PID:

SELECT pg_terminate_backend(blocking_pid);

因為無效資料列或「元組」可能會增加 SELECT 時間,請執行此命令來檢查來源表格中是否有大量的無效資料列:

select * from pg_stat_user_tables where relname= 'table_name';

檢查失敗的目標表格是否有主索引鍵或唯一索引。如果表格沒有主索引鍵或唯一索引,則會在執行任何 UPDATE 陳述式期間執行完整表格掃描。此表格掃描可能需要很長時間。

增加逾時值

AWS DMS 會在來源端點和目標端點中使用 executeTimeout 額外連線屬性。executeTimeout 的預設值為 60 秒,因此如果查詢執行時間超過 60 秒,AWS DMS 即會逾時。

如果在 Source_UnloadSource_Capture 中出現錯誤,則請在來源中設定 executeTimeout 的逾時值。如果錯誤出現在 Target_LoadTarget_Apply 中,請在目標中設定 executeTimeout 的逾時值。遵循下列步驟增加逾時值設定:

1.    開啟 AWS DMS 主控台

2.    從導覽窗格中選取「端點」。

3.    選取 PostgreSQL 端點。

4.    選取「動作」,然後選取「修改」。

5.    展開「端點特定設定」區段。

6.    在「額外連線屬性」的欄位中,輸入此值:

executeTimeout=3600;

7.    選擇「儲存」。

8.    在「端點」窗格中,選擇 PostgreSQL 端點的名稱。

9.    在「連線」區段中,端點的「狀態」會從「測試」變更為「成功」。

您可以增加 PostgreSQL DB 執行個體中的 statement_timeout 參數 (以毫秒為單位)。預設值為 0,這會關閉任何查詢的逾時。您也可以增加 lock_timeout 參數。預設值為 0,這會關閉鎖定的逾時。

疑難排解插槽建立問題

如果在 PostgreSQL 資料庫中建立複寫插槽時發生逾時,您會看到類似下列內容的日誌項目:

訊息

「]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)」

您可以在「任務設定」區段中設定 TransactionConsistencyTimeout參數,以增加此逾時。預設值為 600 秒。

如果資料庫使用者表格中有任何作用中的鎖定,PostgreSQL 即無法建立複寫插槽。執行此命令以檢查鎖定:

select * from pg_locks;

然後,若要測試錯誤是否已解決,請執行此命令,在來源 PostgreSQL 資料庫中手動建立複寫插槽:

select  xlog_position FROM pg_create_logical_replication_slot('<Slot name as per
    the task log>', 'test_decoding');

如果該命令仍然無法建立插槽,則您可能需要使用 PostgreSQL DBA 來識別瓶頸並設定資料庫。如果命令成功,請刪除剛建立作為測試的插槽:

select pg_drop_replication_slot(‘<slot name>');

最後,重新啟動遷移任務。


相關資訊

用戶端連線預設值的 PostgreSQL 文件

使用 PostgreSQL 作為 AWS DMS 目標時的額外連線屬性

使用 PostgreSQL 作為 DMS 來源時的額外連線屬性

使用 PostgreSQL 資料庫作為 AWS DMS 來源

AWS 官方
AWS 官方已更新 2 年前