「ERROR: canceling statement due the statement timeout」(エラー: ステートメントのタイムアウトにより、ステートメントをキャンセルしています) というエラーメッセージが表示される、失敗した AWS DMS タスクをトラブルシューティングするにはどうすればよいですか?
AWS Database Migration Service (AWS DMS) を使用して、オンプレミスの PostgreSQL データベースとの間でデータを移行しています。AWS DMS タスクはしばらくの間正常に実行されますが、それからエラーで失敗します。このエラーをトラブルシューティングして解決するにはどうすればよいですか?
簡単な説明
PostgreSQL データベースが移行タスクのソースである場合、AWS DMS はフルロードフェーズでテーブルからデータを取得します。その後、AWS DMS は、変更データキャプチャ (CDC) フェーズで、レプリケーションスロットによって保持されている先書きログ (WAL) から読み取ります。
PostgreSQL データベースがターゲットである場合、AWS DMS はソースからデータを取得し、レプリケーションインスタンスに CSV ファイルを作成します。その後、AWS DMS はフルロードフェーズで COPY コマンドを実行し、それらのレコードをターゲットに挿入します。
ただし、トランザクション適用モードでは、AWS DMS は CDC フェーズでソースの WAL ログから正確な DML ステートメントを実行します。バッチ適用モードの場合、AWS DMS は CDC フェーズ中に CSV ファイルも作成します。その後、COPY コマンドを実行して正味の変更をターゲットに挿入します。
AWS DMS がソースからデータを取得するか、ターゲットにデータを配置することを試みる場合、デフォルトのタイムアウト設定である 60 秒が使用されます。ソースまたはターゲットが高負荷であるか、テーブルにロックがある場合には、AWS DMS は 60 秒以内にこれらのコマンドの実行を終了できません。そのため、タスクは失敗して、「canceling statement due to statement timeout」(ステートメントのタイムアウトにより、ステートメントをキャンセルしています) というエラーになり、ログに次のいずれかのエントリが表示されます。
メッセージ:
「]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: 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))」(]E: test_decoding_create_replication_slot(...) - (実行(...) フェーズで)「lrcyli7hfxcwkair_00016402_8917165c_29f0_4070_97dd_26e78336e01b」のスロットを作成できませんでした [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_Unload または Source_Capture に表示される場合は、ソースの executeTimeout のタイムアウト値を設定します。エラーが Target_Load または Target_Apply に表示される場合は、ターゲットの executeTimeout のタイムアウト値を設定します。次のステップに従って、タイムアウト値の設定を増やします。
1. AWS DMS コンソールを開きます。
2. ナビゲーションペインから [Endpoints] (エンドポイント) を選択します。
3. PostgreSQL エンドポイントを選択します。
4. [Actions (アクション)] を選択し、[Modify (変更)] を選択します。
5. [Endpoint-specific settings] セクションを展開します。
6. [Extra connection attributes] (追加の接続属性) のフィールドに、次の値を入力します。
executeTimeout=3600;
7. [Save] (保存) を選択します。
8. [Endpoints (エンドポイント)] ペインで、PostgreSQL エンドポイントの名前を選択します。
9. [Connections] (接続) セクションで、エンドポイントの [Status] (ステータス) が [Testing] (テスト中) から [Successful] (成功) に変わります。
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)」(]E: test_decoding_create_replication_slot(...) - (実行(...) フェーズで)「lrcyli7hfxcwkair_00016402_8917165c_29f0_4070_97dd_26e78336e01b」のスロットを作成できませんでした [1022506] (postgres_test_decoding.c:392))
このタイムアウトは、[Task settings] (タスク設定) セクションの 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 のドキュメント
AWS DMS のターゲットとして PostgreSQL を使用する場合の追加の接続属性
DMS ソースとして PostgreSQL を使用する場合の追加の接続属性
Using a PostgreSQL database as an AWS DMS source (AWS DMS のソースとしての PostgreSQL データベースの使用)
関連するコンテンツ
- 質問済み 11日前lg...
- 質問済み 2ヶ月前lg...
- AWS公式更新しました 1年前
- AWS公式更新しました 7ヶ月前