天天看點

詳解數倉的鎖相關參數及視圖

摘要: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的邏輯關系如下:

  1. 當ddl_lock_timeout生效,且申請的鎖是八級鎖時,鎖等待逾時報錯的時間為ddl_lock_timeout的值;當申請的鎖不是八級鎖時,鎖等待逾時報錯的時間為lockwait_timeout的值;
  2. 如果參數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時不能進行排序和分組。