平時遇到數據庫,查詢慢,或者數據庫故障問題,怎么辦,可以看看數據庫相關的一些狀態視圖,快速定位問題
pg_stat_activity 是postgrsql 實例維護的一個進程相關的視圖,是實時變化的。
1、pg_stat_activity表(9.6 版本之后 pg_stat_activity 視圖的 waiting 字段被 wait_event_type 和 wait_event 字段取代,這兩個字段分別代表等待事件的類型、等待事件名稱)
使用 SELECT * FROM pg_stat_activity 可以看到這個表的所有字段信息
主要字段包括如下:
一般關注的屬性主要包括:datname,pid,usename,application_name,client_addr,client_port,backend_start,xact_start,query_start,state_change,wait_event,state ,query
datname:數據庫名稱,比如:postgres
pid:進程id
usename:數據庫登錄賬號
application_name:登錄客戶端的類型,比如:DBeaver 6.2.0 - Main 客戶端 或者 PostgreSQL JDBC Driver 數據庫驅動代碼客戶端
client_addr:客戶端ip
client_port:客戶端端口
backend_start:連接創建時間
xact_start:事務開始時間,null表示沒有用到事務,如果當前查詢是其第一個事務,那么就是query_start一致
query_start:如果state是active,當前查詢開始時間點;如果state不是active,那么就是上一次查詢開始時間
state_change:state上次改變時間
wait_event和wait_event_type
wait_event_type 主要分類四類:
- LWLockNamed:表示backend后台進程等待某種特定的輕量級鎖;
- LWLockTranche:表示backend后台進程等待一組相關輕量級鎖;
- Lock:表示backend后台進程等待重量級的鎖,通常是指 relation、tuple、page、transactionid 等子類型鎖;
- BufferPin:表示server process 后台進程等待 buffer pin,手冊上解釋為 Waiting to acquire a pin on a buffer
官網地址:https://www.postgresql.org/docs/9.6/monitoring-stats.html#WAIT-EVENT-TABLE
state :active:表示當前用戶正在執行查詢等操作;idle:表示當前用戶空閑; idle in transaction:表示當前用戶在事務中;idle in transaction (aborted): 表示當前用戶在事務中,但是已經發生錯誤;
query:當前執行狀態關聯的sql
使用 查詢慢sql語句:
select 'select pg_cancel_backend('|| a0.pid || ');' as cancel_pid, 'select pg_terminate_backend('|| a0.pid || ');' as terminate_pid, xact_start,round(extract(epoch FROM (now()-xact_start))::numeric,1) as xact_second, query_start,round(extract(epoch FROM (now()-query_start))::numeric,1) as query_second, datname, pid, usename, application_name, client_addr, client_port, xact_start, query_start, state_change,wait_event_type,wait_event, state, backend_xid, backend_xmin, query from pg_stat_activity a0 where 1=1 and a0.state<>'idle' and (a0.backend_xid is not null or a0.backend_xmin is not null) order by now()-xact_start;
now() - xact_start 是指事務截至當前已運行時間。
now() - query_start 是指query截至當前已運行時間。
慢sql 可以使用explian 查看下原因
如果遇到長時間執行的sql,那么該怎么取消,有兩種方法
SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL;
pid | wait_event_type | wait_event ------+-----------------+--------------- 2540 | Lock | relation 6644 | LWLockNamed | ProcArrayLock (2 rows)
3、查詢是否鎖表
select oid from pg_class where relname='可能鎖表了的表' select pid from pg_locks where relation='上面查出的oid'