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 = '資料庫使用者名稱';
上面查詢結果中: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
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。