無限ループplperl関数を使用してセッションを強制終了するにはどうすればよいですか?
両方とも pg_terminate_backend
およびpg_cancel_backend
は効果がありませんでした。 kill -1 pid
も何もせず、kill -9 pid
クラッシュしたサーバー。
あなたは正しいです、
CREATE FUNCTION foo()
RETURNS void
AS $$
while(1) {}
$$ LANGUAGE plperl;
SELECT * FROM foo();
Plperlバックエンドが存続するpg_terminate_backend
およびpg_cancel_backend
を呼び出しました。彼らがすでに知っているバグのようです、 トム・レーンが言うリストから、
このようなガーデンバラエティのバグを修正できると仮定しても、非協力的なユーザー関数(特にplperl/pltcl/plpythonの関数)が
pg_terminate_backend
への応答を無期限に遅延させる可能性がある基本的な問題がまだあります。QueryCancel
も同様に延期または無視できることを確認すれば大丈夫かもしれませんが、これを要求する人々が本当に満足するかどうかはわかりません。 (考慮すべき1つのことは、ERRCODE_ADMIN_SHUTDOWN
をplpgsql例外ブロックによって無条件にトラップできないようにすることです。これにより、少なくともplpgsql関数の問題が修正されます。)
彼らがこれに対する解決策を持っているかどうかはわかりません。クレイグリンガーから
一般に、
pg_terminate_backend
を「大きなハンマー」として使用するのが安全です。pg_terminate_backend()
から送信されるSIGTERM
は、多くの場合常にではありませんが、応答できないバックエンドを引き起こしますキャンセルして終了します。
彼は がハング を引き起こす可能性のあるオプションのいくつかについても説明しています。
とにかく、何かやってみよう
CREATE FUNCTION foo()
RETURNS void
AS $$
$SIG{INT} = $SIG{TERM} = sub { die; };
while(1) {}
$$ LANGUAGE plperl;
それから私は走った
SESSION 1 SESSION 2
SELECT pg_backend_pid();
pg_backend_pid
----------------
20465
SELECT * FROM foo();
-- LOOPING
pg_terminate_backend(20465);
ERROR: Died at line 2.
CONTEXT: PL/Perl function "foo"
それがオプションであれば、それはうまくいくようです。