postgresql表死鎖問題的排查方式
1.查詢激活的執行中的sql,查看有哪些更新update的sql。
select * from pg_stat_activity where state = 'active';
2. 查詢表中存在的鎖
select a.locktype, a.database, a.pid, a.mode, a.relation, b.relname from pg_locks a join pg_class b on a.relation = b.oid where lower(b.relname) = 'h5_game';
3. 殺掉死鎖進程
select pg_terminate_backend(pid) from pg_stat_activity where state = 'active' and pid != pg_backend_pid() --and pid = 14172 and pid in (select a.pid from pg_locks a join pg_class b on a.relation = b.oid where lower(b.relname) = 'news_content')
鎖模式
/* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */ #define NoLock 0 #define AccessShareLock 1 /* SELECT */ #define RowShareLock 2 /* SELECT FOR UPDATE/FOR SHARE */ #define RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */ #define ShareUpdateExclusiveLock 4 /* VACUUM (non-FULL),ANALYZE, CREATE * INDEX CONCURRENTLY */ #define ShareLock 5 /* CREATE INDEX (WITHOUT CONCURRENTLY) */ #define ShareRowExclusiveLock 6 /* like EXCLUSIVE MODE, but allows ROW * SHARE */ #define ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR * UPDATE */ #define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM * FULL, and unqualified LOCK TABLE */
補充:Postgresql死鎖的處理
背景:
對表進行所有操作都卡住,原因可能是更新表時導致這個表死鎖瞭,開始進行排查
解決一:查詢pg_stat_activity有沒有記錄
pg版本10.2
select pid,query,* from pg_stat_activity where datname='死鎖的數據庫' and wait_event_type = 'Lock'; select pg_cancel_backend('死鎖那條數據的pid值');##隻能殺死select 語句, 對其他語句不生效 pg_terminate_backend('死鎖那條數據的pid值');#select,drop等各種操作
執行後發現select和delete表時正常執行,但truncate和drop表時會一直運行,也不報錯。
“drop table” 和 “truncate table” 需要申請排它鎖”ACCESS EXCLUSIVE”, 執行這個命令卡住時,說明此時這張表上還有操作正在進行,比如查詢等,
那麼隻有等待這個查詢操作完成,“drop table” 或”truncate table”或者增加字段的SQL才能獲取這張表上的 “ACCESS EXCLUSIVE”鎖,操作才能進行下去。
解決二:查詢pg_locks是否有這個對象的鎖
select oid,relname from pg_class where relname='table name'; select locktype,pid,relation,mode,granted,* from pg_locks where relation= '上面查詢出來的oid'; select pg_terminate_backend('進程ID');
問題解決!!!
坑:一開始不知道pg_cancel_backend(‘死鎖那條數據的pid值’);##隻能殺死select 語句, 對其他語句不生效,殺瞭進程查詢發現還存在,反復殺反復存在,換瞭pg_terminate_backend(‘進程ID’)問題就解決瞭。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。如有錯誤或未考慮完全的地方,望不吝賜教。
推薦閱讀:
- Postgresql鎖機制詳解(表鎖和行鎖)
- pgsql鎖表後kill進程的操作
- 解決postgresql 數據庫 update更新慢的原因
- 基於postgresql數據庫鎖表問題的解決
- PostgreSQL出現死鎖該如何解決