1. ホーム
  2. postgresql

[解決済み] ハングしたクエリ(トランザクション中のアイドル状態)を終了させる。

2022-10-01 22:35:33

質問

私はHerokuをCrane Postgresオプションで使用しており、私のローカルマシンからデータベース上でクエリを実行していたところ、私のローカルマシンがクラッシュしました。私が実行する場合

select * from pg_stat_activity

のうち、1つは

<IDLE> in transaction

をcurrent_query_textカラムに追加します。

その結果、終了したクエリによって書き込まれていたテーブルを削除することができません。pg_cancel_backend(N) を使用してみましたが、それは True を返しますが、何も起こらないようです。

テーブルを削除できるように、どのようにこのプロセスを終了させることができますか。

どのように解決するのですか?

これは一般的な Postgres の回答であり、heroku に固有のものではありません。


(この質問に対する単純で愚かな答えは、...ただ postgresql を再起動することです。 それが望ましくない、またはオプションでないと仮定すると...)

このSQLを実行してPIDを見つけます。

SELECT pid , query, * from pg_stat_activity
  WHERE state != 'idle' ORDER BY xact_start;

(このクエリはpostgresのバージョンによって修正が必要かもしれません - 最終的には、単にselect * from pg_stat_activityとします). 最初の(左の)列にpidがあり、最初の(上の)行に終了させたいクエリがあると思われます。 以下では、pidが1234であると仮定します。

自分のものであるか、スーパーユーザのアクセス権を持っている限り、SQLを通じて(つまりシェルアクセスなしで)クエリをキャンセルすることができます。

select pg_cancel_backend(1234);

これは 1234-query をキャンセルするための "friendly" リクエストで、運が良ければしばらくして消えます。 結局、この方が効率的なのです。

select pg_terminate_backend(1234);

シェルアクセスおよびrootまたはpostgres権限を持っている場合、シェルから行うこともできます。 キャンセルするには、以下のようにします。

kill -INT 1234

で、quot;terminate" に、簡単に。

kill 1234

しないでください。

kill -9 1234

...この場合、postgresサーバ全体が炎上してしまうことが多いので、postgresを再起動することをお勧めします。 Postgresはかなり堅牢なので、データが破損することはありませんが、どんな場合でも"kill -9"を使用しないことをお勧めします :-)。


長く続く "idle in transaction" は、多くの場合、トランザクションが "commit" または "rollback" で終了していないことを意味し、アプリケーションがバグであるか、トランザクション データベースを扱うように正しく設計されていないことを意味します。 トランザクション内のアイドル状態が長く続くと、パフォーマンス上の大きな問題を引き起こす可能性があるため、避ける必要があります。