Ongoing service disruptions
For the most recent update on ongoing service disruptions affecting the AWS Middle East (UAE) Region (ME-CENTRAL-1), refer to the AWS Health Dashboard. For information on AWS Service migration, see How do I migrate my services to another region?
Amazon RDS PostgreSQL または Aurora PostgreSQL データベースインスタンスでクエリがブロックされている原因を特定する方法を教えてください。
Amazon Relational Database Service (Amazon RDS) の PostgreSQLまたは Amazon Aurora PostgreSQL データベースインスタンスでブロックされたクエリをトラブルシューティングしたいと考えています。
解決策
コミットされていないトランザクションでは、ロック待ちタイムアウトやステートメントのタイムアウトを超えると、新しいクエリがブロックされたり、スリープ状態になったり、失敗する可能性があります。この問題を解決するには、コミットされていないトランザクションを特定して停止します。
ブロックされたトランザクションを特定する
ブロックされたトランザクションを特定するには、Performance Insights を有効にして Database Insights を使用します。データベースロードチャートを使用して、Waits、Host、SQL、または User のデータベースロードディメンションを表示します。詳細については、「Amazon RDS で Performance Insights を使用して DB 負荷を監視する」を参照してください。
ブロックされたトランザクションの現在の状態を確認するには、次のステートメントを実行します。
SELECT * FROM pg_stat_activity WHERE query iLIKE '%TABLE NAME%' ORDER BY state;
注: TABLE NAME をテーブル名または条件に置き換えてください。
wait_event_type 列の値が Lock でない場合は、CPU、ストレージ、ネットワーク容量などのリソースにパフォーマンスのボトルネックがあります。パフォーマンスのボトルネックを解決するには、データベースのパフォーマンスを調整してください。例えば、インデックスを追加したり、クエリを書き換えたり、vacuum コマンドを実行したり、analyze コマンドを実行したりできます。詳細については、「PostgreSQL を使用する際のベストプラクティス」を参照してください。
wait_event_type 列の値が Lock の場合、他のトランザクションまたはクエリがそのクエリをブロックします。ブロックされたトランザクションの原因を特定するには、次のステートメントを実行します。
SELECT blocked_locks.pid AS blocked_pid, blocked_activity.usename AS blocked_user, blocked_activity.client_addr as blocked_client_addr, blocked_activity.client_hostname as blocked_client_hostname, blocked_activity.client_port as blocked_client_port, blocked_activity.application_name as blocked_application_name, blocked_activity.wait_event_type as blocked_wait_event_type, blocked_activity.wait_event as blocked_wait_event, blocked_activity.query AS blocked_statement, blocking_locks.pid AS blocking_pid, blocking_activity.usename AS blocking_user, blocking_activity.client_addr as blocking_user_addr, blocking_activity.client_hostname as blocking_client_hostname, blocking_activity.client_port as blocking_client_port, blocking_activity.application_name as blocking_application_name, blocking_activity.wait_event_type as blocking_wait_event_type, blocking_activity.wait_event as blocking_wait_event, 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 ORDER BY blocked_activity.pid;
どのセッションがトランザクションをブロックしているかを特定するには、blocking_user、blocking_user_addr、blocking_client_port を確認してください。次の出力例では、マスターユーザーが psql を使用して 27.0.3.146 ホストで実行されているトランザクションをブロックしています。blocking_pid は 8740 です。
blocked_pid | 9069blocked_user | master blocked_client_addr | 27.0.3.146 blocked_client_hostname | blocked_client_port | 50035 blocked_application_name | psql blocked_wait_event_type | Lock blocked_wait_event | transactionid blocked_statement | UPDATE test_tbl SET name = 'Jane Doe' WHERE id = 1; blocking_pid | 8740 blocking_user | master blocking_user_addr | 27.0.3.146 blocking_client_hostname | blocking_client_port | 26259 blocking_application_name | psql blocking_wait_event_type | Client blocking_wait_event | ClientRead current_statement_in_blocking_process | UPDATE tset_tbl SET name = 'John Doe' WHERE id = 1;
トランザクションを停止する
トランザクションを終了する前に、各トランザクションがデータベースとアプリケーションの状態に及ぼす潜在的な影響を評価してください。
トランザクションを停止するには、次のステートメントを実行します。
SELECT pg_terminate_backend(PID);
注: PID をトランザクションの blocking_pid に置き換えます。

