PostgreSQLハングクエリを強制終了/終了する方法
今日、私はSQLクエリの1つがPostgreSQLでハングしており、それ自体をリリースしないことを発見しました。 「クエリのキャンセル」コマンドは役に立ちません。クエリはそこにぶら下がって「idle in transaction」ステータスを表示します。 私には選択の余地がありませんでしたが、Debianターミナルに行き、「kill」コマンドを発行して手動で終了しました。
PostgreSQLでクエリがハングまたは応答しないのは、Webアプリケーションでトランザクションマネージャーを適切に処理しなかったためです。 システムが誤ってシャットダウンすると、実行中のクエリがPostgreSQLでハングし、トランザクションマネージャー(DataSourceTransactionManager
など)が進行中のトランザクションをロールバックできなくなります。
Note
トランザクションマネージャーをJtaTransactionManager
に変更した後、システムが誤ってシャットダウンされた場合でも、Webアプリケーションは進行中のトランザクションを強制終了できます。
ただし、ここでは、ハングするSQLクエリを終了する方法を示します。 PostgreSQLでは、ハングしているクエリはすべて「idle in transaction」と表示されます。 まず、既存のすべてのPostgreSQLプロセスをリストし、kill terminateコマンドを発行して、ハングしているクエリを手動で終了する必要があります。
1. すべてのプロセスをリストする
「ps -ef | grep postgres
」コマンドを発行して、postgresユーザーに属するすべての既存のプロセスを一覧表示します。
example:~# ps -ef | grep postgres postgres 13648 1 0 11:04 ? 00:00:00 /var/lib/postgresql/PostgresPlus8.3xxxxxxx postgres 13651 13648 0 11:04 ? 00:00:00 postgres: logger process postgres 13653 13648 0 11:04 ? 00:00:00 postgres: writer process postgres 13654 13648 0 11:04 ? 00:00:00 postgres: wal writer process postgres 13655 13648 0 11:04 ? 00:00:00 postgres: autovacuum launcher process postgres 13656 13648 0 11:04 ? 00:00:00 postgres: stats collector process postgres 13668 13648 0 11:04 ? 00:00:00 postgres: postgres postgres 10.70.1.27(3734) idle postgres 13689 13648 0 11:05 ? 00:00:00 postgres: usrdba db_test 10.70.1.67(4164) idle postgres 13714 13648 0 11:06 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57586) idle in transaction postgres 13721 13648 0 11:06 ? 00:00:16 postgres: usrdba db_test 10.70.1.67(4165) idle postgres 13832 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57592) idle postgres 13833 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57593) idle postgres 13834 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57594) idle postgres 13835 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57595) idle postgres 13836 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57596) idle postgres 14201 13648 0 11:23 ? 00:00:00 postgres: nrsdba postgres 10.70.1.8(4419) idle postgres 14202 13648 0 11:23 ? 00:00:00 postgres: usrdba db_test 10.70.1.8(4420) idle postgres 14207 13648 0 11:24 ? 00:00:00 postgres: usrdba db_test 10.70.1.8(4421) idle root 18030 17992 0 13:46 pts/0 00:00:00 grep postgres example:~#
2. アイドル状態のトランザクションを見つける+キルする
プロセスID「13714, idle in transaction」に注意してください。これはPostgreSQLでハングしているクエリです。 「kill」コマンドを発行して、PostgreSQLプロセスを手動で終了します。
example:~# kill 13714
or
example:~# kill -TERM 13714
or
example:~# kill -15 13714
3. 殺された! 完了しました。
ハングしたクエリはなくなりました!
example:~# ps -ef | grep postgres postgres 13648 1 0 11:04 ? 00:00:00 /var/lib/postgresql/PostgresPlus8.3xxxxxxx postgres 13651 13648 0 11:04 ? 00:00:00 postgres: logger process postgres 13653 13648 0 11:04 ? 00:00:00 postgres: writer process postgres 13654 13648 0 11:04 ? 00:00:00 postgres: wal writer process postgres 13655 13648 0 11:04 ? 00:00:00 postgres: autovacuum launcher process postgres 13656 13648 0 11:04 ? 00:00:00 postgres: stats collector process postgres 13668 13648 0 11:04 ? 00:00:00 postgres: postgres postgres 10.70.1.27(3734) idle postgres 13689 13648 0 11:05 ? 00:00:00 postgres: usrdba db_test 10.70.1.67(4164) idle postgres 13721 13648 0 11:06 ? 00:00:16 postgres: usrdba db_test 10.70.1.67(4165) idle postgres 13832 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57592) idle postgres 13833 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57593) idle postgres 13834 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57594) idle postgres 13835 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57595) idle postgres 13836 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57596) idle postgres 14201 13648 0 11:23 ? 00:00:00 postgres: nrsdba postgres 10.70.1.8(4419) idle postgres 14202 13648 0 11:23 ? 00:00:00 postgres: usrdba db_test 10.70.1.8(4420) idle postgres 14207 13648 0 11:24 ? 00:00:00 postgres: usrdba db_test 10.70.1.8(4421) idle root 18030 17992 0 13:46 pts/0 00:00:00 grep postgres example:~#