web-dev-qa-db-ja.com

kill -9 postgresプロセス

Postgres SELECTクエリがDBサーバーで制御不能になり、サーバーがメモリ不足になるまで大量のメモリとスワップを消費し始めました。特定のプロセスをps aux | grep postgresで見つけ、kill -9 pidを実行しました。これによりプロセスが強制終了され、メモリが予想どおりに解放されました。システムとpostgresの残りのクエリは影響を受けないようです。このサーバーは、SLES 9 SP4でpostgres 9.1.3を実行しています。

しかし、私たちの開発者の1人がkill -9を使用してpostgresプロセスを強制終了したことで、postgresサービス全体がダウンすると言って私をかき立てました。実際にはそうではありませんでした。私はこれをほんの一握りの時間の前に行ったことがあり、悪影響は見ていません。

そうは言っても、さらに読むと、フラグのないkill pidは暴走するpostgresプロセスを強制終了するための好ましい方法のようですが、postgresコミュニティの他のユーザーによると、postgresが「良くなった」ように思えます長年にわたって、個々のクエリプロセス/スレッドのkill -9がもはや死刑判決ではなくなりました。

誰かが暴走したpostgresプロセスを強制終了する適切な方法と、最近のPostgresでのkill -9の使用がどれほど悲惨(または無害)かを教えてくれますか?洞察をありがとう。

25
Banjer

voretaq7answer は、 バックエンドを終了する正しい方法 を含む重要な点をカバーしていますが、もう少し説明を追加したいと思います。

_kill -9_(つまり、SIGKILL)が、最初の選択肢のデフォルトになることは決してありません。プロセスが通常のシャットダウン要求に応答せず、SIGTERM(_kill -15_)が効果を発揮しない場合は、これが最後の手段です。それはPgと他のほとんどすべてに当てはまります。

_kill -9_は、強制終了されたプロセスにクリーンアップを実行する機会をまったく与えません。

PostgreSQLに関しては、Pgは、_kill -9_で終了するバックアップを、クラッシュしたクラッシュとして認識します。バックエンドが共有メモリを破損している可能性があることを認識しています。たとえば、ページをshmに書き込んだり、ページを変更したりして途中で中断した可能性があるため、他のすべてのバックエンドを終了して再起動しますバックエンドが突然消えてゼロ以外のエラーコードで終了したことに気づいたとき。

これはログで報告されます。

Pgがクラッシュ後にすべてを再起動しており、アプリケーションが失われた接続から完全に回復しているため、害が無いように見えます。それは良い考えにはなりません。バックエンドクラッシュのテストがPgの正常に機能する部分ほど十分にテストされておらず、はるかに複雑/変化している場合、バックエンドクラッシュの処理と回復に潜むバグの可能性が高くなります。

ところで、ポストマスターが_kill -9_した場合、_postmaster.pid_を削除し、postgresバックエンドがすべて削除されていることを確認せずに再起動します非常に悪いことが起こります。これは、バックエンドの代わりにポストマスターを誤って終了し、データベースがダウンしたことを確認し、再起動しようとし、再起動が失敗したときに「古い」.pidファイルを削除して、再起動しようとした場合に簡単に発生します。これが、Pgの周りで_kill -9_を振るのを避け、_postmaster.pid_を削除してはならない理由の1つです。

デモンストレーション:

バックエンドを_kill -9_するとどうなるかを正確に確認するには、次の簡単な手順を試してください。 2つのターミナルを開き、それぞれでpsqlを開き、それぞれでSELECT pg_backend_pid();を実行します。別の端末で_kill -9_ PIDの1つ。次に、両方のpsqlセッションでSELECT pg_backend_pid();を再度実行します。彼ら両方が接続を失ったことに注意してください。

私たちが殺したセッション1:

_$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6357
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6463
(1 row)
_

セッション2、これは付随的な損傷でした。

_$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6283
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
WARNING:  terminating connection because of crash of another server process
DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT:  In a moment you should be able to reconnect to the database and repeat your command.
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6464
(1 row)
_

両方のセッションがどのように壊れたかを確認しますか?そのため、バックエンドを_kill -9_しないでください。

31
Craig Ringer

_I found the particular process via ps aux | grep postgres and ran kill -9 pid._
番号!悪い!バックエンドから一歩離れて!

真剣に-Postgresバックエンドをそのように殺さないでください-ひどいことが起こり(7.x日以降に行われたすべての安定性の強化があっても)、DB全体を破壊する可能性があり、開発者は噛む権利がありますあなたはこれをやってくれました。

実際には Postgres内からこれを行うための祝福され承認された方法 - Postgresマニュアル にもありますSO =投稿はそれを説明するより良い仕事をします...

SELECT pg_cancel_backend(pid)
キャンセル(SIGINT)シグナルを指定されたバックエンドに送信し、現在実行中のクエリをキャンセルします。

select pg_terminate_backend(pid)
終了(SIGTERM)シグナルを指定されたバックエンドに送信します。これにより、クエリがキャンセルされ、バックエンドが中止されます(接続が切断されます)。

バックエンドIDは_pg_stat_activity_テーブル(またはps)から取得できます

29
voretaq7

PostgreSQLクライアントプロセスを強制終了しても問題ありません。 PostgreSQLデーモンプロセスを強制終了すると、怒られる可能性があります。

SQLデーモンにも内部プロセス制御があるため、推奨される方法は、最初にそのチャネルを使用することです。

StackOverflowの PostgreSQLでのSQLクエリの実行の停止(長時間)... を参照してください。

8
Jeff Ferland