web-dev-qa-db-ja.com

無限ループplperlを強制終了します

無限ループplperl関数を使用してセッションを強制終了するにはどうすればよいですか?

両方とも pg_terminate_backendおよびpg_cancel_backendは効果がありませんでした。 kill -1 pidも何もせず、kill -9 pidクラッシュしたサーバー。

5

あなたは正しいです、

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"

それがオプションであれば、それはうまくいくようです。

5
Evan Carroll