首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

DB2 V9.7 鎖事件監控:從被動排查到主動洞察的實戰指南

     編輯:DB2 教學

背景與痛點

大型 DB2 環境多應用競爭資源,鎖機制保障資料完整性。隨應用增多複雜化,診斷鎖爭用極耗時。V9.7 前僅能用 SNAP_GET_LOCKWAIT、GET SNAPSHOT FOR LOCKS、SYSIBMADM.SNAPLOCKWAIT 即時查詢,無法捕捉已超時/死鎖回滾的應用上下文(鎖模式、鎖物件、觸發 SQL)。

V9.7 鎖事件監視器核心能力

  • 鎖定事件發生時自動捕獲描述性資訊
  • 同時記錄請求者(接收死鎖/超時/等待超閾值的應用)與持有者資訊
  • 支援活動類型:SQL(DML/DDL/CALL)、LOAD、REORG、BACKUP、Utility 請求

棄用建議:不再推薦死鎖事件監視器(CREATE EVENT MONITOR FOR DEADLOCKS、DB2DETAILDEADLOCK)與鎖超時回報(DB2_CAPTURE_LOCKTIMEOUT)。新資料庫預設仍建立 DB2DETAILDEADLOCK,建議刪除:

SET EVENT MONITOR DB2DETAILDEADLOCK STATE 0;
DROP EVENT MONITOR DB2DETAILDEADLOCK;

非格式化事件表

V9.7 新寫入目標,效能優於傳統表。事件以二進制寫入,一事件可能多列(不同 record_type)。關鍵欄位:

  • event_data (BLOB) - 核心資料
  • 輔助欄位:appl_id, event_type, event_timestamp, member 等

事後可用 db2evmonfmt、EVMON_FORMAT_UE_TO_XML、EVMON_FORMAT_UE_TO_TABLES 解析。本文採用存儲過程 EVMON_FORMAT_UE_TO_TABLES。

關鍵配置參數

參數可選值與含義
MON_LOCKWAITNONE / WITHOUT_HIST / WITH_HIST(保留 250 筆活動歷程) / HIST_AND_VALUES(含輸入值,不含 LOB/XML/結構化型別)
MON_LW_THRESH產生事件前等待閾值(微秒)
MON_LOCKTIMEOUT同 MON_LOCKWAIT,針對鎖超時事件
MON_DEADLOCK同 MON_LOCKWAIT,針對死鎖事件

建議全設 HIST_AND_VALUES,MON_LW_THRESH=5000000(5 秒):

db2 update db cfg using MON_LOCKTIMEOUT HIST_AND_VALUES MON_DEADLOCK HIST_AND_VALUES MON_LOCKWAIT HIST_AND_VALUES MON_LW_THRESH 5000000

鎖等待事件實戰

建立監視器

db2 create event monitor lockwaitevm for locking write to UNFORMATTED EVENT TABLE
db2 set event monitor lockwaitevm state 1

自動建立同名表儲存捕獲資料。

模擬場景

  • 測試表 stock 授權 public
  • 兩應用 app1(handle 7)、app2(handle 14) 同時更新 itemno=300
  • app1 先執行未 commit 持有 X 鎖,app2 等待超過 5 秒觸發事件

資料解析與查詢

db2 set event monitor lockwaitevm state 0
db2 "call EVMON_FORMAT_UE_TO_TABLES('LOCKING', NULL, NULL, NULL, NULL, NULL, 'RECREATE_FORCE', -1, 'SELECT * FROM lockwaitevm ORDER BY event_timestamp')"

產生四張表:

  • LOCK_EVENT:事件主檔(XMLID 格式 db2LockEvent_<id>_LOCKWAIT_<timestamp>_<partition>)
  • LOCK_PARTICIPANTS:參與者(PARTICIPANT_TYPE Requester/Owner,LOCK_MODE_REQUESTED=5 為 X 鎖,LOCK_OBJECT_TYPE=2 為列鎖)
  • LOCK_PARTICIPANT_ACTIVITIES:參與者活動(ACTIVITY_TYPE current/past,STMT_TEXT 顯示 SQL)
  • LOCK_ACTIVITY_VALUES:活動輸入值

查詢腳本

-- 事件概覽
SELECT substr(XMLID,1,64) XML_id, EVENT_ID, substr(EVENT_TYPE,1,32) evn_type, MEMBER, DL_CONNS, ROLLED_BACK_PARTICIPANT_NO FROM LOCK_EVENT;

-- 參與者詳情
SELECT substr(XMLID,1,64) XML_id, PARTICIPANT_NO, PARTICIPANT_TYPE, PARTICIPANT_NO_HOLDING_LK, APPLICATION_HANDLE, LOCK_WAIT_VAL, LOCK_NAME, LOCK_OBJECT_TYPE, LOCK_ATTRIBUTES, LOCK_CURRENT_MODE, LOCK_MODE_REQUESTED, LOCK_MODE, LOCK_COUNT, LOCK_HOLD_COUNT, LOCK_RRIID, LOCK_STATUS, LOCK_RELEASE_FLAGS, TABLE_FILE_ID, substr(TABLE_NAME,1,10) t_name, TABLE_SCHEMA, TABLESPACE_NAME, THRESHOLD_ID, THRESHOLD_NAME FROM LOCK_PARTICIPANTS;

-- 參與者活動 SQL
SELECT PARTICIPANT_NO, ACTIVITY_TYPE, substr(STMT_TEXT,1,256) sql_text FROM LOCK_PARTICIPANT_ACTIVITIES;

結果解讀

  • LOCK_EVENT:1 筆 LOCKWAIT 事件
  • LOCK_PARTICIPANTS:2 筆,Requester=app2(handle 14) 要求 X 鎖,Owner=app1(handle 7) 持有 X 鎖
  • LOCK_PARTICIPANT_ACTIVITIES:app2 正執行 UPDATE(current),app1 已完成 UPDATE(past)

鎖超時事件實戰

設定會話級超時

db2 "set current lock timeout 30"

重建監視器並觸發

刪除舊事件/表,建立 locktimeout 監視器。app1 更新 itemno=259,app2 同行更新等待 30 秒報 SQL0911N reason code 68(鎖超時)。

解析發現

  • LOCK_EVENT 有兩筆:先發生 LOCKWAIT(超過 5 秒),再發生 LOCKTIMEOUT
  • 參與者同鎖等待事件

死鎖事件實戰

經典死鎖場景

  1. app1 更新 itemno=300(持有資源 A)
  2. app2 更新 itemno=259(持有資源 B)
  3. app1 嘗試更新 itemno=259(請求資源 B,等待)
  4. app2 嘗試更新 itemno=300(請求資源 A,等待)→ 循環等待

監視器建立與觸發

db2 create event monitor lockdead for locking write to UNFORMATTED EVENT TABLE
db2 set event monitor lockdead state 1

依序執行上述 3 步驟 SQL,DB2 死鎖檢測器(預設 10 秒間隔 DLCHKTIME)將發現死鎖並犧牲一受害者回滾。

最佳實踐總結

  • 啟用鎖事件監視器取代舊機制
  • 配置 HIST_AND_VALUES 獲取完整上下文
  • 設定合理 MON_LW_THRESH 避免噪音
  • 善用 EVMON_FORMAT_UE_TO_TABLES 解析為關聯表便於 SQL 分析
  • 重點關注 LOCK_PARTICIPANT_ACTIVITIES 中的 current/past SQL 定位問題根因
  • 死鎖預防:建立統一資源存取順序規範
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved