今天遇到一個問題,就是pg一直報錯,說有太多的客戶端鏈接到數據庫上面。但如今不知道是什麼程序鏈接。pg默認的max_connection是100,我並無修改過,覺得平時公司內部用,應該夠了,但如今貌似這100個鏈接都被消耗掉。在網上google了一下,發現用下面的SQL,竟然能夠查看全部鏈接的情況: sql
select * from pg_stat_activity;
結果集會顯示出當前鏈接的數據庫名,用戶,IP地址,鏈接開始時間,查詢的語句等。 數據庫
這裏的pg_stat_activity實際上是一個視圖,它的定義能夠在postgres這個數據庫裏面的視圖部分找到,如下是它的定義: windows
CREATE OR REPLACE VIEW pg_stat_activity AS SELECT s.datid, d.datname, s.procpid, s.usesysid, u.rolname AS usename, s.application_name, s.client_addr, s.client_hostname, s.client_port, s.backend_start, s.xact_start, s.query_start, s.waiting, s.current_query FROM pg_database d, pg_stat_get_activity(NULL::integer) s(datid, procpid, usesysid, application_name, current_query, waiting, xact_start, query_start, backend_start, client_addr, client_hostname, client_port), pg_authid u WHERE s.datid = d.oid AND s.usesysid = u.oid;
能夠看到,pg_stat_activity這個視圖是由 pg_database,pg_authid,以及兩個方法的結果來組合成的。 服務器
pg_database ,顧名思義就是儲存了在pg裏面的全部的數據庫名稱。 app
pg_authid,是用來儲存pg的登陸帳號。 工具
pg_stat_get_backend_activity在Postgresql裏面的定義以下: post
CREATE OR REPLACE FUNCTION pg_stat_get_backend_activity(integer) RETURNS text AS 'pg_stat_get_backend_activity' LANGUAGE internal STABLE STRICT COST 1;
ALTER FUNCTION pg_stat_get_backend_activity(integer) OWNER TO postgres; COMMENT ON FUNCTION pg_stat_get_backend_activity(integer) IS 'statistics: current query of backend';
可見它是一個pg的內部方法,用來統計當前query的數目。 google
看來pg的內部結構仍是挺清楚簡單的。愈來愈喜歡pg的這種簡單與強大了! spa
好了,如今咱們找出全部鏈接到數據庫的進程了,那麼如何去殺死那些IDEL的進程從而釋放出鏈接呢? 命令行
若是pg的版本是 8.4及以上的,能夠很簡單地用下面的語句來殺死全部IDEL進程 :
SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE current_query='<IDLE>'
pg_terminate_backend 是pg的內部方法,另外還有一個叫pg_cancel_backend,這個方法在8.4之前的版本中就一直存在。這兩個方法的區別在於,pg_cancel_backend 只是取消當前某一個進程的查詢操做,但不能釋放數據庫鏈接。但pg_terminate_backend 能夠在pg的後臺殺死這個進程,從而釋放出寶貴的鏈接資源。
但若是pg的版本是在8.3或者如下的,就不能用上面的方法了。首先,一樣的,要先找出pg裏面有什麼IDEL的鏈接,而後在windows的command裏面,輸入如下命令:
pg_ctl kill TERM PID
以上命令是調用pg的後臺命令行 pg_ctl去執行命令,直接kill那個進程。這樣會同時致使windows和pg的進程同時被殺死,從而釋放資源。比較麻煩的是,只能手動地一個一個進程來殺,沒有批量的方法。
另一個比較有用的工具是pgAdmin提供的,在pgAdmin -> 工具 -> 服務器狀態,會列出當前pg裏面全部的鏈接,從而能夠看到什麼進程在進行什麼操做,pid是多少,何時開始,運行多長時間了,結果是跟用 pg_stat_activity 查詢出來的結果同樣的。