1. 程式人生 > 資料庫 >Postgresql 解決鎖表

Postgresql 解決鎖表

##一、postgresql解決鎖表
--查詢是否鎖表了
select oid from pg_class where relname='可能鎖表了的表'
select pid from pg_locks where relation='上面查出的oid'
--如果查詢到了結果,表示該表被鎖 則需要釋放鎖定
select pg_cancel_backend(上面查到的pid)
12345 二、檢視鎖的其他方法
轉載地址:https://yq.aliyun.com/ask/184?order=ctime
--  用一個函式來將鎖轉換為數字,
create or replace function f_lock_level(i_mode text) returns int as
$$ declare
begin
  case i_mode
    when 'INVALID' then return 0;
    when 'AccessShareLock' then return 1;
    when 'RowShareLock' then return 2;
    when 'RowExclusiveLock' then return 3;
    when 'ShareUpdateExclusiveLock' then return 4;
    when 'ShareLock' then return 5;
    when 'ShareRowExclusiveLock' then return 6;
    when 'ExclusiveLock' then return 7;
    when 'AccessExclusiveLock' then return 8;
    else return 0;
  end case;
end; $$
 language plpgsql strict;
-- 修改查詢語句,按鎖級別排序:
with t_wait as                    
(   select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.objid,a.objsubid,
 a.pid,a.virtualtransaction,a.virtualxid,a,transactionid,b.query,b.xact_start,b.query_start,
 b.usename,b.datname
 from pg_locks a,pg_stat_activity b
 where a.pid=b.pid and not a.granted
),
t_run as
(
 select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.objid,a.objsubid,
 a.pid,a.virtualtransaction,a.virtualxid,a,transactionid,b.query,b.xact_start,b.query_start,
 b.usename,b.datname
 from pg_locks a,pg_stat_activity b
 where a.pid=b.pid and a.granted
)
select r.locktype,r.mode r_mode,r.usename r_user,r.datname r_db,r.relation::regclass,r.pid r_pid,
r.page r_page,r.tuple r_tuple,r.xact_start r_xact_start,r.query_start r_query_start,
now()-r.query_start r_locktime,r.query r_query,w.mode w_mode,w.pid w_pid,w.page w_page,
w.tuple w_tuple,w.xact_start w_xact_start,w.query_start w_query_start,
now()-w.query_start w_locktime,w.query w_query 
from t_wait w,t_run r
where r.locktype is not distinct from w.locktype
and r.database is not distinct from w.database
and r.relation is not distinct from w.relation
and r.page is not distinct from w.page
and r.tuple is not distinct from w.tuple
and r.classid is not distinct from w.classid
and r.objid is not distinct from w.objid
and r.objsubid is not distinct from w.objsubid
and r.transactionid is not distinct from w.transactionid
and r.pid <> w.pid
order by f_lock_level(w.mode)+f_lock_level(r.mode) desc,r.xact_start;
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
--現在可以排在前面的就是鎖級別高的等待,優先幹掉這個。
-[ RECORD 1 ]-+---------------------------------------------------------------------
locktype      | relation  -- 衝突型別
r_mode        | ShareUpdateExclusiveLock  -- 持鎖模式
r_user        | postgres  -- 持鎖使用者
r_db          | postgres  -- 持鎖資料庫
relation      | tbl  -- 持鎖物件
r_pid         | 25656  -- 持鎖程序
r_xact_start  | 2015-05-10 14:11:16.08318+08  -- 持鎖事務開始時間
r_query_start | 2015-05-10 14:11:16.08318+08  -- 持鎖SQL開始時間
r_locktime    | 00:01:49.460779  -- 持鎖時長
r_query       | vacuum freeze tbl;  --  持鎖SQL,注意不一定是這個SQL帶來的鎖,也有可能是這個事務在之前執行的SQL加的鎖
w_mode        | AccessExclusiveLock  -- 等待鎖模式
w_pid         | 26731  -- 等待鎖程序
w_xact_start  | 2015-05-10 14:11:17.987362+08  --  等待鎖事務開始時間
w_query_start | 2015-05-10 14:11:17.987362+08  --  等待鎖SQL開始時間
w_locktime    | 00:01:47.556597  --  等待鎖時長
w_query       | truncate tbl;  -- 等待鎖SQL
-[ RECORD 2 ]-+---------------------------------------------------------------------
locktype      | relation
r_mode        | ShareUpdateExclusiveLock
r_user        | postgres
r_db          | postgres
relation      | tbl
r_pid         | 25656
r_xact_start  | 2015-05-10 14:11:16.08318+08
r_query_start | 2015-05-10 14:11:16.08318+08
r_locktime    | 00:01:49.460779
r_query       | vacuum freeze tbl;
w_mode        | RowExclusiveLock
w_pid         | 25582
w_xact_start  | 2015-05-10 14:11:22.845+08
w_query_start | 2015-05-10 14:11:22.845+08
w_locktime    | 00:01:42.698959
w_query       | insert into tbl(crt_time) select now() from generate_series(1,1000);  -- 這個SQL其實等待的是truncate tbl的鎖;
......