PostgreSQL kill pg_terminate_backend

PostgreSQL

PostgreSQL プロセスのkill

PostgreSQLでkillを試してみましたので、掲載しておきます。

実行中のプロセス確認方法は、pg_stat_activity PostgreSQLへ掲載していますので

あんまりポスグレに慣れてない方は見ていただけるといいかと。

 

適当にkill用のプロセスを作る

とりあえず、サンプルのテーブル作っておきましょう。

=> create table kill_sample(
c1 int4 primary key,
c2 text
);


=> \d kill_sample
  Table "public.kill_sample"
 Column |  Type   | Modifiers 
--------+---------+-----------
 c1     | integer | not null
 c2     | text    | 
Indexes:
    "kill_sample_pkey" PRIMARY KEY, btree (c1)

 

kill用のプロセス作ります。

○端末1

=> begin;
BEGIN

=> insert into kill_sample values(1, 'kill_data');

 

別端末で、pg_stat_activityビューでプロセスを確認してみましょう。

○端末2

=> SELECT pid, query_start, query, state, query_start, query_start from pg_stat_activity where pid != pg_backend_pid() and state = 'idle in transaction';
  pid  |          query_start          |                      query                      |        state        |          query_start          |          query_start          
-------+-------------------------------+-------------------------------------------------+---------------------+-------------------------------+-------------------------------
 14912 | 2017-12-22 19:58:23.364255+09 | insert into kill_sample values(1, 'kill_data'); | idle in transaction | 2017-12-22 19:58:23.364255+09 | 2017-12-22 19:58:23.364255+09
(1 row)

 

存在していたプロセスをkillするには「pg_cancel_backend」と「pg_terminate_backend」がありますが
まずは「pg_cancel_backend」でkillしてみましょう。

  • 「pg_cancel_backend」と「pg_terminate_backend」の違い

pg_cancel_backendとpg_terminate_backendは(それぞれ、SIGINTまたはSIGTERM)
シグナルをプロセス識別子で特定されたバックエンドプロセスに送ります。
https://www.postgresql.jp/document/pg930doc/html/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL-TABLE

 

○端末2

=> SELECT pg_cancel_backend(14912);
 pg_cancel_backend 
-------------------
 t
(1 row)

 

プロセスがkillされたか確認するとkillされていないかと思います。
SIGINTのシグナルでは消えなかったみたいです。

○端末2

=> SELECT pid, query_start, query, state, query_start, query_start from pg_stat_activity where pid != pg_backend_pid() and state = 'idle in transaction';
  pid  |          query_start          |                      query                      |        state        |          query_start          |          query_start          
-------+-------------------------------+-------------------------------------------------+---------------------+-------------------------------+-------------------------------
 14912 | 2017-12-22 20:04:38.861232+09 | insert into kill_sample values(1, 'kill_data'); | idle in transaction | 2017-12-22 20:04:38.861232+09 | 2017-12-22 20:04:38.861232+09
(1 row)

 

「pg_terminate_backend」で実行して、確認してみましょう。
SIGTERMのシグナルではkillできました。

○端末2

=> SELECT pg_terminate_backend(14912);
 pg_terminate_backend 
----------------------
 t
(1 row)


=> SELECT pid, query_start, query, state, query_start, query_start from pg_stat_activity where pid != pg_backend_pid() and state = 'idle in transaction';
 pid | query_start | query | state | query_start | query_start 
-----+-------------+-------+-------+-------------+-------------
(0 rows)

 

端末1で「commit;」してみます。
予想通りのエラーでました。

○端末1

=> commit;
FATAL:  terminating connection due to administrator command
SSL connection has been closed unexpectedly
The connection to the server was lost. Attempting reset: Succeeded.

 

まとめ

プロセスをkillしたい時には、純粋に「pg_terminate_backend」を使えば良さそう。

コメント