1. 程式人生 > 資料庫 >postgresql查詢鎖表以及解除鎖表操作

postgresql查詢鎖表以及解除鎖表操作

1.-- 查詢ACTIVITY的狀態等資訊

select T.PID,T.STATE,T.QUERY,T.WAIT_EVENT_TYPE,T.WAIT_EVENT,T.QUERY_START
 from PG_STAT_ACTIVITY T
 where T.DATNAME = '資料庫使用者名稱';

postgresql查詢鎖表以及解除鎖表操作

上面查詢結果中:pid就是ACTIVITY的唯一標識,state就是活動狀態,query就是正在執行的sql語句,query——start就是開始執行的時間。

2.-- 查詢死鎖的ACTIVITY

select T.PID,T.QUERY_START
 from PG_STAT_ACTIVITY T
 where T.DATNAME = '資料庫使用者名稱'
  and T.WAIT_EVENT_TYPE = 'Lock';

3.將第二條查詢語句的pid欄位的數字值記錄下來,執行下面的查詢語句可以解鎖:

-- 通過pid解鎖對應的ACTIVITY

select PG_CANCEL_BACKEND('6984');

上面的查詢語句,執行了pg_cancel_backend()函式,該函式是取消後臺操作,回滾未提交事物的用途。

補充:PostgreSQL 之 鎖機制

當要增刪改查表中的資料時,首先是要獲得表上的鎖,然後再獲得行上的鎖

postgresql中有8種表鎖

最普通的是共享鎖 share 和排他鎖 exclusive

因為多版本的原因,修改一條語句的同時,允許了讀資料,為了處理這種情況,又增加了兩種鎖”access share”和”acess excusive”,鎖中的關鍵字 access 是與多版本相關的

為了處理表鎖和行鎖之間的關係,有了 意向鎖 的概念,這時又加了兩種鎖,即 意向共享鎖 和 意向排他鎖 ,由於意向鎖之間不會產生衝突,而且意向排它鎖相互之間也不會產生衝突,於是又需要更嚴格一些的鎖,這樣就產生了“share update exclusive” 和 ”share row exclusive”

表級鎖模式

表級鎖模式

解釋

ACCESS SHARE

只與“ACCESS EXCLUSIVE” 鎖模式衝突;

查詢命令(Select command)將會在它查詢的表上獲取”Access Shared” 鎖,一般地,任何一個對錶上的只讀查詢操作都將獲取這種型別的鎖。

ROW SHARE

與”Exclusive'和”Access Exclusive”鎖模式衝突;

”Select for update”和”Select for share”命令將獲得這種型別鎖,並且所有被引用但沒有 FOR UPDATE 的表上會加上”Access shared locks”鎖。

ROW EXCLUSIVE

與 “Share,Shared roexclusive,Exclusive,Access exclusive”模式衝突;

“Update,Delete,Insert”命令會在目標表上獲得這種型別的鎖,並且在其它被引用的表上加上”Access shared”鎖,一般地,更改表資料的命令都將在這張表上獲得”Row exclusive”鎖。

SHARE UPDATE EXCLUSIVE

”Share update exclusive,Share,Share row,exclusive,Access exclusive”模式衝突,這種模式保護一張表不被併發的模式更改和VACUUM;

“Vacuum(without full),Analyze ”和 “Create index concurrently”命令會獲得這種型別鎖。

SHARE

與“Row exclusive,Shared update exclusive,Share row exclusive,Access exclusive”鎖模式衝突,這種模式保護一張表資料不被併發的更改;

“Create index”命令會獲得這種鎖模式。

SHARE ROW EXCLUSIVE

與“Row exclusive,Share update exclusive,Shared,Shared row exclusive,Access Exclusive”鎖模式衝突;

任何Postgresql 命令不會自動獲得這種鎖。

EXCLUSIVE

與” ROW SHARE,ROW EXCLUSIVE,SHARE UPDATE EXCLUSIVE,SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE,ACCESS EXCLUSIVE”模式衝突,這種索模式僅能與Access Share 模式併發,換句話說,只有讀操作可以和持有”EXCLUSIVE”鎖的事務並行;

任何Postgresql 命令不會自動獲得這種型別的鎖;

ACCESS EXCLUSIVE

與所有模式鎖衝突(ACCESS SHARE,ROW SHARE,and ACCESS EXCLUSIVE),這種模式保證了當前只有一個事務訪問這張表;“ALTER TABLE,DROP TABLE,TRUNCATE,REINDEX,CLUSTER,VACUUM FULL” 命令會獲得這種型別鎖,在Lock table 命令中,如果沒有申明其它模式,它也是預設模式。

表鎖的衝突關係

Requested Lock Mode

Current Lock Mode

ACCESS SHARE

ROW SHARE

ROW EXCLUSIVE

SHARE UPDATE EXCLUSIVE

SHARE

SHARE ROW EXCLUSIVE

EXCLUSIVE

ACCESS EXCLUSIVE

ACCESS SHARE

X

X

ROW SHARE

X

X

ROW EXCLUSIVE

X

X

X

X

SHARE UPDATE EXCLUSIVE

X

X

X

X

X

SHARE

X

X

X

X

X

SHARE ROW EXCLUSIVE

X

X

X

X

X

X

EXCLUSIVE

X

X

X

X

X

X

X

ACCESS EXCLUSIVE

X

X

X

X

X

X

X

X

表鎖型別對應的資料庫操作

鎖型別

對應的資料庫操作

ACCESS SHARE

select

ROW SHARE

select for update,select for share

ROW EXCLUSIVE

update,delete,insert

SHARE UPDATE EXCLUSIVE

vacuum(without full),analyze,create index concurrently

SHARE

create index

SHARE ROW EXCLUSIVE

任何Postgresql命令不會自動獲得這種鎖

EXCLUSIVE

任何Postgresql命令不會自動獲得這種型別的鎖

ACCESS EXCLUSIVE

alter table,drop table,truncate,reindex,cluster,vacuum full

表級鎖命令(顯式在表上加鎖的命令)

testdb=# \h lock
Command:  LOCK
Description: lock a table
 
Syntax:
LOCK [ TABLE ] [ ONLY ] name [ * ] [,...] [ IN lockmode MODE ] [ NOWAIT ]
 
where lockmode is one of:
 ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
 | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE

注:

name:要鎖定的現有表的鎖名稱(可選模式限定)。 如果在表名之前指定了ONLY,則僅該表被鎖定 如果未指定ONLY,則表及其所有後代表(如果有)被鎖定。

lock_mode:鎖模式指定此鎖與之衝突的鎖。 如果未指定鎖定模式,則使用最嚴格的訪問模式ACCESS EXCLUSIVE。

nowait

當事務要更新表中的資料時,應該申請“ROW EXCLUSIVER”

行級鎖模式

只有兩種,共享鎖和排他鎖,或者可以說是“讀鎖” 或 “寫鎖“

由於多版本的實現,實際讀取行資料時,並不會在行上執行任何鎖

行級鎖命令(顯式加行鎖)

SELECT …… FOR { UPDATE | SHARE } [OF table_name[,……]] [ NOWAIT]

備註:

1)指定 OF table_name,則只有被指定的表會被鎖定

2)例外情況,主查詢中引用了WITH查詢時,WITH查詢中的表不被鎖定

3)如果需要鎖定WITH查詢中的表,需在WITH查詢內指定FOR UPDATA或FOR SHARE

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。