Amazon Relational Database Service (Amazon RDS) for PostgreSQL または Amazon Aurora PostgreSQL 互換エディションデータベース (DB) インスタンスで長時間実行中のプロセスを終了したいです。
簡単な説明
ユースケースに応じて、pg_cancel_backend(pid) または pg_terminate_backend(pid) 関数のいずれかを使用できます。
pg_cancel_backend(pid) 関数を使用すると、SIGINT シグナルが特定のバックエンドプロセスに送信され、現在の長時間実行されているクエリがキャンセルされます。このプロセスの間、データベースへの接続はアクティブな状態が維持されます。バックエンドは、関数が現在のクエリを正常に終了した後も、他のクエリまたはトランザクションの処理を継続できます。
pg_terminate_backend(pid) 関数を使用すると、クエリが終了して接続が閉じます。この関数を使用して、SIGTERM シグナルを特定のバックエンドプロセスに送信し、そのプロセスに関連付けられている接続を強制的に終了します。このプロセスは、接続内のオープントランザクションまたは保留中のロックをロールバックして解放します。
詳細については、PostgreSQL のウェブサイトで「Server signaling functions」(サーバーシグナリング関数) を参照してください。
注: Aurora PostgreSQL 互換バージョンの中には、すべてのシステム要件を満たしていても、自動バキュームプロセスを終了できないものがあります。これらのバージョンで自動バキュームプロセスを終了しようとすると、次のエラーメッセージが表示される場合があります。
"ERROR: 42501: must be a superuser to terminate superuser process LOCATION: pg_terminate_backend, signalfuncs.c:227."
一部のマイナーバージョンでは、rds_superuser により、ロールに明示的に関連付けられていない自動バキュームプロセスを終了させることができます。お使いのバージョンで rds_superuser が自動バキュームプロセスを終了できるかどうかを確認するには、「Amazon Aurora PostgreSQL updates」(Amazon Aurora PostgreSQL の更新) を参照してください。
解決策
pg_cancel_backend(pid) または pg_terminate_backend(pid) を使用するには、以下のいずれかのユーザーである必要があります。
- rds_superuser または、デフォルトロール pg_signal_backend のメンバーである。
- キャンセルするセッションと同じデータベースユーザーとしてデータベースに接続している。
長時間実行されているクエリを終了するには、トランザクションのプロセス ID (PID) が必要です。PID を特定するには、pg_stat_activity クエリを実行して pid 列を確認してください。詳細については、PostgreSQL のウェブサイトで「pg_stat_activity」を参照してください。
pg_cancel_backend(pid) 関数を使用する
別のセッションから次のコマンドを実行すると、関数は長時間実行されているクエリの PID を使用して、データベースバックエンドからのクエリをキャンセルします。
SELECT pg_cancel_backend(8121);
注: 前述のコマンドにおけるクエリの PID は 8121 です。
想定される出力:
pg_cancel_backend
------------------------
t
前述の出力では、"true" を示す t 値は、関数がクエリをキャンセルしたことを示しています。クエリが存在しない場合、またはアクティブなデータベース接続がない場合、出力には "false" を示す f 値が表示されます。
pg_terminate_backend(pid) 関数を使用する
別のセッションから次のコマンドを実行すると、この関数は pid 8121 のデータベース接続を終了します。
SELECT pg_terminate_backend(8121);
想定される出力:
pg_terminate_backend
------------------------
t
前述の出力では、関数がクエリをキャンセルしなかった場合でも t が表示されます。このレスポンスは、関数が SIGTERM シグナルを正常に送信したことを示しています。この関数はバックエンドプロセスをすぐには中断しません。共有メモリを一貫した状態に保つため、このコマンドは CHECK_FOR_INTERRUPTS 中に正常なシャットダウンプロセスを開始します。
終了しないで長時間実行しているプロセスをキャンセルする
中断可能なセクションで pg_cancel_backend(pid) または pg_terminate_backend(pid) を実行すると、関数はクエリをキャンセルできません。例えば、プロセスが軽量ロックを取得しようとしているとします。または、プロセスがストレージからの読み取りまたは書き込みシステムコールの完了を待機しているとします。このような場合、バックエンドプロセスはキャンセルシグナルを受信せず、プロセスは無期限に停滞します。
プロセスがキャンセル方法に応答しない場合は、データベースエンジン全体を再起動し、停滞したプロセスを強制終了します。
PostgreSQL バージョン 14 以降では、statement_timeout、idle_in_transaction_session_timeout、idle_session_timeout などのタイムアウトパラメータを調整することがベストプラクティスです。tcp_keepalives_idle、tcp_keepalives_interval、tcp_keepalives_count などのクライアント側およびサーバー側のタイムアウトを設定することもベストプラクティスです。
注: これらのタイムアウトパラメータは動的であるため、変更を反映させるためにデータベースを再起動する必要はありません。
要件に基づいてパラメータを設定します。例えば、次のレベルでパラメータを設定できます。
- 特定のクエリに対する個別のステートメントレベル
- 特定のユーザーからのすべてのクエリに対するユーザーレベル
- データベース全体の動作を制御するためのデータベースレベル
- グローバル設定を確立するためのインスタンスパラメータグループレベル
注: タイムアウトを短くすると、意図的に長時間実行させているクエリがキャンセルされるため、インスタンスまたはデータベースレベルで短いタイムアウトを設定しないでください。log_min_error_statement を ERROR 以下に設定した場合、Amazon RDS はタイムアウトしたステートメントをログに記録します。詳細については、PostgreSQL のウェブサイトで「Statement behavior」(ステートメントの動作) を参照してください。
関連情報
Amazon RDS for PostgreSQL または Aurora PostgreSQL DB インスタンスの実行中のクエリを確認し、リソース消費の問題を診断する方法を教えてください
Amazon RDS for PostgreSQL または Aurora PostgreSQL 互換 DB インスタンスで、パフォーマンスの問題や実行速度が遅いクエリを特定してトラブルシューティングする方法を教えてください