DB2 併發場景下,死鎖 是應用邏輯缺陷導致的循環等待,**需修代碼**;鎖等待 是資源爭用導致的性能問題,**需調優化**。本文構建從參數配置、應用排查、快照監控到事件監視器的完整診斷體系 (上篇)。
| 維度 | 死鎖 | 鎖等待 |
|---|---|---|
| 本質 | 循環等待 (A持L1等L2, B持L2等L1) | 線性等待 (A持鎖, B排隊等待) |
| 歸因 | **應用邏輯缺陷** (訪問順序不一致、長事務、缺少索引) | **資源爭用/性能** (高併發、大事務、慢SQL、鎖粒度過粗) |
| DB2行為 | 死鎖檢測器 (DLCHKTIME) 選擇犧牲者回滾 (-911/913) | 等待至 LOCKTIMEOUT 超時報錯 (-911) 或獲取鎖繼續 |
| 解決路徑 | 修正應用訪問順序、縮短事務、添加索引、降低隔離級別 | SQL調優、索引優化、分區/MDC、調整鎖參數、應用重試邏輯 |
# 查看當前配置
db2 get db cfg for | grep -E 'DLCHKTIME|LOCKTIMEOUT|LOCKLIST|MAXLOCKS'
# 關鍵參數:
# DLCHKTIME (毫秒): 死鎖檢測間隔。默認 10000ms (10秒)。建議 5000-10000。
# LOCKTIMEOUT (秒): 鎖等待超時。默認 -1 (無限等待)。**生產必須改為 >0**,如 30-60秒。
# LOCKLIST (4KB頁): 鎖列表內存。自動調整 (AUTOMATIC) 或手動設置 (建議 ≥ 總內存 10-20%)。
# MAXLOCKS (%): 單應用佔用鎖列表上限。默認 10%。大批量操作應用需調大至 50-80%。
db2 update db cfg for using LOCKTIMEOUT 30 DLCHKTIME 5000 (立即生效,無需重啟)。# 查看所有連接
db2 list applications show detail
# 關鍵列解讀:
# Application Handle: 內部句柄 (FORCE APPLICATION 用)
# Application Name: db2bp(CLP), java(JDBC), db2jcc_app(Type2), 用戶自定義
# Application Id: *LOCAL.user.time (本地) / IP端口.user.time (遠程, 16進制IP)
# Sequence #: 單位提交計數
# Status: UOW Executing / UOW Waiting / Lock Waiting / Compiling ...
# 篩選鎖等待應用
db2 "SELECT APPL_ID, APPL_NAME, AUTH_ID, CLIENT_PID, LOCKS_HELD, LOCK_WAITS, LOCK_WAIT_TIME, LOCK_ESCALS
FROM TABLE(MON_GET_APPLICATION(-2)) WHERE LOCK_WAITS > 0"
# 1. 檢查監控開關 (必須開啟 LOCK, UOW, STATEMENT, TABLE)
db2 get monitor switches
# 輸出關鍵:
# Lock Monitoring = ON/OFF (DB2_MON_LOCK / DFT_MON_LOCK)
# Unit of Work Monitoring = ON/OFF
# Statement Monitoring = ON/OFF
# Table Monitoring = ON/OFF
# 2. 開啟開關 (會話級, 即時生效)
db2 "UPDATE MONITOR SWITCHES USING LOCK ON UOW ON STATEMENT ON TABLE ON"
# 3. 獲取鎖快照 (核心診斷數據)
db2 get snapshot for locks on > locks_snap_$(date +%H%M%S).txt
# 4. 關鍵快照字段分析:
# - Lock Name: 鎖標識 (表/行/頁/表空間)
# - Lock Mode: IS/IX/S/X/IN/Z/NS/U ... (意向/共享/排他/超級排他/更新)
# - Lock Status: GRANTED / WAITING / CONVERTING
# - Lock Object: TABLE / ROW / INTERNAL_*
# - Agent ID / Appl ID: 持有者/等待者
# - Lock Wait Start Time: 等待開始時間
# - Deadlocks Detected: 死鎖計數
快照是即時切片,事件監視器提供**持久化、可查詢、可告警**的歷史記錄。
# 1. 創建鎖事件監視器 (寫入表, 便於SQL分析)
db2 "CREATE EVENT MONITOR LOCK_EV FOR LOCKING WRITE TO TABLE"
# 2. 創建死鎖事件監視器 (含詳細死鎖圖)
db2 "CREATE EVENT MONITOR DL_EV FOR DEADLOCKS WRITE TO TABLE"
# 3. 啟用
db2 "SET EVENT MONITOR LOCK_EV STATE 1"
db2 "SET EVENT MONITOR DL_EV STATE 1"
# 4. 核心查詢 (死鎖詳情)
db2 "SELECT DEADLOCK_ID, VICTIM_APPL_ID, VICTIM_STMT_TEXT,
WAITER_APPL_ID, WAITER_STMT_TEXT, HOLDER_APPL_ID, HOLDER_STMT_TEXT,
DL_CONN_ID, DL_TIMESTAMP
FROM DEADLOCK_DETAILS_EV ORDER BY DL_TIMESTAMP DESC FETCH FIRST 20 ROWS ONLY"
# 5. 定期清理/歸檔 (防表膨脹)
# 建立分區表按月分區, 或定期 EXPORT + TRUNCATE
死鎖事件記錄包含:
定位修復:找到環中所有 SQL,分析訪問表順序差異,**統一所有事務對相關表的訪問順序** (如按表名字母序、業務邏輯序),打破環路。
死鎖與鎖等待雖同屬「鎖」,但**死鎖修代碼、鎖等待調性能**。建立 LOCKTIMEOUT>0、DLCHKTIME監控開關全開、事件監視器持久化 四大基線,配合 MON_GET_APPLICATION / MON_GET_LOCKS 表函數實時查詢,構建從「發現→定位→根因→修復→驗證」閉環。下篇將深入實戰案例與高併發設計模式。