-9をpostgresプロセスで強制終了します


25

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

しかし、開発者の1人が、kill -9postgresサービス全体を停止させると言って、postgresプロセスを殺すことで私をかみ砕きました。実際にはそうではありませんでした。私はこれを数回前にやったことがあり、マイナスの副作用は見ていません。

そうは言っても、さらに読んだ後kill pid、暴走したpostgresプロセスを殺すにはフラグなしが好ましい方法のように見えますが、postgresコミュニティの他のユーザーごとに、postgresは長年にわたって「良くなった」ように聞こえますkill -9個々のクエリプロセス/スレッドでは、もはや死刑宣告ではありません。

誰かが暴走したpostgresプロセスを殺すための適切な方法と、kill -9最近のPostgresでの悲惨な(または良性の)使用がどのようになっているのかを教えてもらえますか?洞察力をありがとう。

回答:


31

voretaq7答えは、バックエンドを終了する正しい方法を含むキーポイントをカバーしていますが、もう少し説明を追加したいと思います。

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

kill -9 強制終了されたプロセスにクリーンアップを行う機会をまったく与えません。

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

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

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

ところで、kill -9ポストマスターがpostmaster.pidすべてのpostgresバックエンドがなくなっていることを確認せずに削除して再起動すると、非常に悪いことが起こる可能性があります。これは、バックエンドではなく誤ってポストマスターを強制終了し、データベースがダウンしたのを確認して再起動しようとし、再起動が失敗したときに「古い」.pidファイルを削除し、再起動しようとすると簡単に起こります。それが、kill -9Pg をあちこち振ることを避け、削除すべきではない理由の1つですpostmaster.pid

デモ:

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

私たちが殺したセッション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バックエンドではない理由です。


1
ここですべての非常に良い答え、そして私は追加するかもしれない非常に謙虚です。それらすべてを承認済みとしてマークすることもできますが、@ Craig Ringerにはいくつかの余分なポイントがあり、本当にそれを推進しています。私の悪い習慣を浄化してくれたSFに再び感謝します!
バンジャー

2
@Craig:なんて素晴らしい反応です。デモを含めるために、この100倍の賛成票を投じることができればと思います。私はPGを毎日使用しているソフトウェア開発者であり、6.xの時代からあなたの反応はすぐにわかります!いいね!
キロ

2
いい答えだ。補遺:で死ぬことのないバックエンドプロセスがある場合- pg_terminate_backendサーバースタックの再起動でも、何でもではなく、あなたが望むようにそれを殺すことができますが、データベースの作業バックアップがあることを確認してください。それにはいくつかの方法があります。データディレクトリをバックアップする(続行する前にバックアップをテストする)ために、pg_basebackupまたは同様(または単にrsyncおよびpg_start\stop_backup)を使用pg_dump[all]するか、データをサルベージするために使用できます。その場合にのみkill -9、、または再起動などを検討してください。
ザックB

1
@ZacBうん、そしてあなたがそれを殺すなら、すべてのバックエンドが死ぬことを確認てください。最も重要なのは、削除しないことpostmaster.pidです。今まで。
クレイグリンガー

29

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


4
kill -9殺されたプロセスに関する限り、突然システムの電源を切ることと似ていないことを考えると、誰かが恐ろしいことについて疑問に思っている場合:Pgはバックエンドクラッシュ(aのようなkill -9)に非常に寛容であり、データ破損は決してありません。そこでしょうあなたが殺した場合に破損することはpostmasterを、削除postmaster.pid、また、最初のすべてのバックエンドを殺すことなく、それを再起動します。それあなたのデータベース破壊しますがkill -9、バックエンドだけではありません。kill -9ポストマスターにバックエンドを殺す時間を与えないため、危険です。
クレイグリンガー

2
...先週やった緊急コンサルティングケースのように。データベースがひどく破損し、バックアップが失敗して(復元を自動テストしなかったため)2日間の仕事を失い、48時間ダウンしました。削除しないでくださいpostmaster.pid
クレイグリンガー14年

8

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

SQLデーモンには内部プロセスコントロールもあるため、最初にそのチャネルを使用してみることをお勧めします。

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


4
kill -9とにかくあなたのデフォルトの選択であってはならない、それは最後の手段です。SIGTERMwith kill -TERMまたはplain killを送信し、受信者がしばらくして応答しない場合は、その場合にのみ検討する必要がありますkill -KILLkill -9)。
クレイグリンガー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.