摘要:GaussDB(DWS) 中鎖等待可以設定等待逾時相關參數,一旦等鎖的時間超過參數配置值會抛錯。
本文分享自華為雲社群《GaussDB(DWS) 鎖相關參數及視圖詳解》,作者: yd_220527686。
一、鎖相關參數
GaussDB(DWS) 中鎖等待可以設定等待逾時相關參數,一旦等鎖的時間超過參數配置值會抛錯。跟鎖相關的參數有4個,具體含義如下:
1.deadlock_timeout
表示死鎖檢測時間,到達該時間後進行死鎖檢測,預設1秒。
2.lockwait_timeout
當出現表鎖沖突的時候生效,當等待表鎖的時間超過配置的時間,抛錯傳回,預設20分鐘。
3.update_lockwait_timeout
當出現記錄鎖沖突的時候生效,如果等待記錄鎖的時間超過update_lockwait_timeout,抛錯傳回,預設2分鐘。
4.ddl_lock_timeout
當出現八級表鎖沖突的時候生效,當等待擷取八級鎖的時間超過配置的時間,抛錯傳回,預設值為0,表示不生效,需使用者手動開啟(在8.1.3版本及更高版本生效)。
二、鎖相關參數之間的邏輯
在8.1.3版本中,新增加參數ddl_lock_timeout,其優先級高于lockwait_timeout。deadlock_timeout、lockwait_timeout和ddl_lock_timeout的邏輯關系如下:
- 當ddl_lock_timeout生效,且申請的鎖是八級鎖時,鎖等待逾時報錯的時間為ddl_lock_timeout的值;當申請的鎖不是八級鎖時,鎖等待逾時報錯的時間為lockwait_timeout的值;
- 如果參數lockwait_timeout > deadlock_timeout時,同時啟死鎖定時器和鎖逾時定時器。當參數lockwait_timeout <= deadlock_timeout時,隻啟動鎖逾時定時器,不啟動死鎖定時器。
三、建構死鎖和鎖逾時場景示例
建構3個元素的死鎖場景如下:
首先執行第一行(按照session号從小到大執行)然後執行第二行(按照session号從小到大執行),可以通過擷取對應鎖的SQL語句,獲得鎖。表鎖還可以手動的使用SQL語句的方式進行強制上鎖,SQL語句的格式如下所示:
LOCK TABLE [ name ] IN [ lockmode ] MODE;
其中 lockmode 可以是以下之一:
ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
| SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
要注意的是LOCK語句隻能在事務塊中執行,事務結束會釋放。
設定deadlock_timeout、lockwait_timeout和ddl_lock_timeout的值,預期如下:
1.當ddl_lock_timeout = 0,lockwait_timeout>deadlock_timeout > 0:
2.當ddl_lock_timeout = 0,deadlock_timeout>lockwait_timeout > 0:
3.當ddl_lock_timeout != 0,ddl_lock_timeout>deadlock_timeout > 0:
4.當ddl_lock_timeout != 0,deadlock_timeout>ddl_lock_timeout > 0:
5.當ddl_lock_timeout != 0,deadlock_timeout=ddl_lock_timeout > 0:
四、鎖等待查詢
1. 通過查詢pg_locks視圖檢視單個節點的鎖持有和等待狀态,pg_locks視圖的結構如下圖:
locktype | database | relation | page | tuple | virtualxid | transactionid | classid | objid | objsubid | virtualtransaction | pid | mode | granted | fastpath
---------------+----------+----------+------+-------+------------+---------------+---------+-------+----------+--------------------+-----------------+--------------------------+---------+----------
relation | 15835 | 11835 | | | | | | | | 13/3755 | 139776366208768 | AccessShareLock | t | t
virtualxid | | | | | 13/3755 | | | | | 13/3755 | 139776366208768 | ExclusiveLock | t | t
virtualxid | | | | | 12/38 | | | | | 12/38 | 139776382990080 | ExclusiveLock | t | t
virtualxid | | | | | 8/263 | | | | | 8/263 | 139776720103168 | ExclusiveLock | t | t
virtualxid | | | | | 7/314 | | | | | 7/314 | 139776736884480 | ExclusiveLock | t | t
virtualxid | | | | | 5/717 | | | | | 5/717 | 139776778299136 | ExclusiveLock | t | t
transactionid | | | | | | 210480 | | | | 12/38 | 139776382990080 | ExclusiveLock | t | f
relation | 15835 | 16980 | | | | | | | | 12/38 | 139776382990080 | ShareUpdateExclusiveLock | t | f
relation | 15835 | 16980 | | | | | | | | 12/38 | 139776382990080 | ShareRowExclusiveLock | t | f
其中:
locktype:表示鎖類型,包括表鎖、事務鎖、擴充鎖、自定義鎖等;
relation:表示表的oid,如果是表鎖,relation列會顯示表的oid
transactionid:表示事務号,如果是事務鎖,transactionid列會顯示session的事務号
mode:表示鎖級别,級别1-8級;
pid:表示session的線程号;
granted:'t’表示持有鎖,'f’表示等待鎖;
2. 通過pgxc_lockwait_detail和pgxc_wait_detail檢視鎖等待狀态,該方法僅适用于8.1.3及以上版本;
1、pgxc_lockwait_detail系統視圖,顯示每個節點中鎖等待鍊詳細資訊
查詢語句:
select * from pgxc_lockwait_detail;
其中:
level:表示等待鍊中的層級,以1開始,每顯示一層等待關系level會加1。
lock_wait_hierarchy:表示等待鍊,以節點名稱:程序号->幾點名稱:等待程序号->節點名稱:等待程序号->…。
wait_for_pid:表示鎖沖突線程的線程号
conflict_mode:表示鎖沖突線程持有的沖突鎖級别
query:表示查詢語句
2、pgxc_wait_detail系統視圖,顯示所有節點SQL等待從上之下的等待鍊詳細資訊,包括wait_node、query等
查詢語句:
select * from pgxc_wait_detail;
level | lock_wait_hierarchy | node_name | db_name | thread_name | query_id | tid | lwtid | ptid | tlevel | smpid | wait_status | wait_event | exec_cn | wait_node | query | application_name | backend_start | xact_start | query_start | waiting | state
-------+---------------------------------------------------------+--------------+----------+-------------+--------------------+-----------------+-------+------+--------+-------+----------------------------------+------------+---------+--------------+-----------------------------------------------------------------------------------+------------------+-------------------------------+-------------------------------+-------------------------------+---------+--------
1 | cn_5002:140698314475264 | cn_5002 | postgres | OM | 144959613006392061 | 140698314475264 | 21820 | | 0 | 0 | wait node(total 3): dn_6005_6006 | | t | dn_6005_6006 | +| OM | 2022-10-08 18:02:55.810858+08 | 2022-10-08 18:03:10.478458+08 | 2022-10-08 18:02:55.819575+08 | t | active
| | | | | | | | | | | | | | | INSERT INTO scheduler.bandwidth_history_table +| | | | | |
| | | | | | | | | | | | | | | SELECT timestamp, node_name, "rxpck/s", "txpck/s", "rxkB/s", "txkB/s"+| | | | | |
| | | | | | | | | | | | | | | FROM (select '2022-10-08 18:02:55' as timestamp), PGXC_COMM_STATUS; +| | | | | |
| | | | | | | | | | | | | | | | | | | | |
2 | cn_5002:140698314475264 -> dn_6005_6006:140246537033472 | dn_6005_6006 | postgres | cn_5002 | 144959613006392061 | 140246537033472 | 1587 | | 0 | 0 | none | | f | | SELECT * FROM pg_comm_status; | cn_5002 | 2022-10-08 12:01:38.70103+08 | 2022-10-08 18:03:10.478458+08 | 2022-10-08 18:03:10.493286+08 | f | active
其中:
wait_status:目前線程的等待狀态
wait_event:持有此鎖或者在等待此鎖的事務的虛拟id
exec_cn:是否執行sql語句的cn節點
wait_node:鎖級别級别
query:查詢語句
backend_start:後端程序啟動時間,即用戶端連接配接伺服器的時間
xact_start:目前事務的啟動時間
query_start:開始目前活躍查詢的時間
waiting:是否正處于等待狀态
state:後端目前總體狀态
tips:為保證查詢鍊條正确,在使用pgxc_wait_detail和pgxc_lockwait_detail時不能進行排序和分組。