Crane PostgresオプションでHerokuを使用しており、ローカルマシンがクラッシュしたときにローカルマシンからデータベースに対してクエリを実行していました。走ったら
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の古いバージョンはpidではなくprocpidを使用します)。最初(左)の列にpidがあり、最初(上)の行はおそらく終了したいクエリです。以下ではpidが1234であると仮定します。
クエリが自分のものであるか、スーパーユーザーアクセスがある場合は、SQLを介して(シェルアクセスなしで)クエリをキャンセルできます。
select pg_cancel_backend(1234);
これは「ソフト」な方法です...クエリはすぐに消えません。それがうまくいかない場合は、代わりにこれを使用してください:
select pg_terminate_backend(1234);
シェルアクセスとrootまたはpostgresのアクセス許可がある場合は、シェルからも実行できます。
kill -INT 1234
それでも解決しない場合は、次を使用します。
kill 1234
しない:
kill -9 1234
...これにより、postgresサーバー全体が炎上してしまうことがよくありますが、postgresを再起動することもできます。 Postgresは非常に堅牢であるため、データは破損しませんが、いずれにしても「kill -9」を使用しないことをお勧めします:-)
長期にわたる「トランザクションのアイドル」とは、多くの場合、トランザクションが「コミット」または「ロールバック」で終了しなかったことを意味します。これは、アプリケーションがバグがあるか、トランザクションデータベースで動作するように適切に設計されていないことを意味します長期にわたる「トランザクションのアイドル」は、重大なパフォーマンスの問題を引き起こす可能性があるため、避ける必要があります。
これを試して:
select pg_terminate_backend(pid int)
これについての詳細は こちら をご覧ください。これは、システムごとにプロセスを強制終了するよりも、この問題の「クリーンな」解決策です。
heroku-pg-extras
アドオンで、次のコマンドを実行してPIDを取得します。
heroku pg:locks --app <your-app>
それからちょうど:
heroku pg:kill <pid> --app <your-app>
[〜#〜] note [〜#〜]:--force
オプションを使用すると、そのクエリの接続全体をドロップするpg_terminate_backendを発行できます。
heroku pg:locks
は何もリストしません。heroku pg:ps
。
詳細については、チェックアウトしてください。
https://devcenter.heroku.com/articles/heroku-postgresql#pg-ps-pg-kill-pg-killall
次を使用して、1つのクエリでそれを実現できます。
SELECT pg_cancel_backend(pid), pg_terminate_backend(pid) FROM pg_stat_activity WHERE state != 'idle';