112

Crane Postgres オプションで Heroku を使用しています。ローカル マシンがクラッシュしたときに、ローカル マシンからデータベースに対してクエリを実行していました。私が走れば

select * from pg_stat_activity

エントリの1つに

<IDLE> in transaction

current_query_text 列に。

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

テーブルを削除できるように、このプロセスを終了するにはどうすればよいですか?

4

3 に答える 3

161

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


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

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

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

(クエリはpostgresのバージョンに応じて修正する必要があるかもしれません-最終的にはpg_stat_activityから*を選択するだけです)。pidは最初の(左)列にあり、最初の(上の)行は終了したいクエリである可能性があります。pidは以下の1234であると仮定します。

SQLを介して(つまり、シェルアクセスなしで)クエリをキャンセルできるのは、それが自分のものであるか、スーパーユーザーアクセス権がある場合です。

select pg_cancel_backend(1234);

これは、1234クエリをキャンセルするための「友好的な」リクエストであり、運が良ければしばらくすると消えます。最終的に、これはより効率的です。

select pg_terminate_backend(1234);

シェルアクセスとrootまたはpostgres権限がある場合は、シェルからも実行できます。「キャンセル」するには、次のことができます。

kill -INT 1234

そして「終了」するには、単純に:

kill 1234

しない:

kill -9 1234

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


長期にわたる「トランザクションのアイドル」は、多くの場合、トランザクションが「コミット」または「ロールバック」で終了しなかったことを意味します。つまり、アプリケーションにバグがあるか、トランザクションデータベースで動作するように適切に設計されていません。長期にわたる「トランザクションのアイドル」は、パフォーマンスに大きな問題を引き起こす可能性があるため、避ける必要があります。

于 2012-07-02T10:46:33.650 に答える