GaussDB(DWS)表級鎖功能實操與思考
本人原來主要接觸TD,表級鎖的分類、場景等跟GaussDB(DWS)的鎖類型有較大區別。TD的表級鎖類型較少,GaussDB(DWS)的鎖類型更細分一些。

此處對GaussDB(DWS)各種類型的鎖都實操一下,加深學習。
鎖類型
下圖是各類型鎖與互斥的關系
從鎖的名稱我們能大致將鎖分為兩類:SHARE鎖、EXCLUSIVE鎖。
這兩類型鎖的核心思想是,SHARE是多事務共享的,EXCLUSIVE是單事務獨享的。根據不同場景分了一下8種鎖類型。同時根據鎖的相關性做了分類
ACCESS鎖訪問相關
ACCESS SHARE
SELECT命令在被引用的表上獲得一個這種模式的鎖,也就是說每當讀取表的數據時,都會上一個ACCESS SHARE鎖。只與ACCESS EXCLUSIVE鎖沖突,也就是說除了DDL語句等,沒有別的事務能阻止ACCESS SHARE鎖下的讀數據動作
ACCESS EXCLUSIVE
ACCESS EXCLUSIVE與所有鎖類型沖突,這個模式保證其所有者(事務)是可以訪問該表的唯一事務。
ALTER TABLE,DROP TABLE,TRUNCATE,REINDEX,CLUSTER,VACUUM FULL命令會自動請求這種鎖。
在LOCK TABLE命令沒有明確聲明需要的鎖模式時,它是缺省鎖模式。
ACCESS SHARE與ACCESS EXCLUSIVE鎖沖突例子:
--SESSION?1? begin; --對表locka加上ACCESS?EXCLUSIVE鎖 lock?table??locka?in?access?exclusive?mode; --查詢locka的數據 select?*?from?locka;
--SESSION?2? begin; --對表locka加上ACCESS?SHARE鎖,此處會一直等待SESSION?1的ACCESS?EXCLUSIVE鎖,直到達到死鎖超時。此處換成其他類型的鎖結果都一樣 lock?table??locka?in?access?share?mode;
ROW行鎖
ROW SHARE
SELECT FOR UPDATE和SELECT FOR SHARE命令會自動在目標表上請求ROW SHARE鎖(且所有被引用但不是FOR SHARE/FOR UPDATE的其他表上,還會自動加上ACCESS SHARE鎖)。
SELECT FOR UPDATE是對行加鎖的語句,執行后指定行在其他事務中只能讀;而其他行能夠正常的增刪改查。
表級加ROW SHARE鎖后,行級也有鎖的例子:
--SESSION?1? begin; --select?for?update語句自動會加上ROW?SHARE select?*?from?locka?where?col1?=?1?for?update;
--SESSION?2? begin; --加上?row?share?lock lock?table?locka?in?row?share?mode; --查詢session?1中指定行 select?*?from?locka?where?col1?=?1; --查詢其他行 select?*?from?locka?where?col1?=?3; --執行對其他行的DML語句 delete?locka?where?col1?=?3; --執行session?1中一樣的行加鎖語句,會等待session?1的事務結束,若執行對該行的增刪改,也會發生沖突等待,因為該行已被sesion1加上了排他鎖。 select?*?from?locka?where?col1?=?1?for?update;
增刪改操作的鎖
ROW EXCLUSIVE
UPDATE,DELETE,INSERT命令會自動在目標表上請求這個鎖(且所有被引用的其他表上還會自動加上的ACCESS SHARE鎖)。通常情況下,所有會修改表數據的命令都會請求表的ROW EXCLUSIVE鎖。
SHARE UPDATE EXCLUSIVE
VACUUM(不帶FULL選項),ANALYZE,CREATE INDEX CONCURRENTLY命令會自動請求這樣的鎖。
從鎖沖突來看,不能夠兩個事務同時對同一個表進行VACUUM(不帶FULL選項),ANALYZE等操作;一個表在進行DML操作時能夠進行VACUUM和ANALYZE操作。下面兩個例子展示ROW EXCLUSIVE與SHARE UPDATE EXCLUSIVE兩種鎖的使用
例子1,增刪改時能操作VACUUM與ANALIZE:
--SESSION?1? begin; --插入操作 insert?into?locka?values?(8);
--SESSION?2?在session?1插入數據后 analyze?locka; --vacuum vacuum?locka; --查詢當前locka的鎖是否ROW?EXCLUSIVE鎖 select?a.relname,b.mode?from?pg_class?a?inner?join?pg_locks?b?on?a.oid?=?b.relation?where?relname?=?'locka';
例子2,確認ANALYZE與VACUUM是SHARE UPDATE EXCLUSIVE鎖;
--SESSION?1? begin; --給表上exclusive鎖 lock?table?locka?in?exclusive?mode;
--SESSION?2? --因為ANALYZE與VACUUM不能在顯示事務中執行,下面就直接執行看,然后在另外的終端看后臺的鎖類型 analyze?locka; vacuum?locka;
--SESSION?3? --在另外的終端看后臺的鎖類型 select?a.relname,b.mode?from?pg_class?a?inner?join?pg_locks?b?on?a.oid?=?b.relation?where?relname?=?'locka';
在查看vacuum的鎖類型時,發現一個問題,就是vacuum顯示的是只有AccessShareLock,并沒有ShareUpdateExclusiveLock。同時如果只是ACCESSSHARE鎖類型的話,那Exclusive鎖是不會與之沖突,說明這里面有問題,不知道是pg_locks上顯示的問題還是內部的問題了。
SHARE鎖與EXCLUSIVE鎖
SHARE
SHARE鎖之間不沖突、SHARE鎖對增刪改的ROW EXCLUSIVE沖突。也就是說,兩個事務持有SHARE鎖,都不能再該事務內增刪改,但是如果只有一個事務持有,那該事務是可以增刪改的,因為鎖沖突起碼要有兩個事務才行。
CREATE INDEX(不帶CONCURRENTLY選項)語句會自動請求這種鎖。
SHARE ROW EXCLUSIVE
此鎖跟SHARE鎖唯一區別是,與同樣的鎖會沖突,也就是說只能有一個事務能持有該鎖,SHARE鎖也不能加上。
任何SQL語句都不會自動請求這個鎖模式。
EXCLUSIVE
EXCLUSIVE鎖顧名思義就是獨占了某個表,除了持有ACCESS SHARE鎖的事務能訪問該表。也就是說,只有對表的讀動作可以和持有這個鎖模式的事務并發執行。
任何SQL語句都不會在用戶表上自動請求這個鎖模式。然而在某些操作的時候,會在某些系統表上請求它。
例子:兩事務加上SHARE鎖后,不能對表增刪改:
--SESSION?1? begin; --對表locka加上share鎖 lock?table?lcoka?in?share?mode; --等session?2上鎖后,執行以下查詢,預估執行成功 select?*?from?locka;
--SESSION?2? begin; --對表locka加上share鎖 lock?table?locka?in?share?mode; --等session?1上鎖后,執行以下查詢,預估執行成功 select?*?from?locka; --執行完session?1后,執行以下插入操作 insert?into?locka?values?(2);
--SESSION?3? --在另外的終端看后臺的鎖類型 select?a.relname,b.mode?from?pg_class?a?inner?join?pg_locks?b?on?a.oid?=?b.relation?where?relname?=?'locka';
總結
各種SQL操作會自動加持的鎖類型,如下表
VACUUM(不帶FULL選項),ANALYZE命令會自動請求這樣的鎖。其中Vacuum在實驗時從pg_locks的記錄上不持有該類型鎖,但表象是持有的。
我們重溫一下上面鎖沖突圖片,并總結一般場景如下:
1、事務A在操作表結構,如ALTER TABLE,DROP TABLE,TRUNCATE,VACUUM FULL時,其他事務要操作該表只能等待該事務結束
2、事務A在建索引時(CREATE INDEX),其他事務沒辦法進行增刪改操作;能兩個事務同時給一個表進行建索引操作。
3、事務A在對表進行增刪改操作時,能同時在另外的事務中進行VACUUM,ANALYZE操作,互不影響;但具體VACUUM與ANALYZE會因為增刪改的改動導致執行結果不理想,因此我認為這兩者還是不要并發執行。
4、雖然增刪改的鎖在表級鎖層面不沖突,但操作某些行時,行上會有行級鎖。例如事務A刪除行1,事務B刪除行1,兩個事務結束前,必然有一方等待另一方結束。
5、事務A在查詢表A,除非表A在進行DDL與VACUUM FULL等加持ACCESS EXCLUSIVE的鎖,不然都能查詢表A的數據。
與TD數據庫鎖的比較思考:
TD的表級鎖只有4種,ACCESS、READ、WRITE、EXCLUSIVE。是不考慮并發對一個表進行增刪改的。
這個我覺得是因為TD絕大部分都是AP的SQL,沒有這樣的TP場景,這樣的4種鎖能滿足絕大部分的AP場景,所以TD的開發者在考慮鎖的問題的時候就將表級鎖簡化為4種。
GaussDB(DWS)鎖類型考慮了TP場景的,像增刪改的RowExclusiveLock,是能夠并發加持到同一個表的,而TD這4個鎖是不能實現這個場景的,TD的增刪改默認加的WRITE鎖只能一個事務持有。當然了TD里面也有行級鎖,但是使用的場景比較少。
總體來說TD的表級鎖只適合AP場景,GaussDB(DWS)適合AP與TP場景。
以上是這兩天對GaussDB(DWS)的鎖的學習,希望能對讀者有所幫助。
數據倉庫服務 GaussDB(DWS) Gauss AP
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。