PostgreSQL批量刪除用戶進程

一臺開發機子上有不少的postgres用戶進程,同事問想在不重啓機子的狀況怎麼樣批量地刪除進程。  sql

首先要說一下的是,postgresql是以進程的方式鏈接到數據庫裏面的,因此一般有兩種方式刪除進程,1是在OS層面,2是在數據庫內部 數據庫


1、OS上批量刪除
[root@db1 kenyon]# ps -ef|grep postgres|grep idle
postgres 14184 14030  0 10:56 ?        00:00:00 postgres: postgres postgres [local] idle       
postgres 14206 14030  0 10:56 ?        00:00:00 postgres: postgres postgres [local] idle       
postgres 14228 14030  0 10:57 ?        00:00:00 postgres: postgres postgres [local] idle       
postgres 14230 14030  0 10:57 ?        00:00:00 postgres: postgres postgres [local] idle       

[root@db1 kenyon]# ps -ef|grep postgres|grep idle |awk '{print $2}' | xargs kill
[root@db1 kenyon]#su - postgres
[postgres@db1 ~]$ psql
psql (9.3.2)
Type "help" for help.

postgres=# select pg_backend_pid();
 pg_backend_pid 
----------------
          14184
postgres=# \d
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.

--進程已經被刪除,下面的再次查詢已是另一個進程了
postgres=# \d
No relations found.
postgres=# select pg_backend_pid();
 pg_backend_pid 
----------------
          14262
(1 row)
2、數據庫裏面刪除
--查詢進程
postgres=# select datname,pid,usename,application_name,waiting,state,query from pg_stat_activity;
 datname  |  pid  | usename  |    application_name     | waiting |        state        |                                         query                                          
----------+-------+----------+-------------------------+---------+---------------------+----------------------------------------------------------------------------------------
 postgres | 14337 | postgres | pgAdmin III - ????????? | f       | idle                | SELECT 1 FROM pg_available_extensions WHERE name='adminpack'
 postgres | 14339 | postgres | psql                    | f       | active              | select pg_sleep(600);
 postgres | 14341 | postgres | psql                    | f       | idle                | 
 postgres | 14343 | postgres | psql                    | f       | idle in transaction | select * from tbl_kenyon limit 2;
 postgres | 14347 | postgres | psql                    | f       | active              | select datname,pid,usename,application_name,waiting,state,query from pg_stat_activity;
 postgres | 14349 | postgres | psql                    | f       | idle                | select pg_backend_pid();
(6 rows)
刪除進程有兩個內置函數
1.pg_cancel_backend(pid)
2.pg_terminate_backend(pid)

第一個函數只對取消查詢操做有效,好比上面有一個pg_sleep(600)的查詢,取消操做,第二個則等同於OS的kill pid
--Session A
postgres=# select pg_cancel_backend(14339);
 pg_cancel_backend 
-------------------
 t
(1 row)

--狀態變成IDLE,說明該進程是空閒狀態
postgres=# select datname,pid,usename,application_name,waiting,state,query from pg_stat_activity;
 datname  |  pid  | usename  |    application_name     | waiting |        state        |                                         query                                          
----------+-------+----------+-------------------------+---------+---------------------+----------------------------------------------------------------------------------------
 postgres | 14337 | postgres | pgAdmin III - ????????? | f       | idle                | SELECT 1 FROM pg_available_extensions WHERE name='adminpack'
 postgres | 14339 | postgres | psql                    | f       | idle                | select pg_sleep(600);
 postgres | 14341 | postgres | psql                    | f       | idle                | 
 postgres | 14343 | postgres | psql                    | f       | idle in transaction | select * from tbl_kenyon limit 2;
 postgres | 14347 | postgres | psql                    | f       | active              | select datname,pid,usename,application_name,waiting,state,query from pg_stat_activity;
 postgres | 14349 | postgres | psql                    | f       | idle                | select pg_backend_pid();
(6 rows)

--Session B,取消查詢並嘗試取消update操做
postgres=# select pg_backend_pid();
 pg_backend_pid 
----------------
          14339
(1 row)
postgres=# select pg_sleep(600);
ERROR:  canceling statement due to user request
postgres=# begin;
BEGIN
postgres=# update tbl_kenyon set id=id+1;
UPDATE 20
postgres=# 

--Session A
postgres=# select pg_cancel_backend(14339);
 pg_cancel_backend 
-------------------
 t
(1 row)

--能夠發現狀態沒有改變
postgres=# select datname,pid,usename,application_name,waiting,state,query from pg_stat_activity;
 datname  |  pid  | usename  |    application_name     | waiting |        state        |                                         query                                          
----------+-------+----------+-------------------------+---------+---------------------+----------------------------------------------------------------------------------------
 postgres | 14337 | postgres | pgAdmin III - ????????? | f       | idle                | SELECT 1 FROM pg_available_extensions WHERE name='adminpack'
 postgres | 14339 | postgres | psql                    | f       | idle in transaction | update tbl_kenyon set id=id+1;
 postgres | 14341 | postgres | psql                    | f       | idle                | 
 postgres | 14343 | postgres | psql                    | f       | idle in transaction | select * from tbl_kenyon limit 2;
 postgres | 14347 | postgres | psql                    | f       | active              | select datname,pid,usename,application_name,waiting,state,query from pg_stat_activity;
 postgres | 14349 | postgres | psql                    | f       | idle                | select pg_backend_pid();
(6 rows)

postgres=# select pg_terminate_backend(14339);
 pg_terminate_backend 
----------------------
 t
(1 row)

--進程已經被殺掉了
postgres=# select datname,pid,usename,application_name,waiting,state,query from pg_stat_activity;
 datname  |  pid  | usename  |    application_name     | waiting |        state        |                                         query                                          
----------+-------+----------+-------------------------+---------+---------------------+----------------------------------------------------------------------------------------
 postgres | 14337 | postgres | pgAdmin III - ????????? | f       | idle                | SELECT 1 FROM pg_available_extensions WHERE name='adminpack'
 postgres | 14341 | postgres | psql                    | f       | idle                | 
 postgres | 14343 | postgres | psql                    | f       | idle in transaction | select * from tbl_kenyon limit 2;
 postgres | 14347 | postgres | psql                    | f       | active              | select datname,pid,usename,application_name,waiting,state,query from pg_stat_activity;
 postgres | 14349 | postgres | psql                    | f       | idle                | select pg_backend_pid();
(5 rows)

--Session B
postgres=# 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.
postgres=# select pg_backend_pid();
 pg_backend_pid 
----------------
          14365
(1 row)
3.批量刪除
--也能夠本身加條件選擇刪除
postgres=# select pg_terminate_backend(pid)  from pg_stat_activity where pid <> pg_backend_pid() ;
pg_terminate_backend 
----------------------
 t
 t
 t
 t
 t
 t
(6 rows)
3、Kill -9
不要使用kill -9來刪除進程,不到萬一千萬別使用該命令,該命令極易致使服務器進程異常,甚至奔潰。使用kill -9時系統日誌輸出的一些信息,有一些crash信息(shm、重啓postgres.pid等),雖然還能繼續使用,實際上是修復好了的緣故,使用kill -9將致使其餘的進程被重置或重連,有點相似斷電重啓。
2013-12-24 13:07:03.963 CST,,,14325,,52b8fbc8.37f5,19,,2013-12-24 11:13:12 CST,,0,LOG,00000,"server process (PID 14549) was terminated by signal 9: Killed","Failed process was running: select pg_backend_pid();",,,,,,,,""
2013-12-24 13:07:03.964 CST,,,14325,,52b8fbc8.37f5,20,,2013-12-24 11:13:12 CST,,0,LOG,00000,"terminating any other active server processes",,,,,,,,,""
2013-12-24 13:07:03.966 CST,,,14537,,52b91617.38c9,2,,2013-12-24 13:05:27 CST,1/0,0,WARNING,57P02,"terminating connection because of crash of another server process","The postmaster has commanded this server process to roll back the curr
ent transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.","In a moment you should be able to reconnect to the database and repeat your command.",,,,,,,""
2013-12-24 13:07:03.972 CST,,,14325,,52b8fbc8.37f5,21,,2013-12-24 11:13:12 CST,,0,LOG,00000,"all server processes terminated; reinitializing",,,,,,,,,""
2013-12-24 13:07:03.990 CST,,,14551,,52b91677.38d7,1,,2013-12-24 13:07:03 CST,,0,LOG,00000,"database system was interrupted; last known up at 2013-12-24 13:05:27 CST",,,,,,,,,""
2013-12-24 13:07:03.990 CST,,,14551,,52b91677.38d7,2,,2013-12-24 13:07:03 CST,,0,LOG,00000,"database system was not properly shut down; automatic recovery in progress",,,,,,,,,""
2013-12-24 13:07:04.000 CST,,,14551,,52b91677.38d7,3,,2013-12-24 13:07:03 CST,,0,LOG,00000,"record with zero length at 0/1839858",,,,,,,,,""
2013-12-24 13:07:04.000 CST,,,14551,,52b91677.38d7,4,,2013-12-24 13:07:03 CST,,0,LOG,00000,"redo is not required",,,,,,,,,""
2013-12-24 13:07:04.006 CST,,,14325,,52b8fbc8.37f5,22,,2013-12-24 11:13:12 CST,,0,LOG,00000,"database system is ready to accept connections",,,,,,,,,""
2013-12-24 13:07:04.007 CST,,,14555,,52b91678.38db,1,,2013-12-24 13:07:04 CST,,0,LOG,00000,"autovacuum launcher started",,,,,,,,,""
2013-12-24 13:07:06.268 CST,,,14557,"",52b9167a.38dd,1,"",2013-12-24 13:07:06 CST,,0,LOG,00000,"connection received: host=[local]",,,,,,,,,""
普通的kill pid的輸出
2013-12-24 13:09:03.910 CST,"postgres","postgres",14557,"[local]",52b9167a.38dd,3,"idle",2013-12-24 13:07:06 CST,2/0,0,FATAL,57P01,"terminating connection due to administrator command",,,,,,,,,"psql"
2013-12-24 13:09:03.910 CST,"postgres","postgres",14557,"[local]",52b9167a.38dd,4,"idle",2013-12-24 13:07:06 CST,,0,LOG,00000,"disconnection: session time: 0:01:57.642 user=postgres database=postgres host=[local]",,,,,,,,,"psql"

4、總結
刪除postgresql的進程使用kill或者pg_terminate_backend()命令,不要使用kill -9 服務器

相關文章
相關標籤/搜索