DB2數據庫鎖超時問題的分析與排查

前言

DB2的鎖管理機制一直爲DB2應用開發人員和DBA所詬病。對其鎖機制不理解的直接後果就是導致鎖超時和死鎖的發生。所以監控並分析鎖超時和死鎖,應是每個DB2 DBA的居家必備生存技能。本文記錄了公司生產環境數據庫發生鎖超時後的分析、處理過程,如有表述不當之處,歡迎指正。

數據庫環境

DB2 pureScale V10.5 FP5。

問題背景

我司生產環境某數據庫每天下午15:40~15:50會報鎖超時。經查明,問題發生時間正好是每日集中跑批時間。

DB2鎖超時設置

爲了能抓到鎖超時的Requestor和Owner,需要對數據庫進行適當配置。

設置TIMEOUT註冊變量

db2set DB2_CAPUTRE_LOCKTIMEOUT=ON

一旦發生鎖超時,會在~/sqllib/db2dump/DIAG000{0,1}/路徑下面生成 db2locktimeout.1.5493.2017-05-25-15-49-01 文件。

設置db2cos

僅有db2locktimeout*文件中的信息不足以定位Lock Requestor的具體語句。因此,我們在生產環境還啓用了db2cos腳本,捕獲更詳細的應用信息。該腳本位於 ~/sqllib/bin/db2cos中。

我們對觸發命令進行了改造,以便抓取更多信息:
微信圖片_20170619133147.jpg
“#”號註釋的命令爲原始命令,此處替換成下一行的新內容。

修改完腳本後,執行以下命令使腳本生效:

db2pdcfg -catch 911,68 count=255

一旦發生鎖超時,便會觸發db2cos腳本,在DIAG目錄下面生成捕獲的文件,
格式爲:$pid.$eduid.$dbpart.db2pd.${database}.txt
例如:202484.5493.001.db2pd.PTSMGMDB.txt

分析鎖超時報告

首先分析db2locktimeout.1.5493.2017-05-25-15-49-01 報告的內容:
微信圖片_20170619133253.png
QQ截圖20170619133527.png
報告裏描述了Lock Requestor和Lock Owner詳細信息,包括鎖超時發生時間,鎖類型(Table lock)和加鎖的資源ID(obj={4;136})。通過表和表空間ID,我們可以執行以下語句定位被鎖的表名:
QQ截圖20170619133616.png
Lock Requestor應用程序名稱爲db2bp,它是CLP後端進程的名稱。但是在db2locktimeout文件中,我們看不到Requestor的語句,這個可以通過查看db2cos腳本抓到的202484.5493.001.db2pd.PTSMGMDB.txt文件得到。

再來看Lock Owner,顯示佔用表的應用是package,可以知道package的名字PTSDAYOFFPUB和版本號V1.1.0_P25,並且當時執行了兩條SQL語句11和12,可以通過SYSCAT.STATEMENTS查找執行語句內容,但是因爲此查詢可能會導致嘗試更新SYSCAT.STATEMENTS目錄視圖的其他應用程序發生競爭,所以查詢時最好使用UR隔離級別。
QQ截圖20170619133647.png
可以發現只有編號位11的查詢table是T_BASE_QWDZLSB ,因此可以確定該語句導致了對錶加鎖,其隔離級別爲CS,會產生一個IS鎖。

再來看下202484.5493.001.db2pd.PTSMGMDB.txt,定位Lock Requestor語句,原始文件中內容很多,我們對其進行了剪裁,提取出關鍵部分。

首先看Locks:段的信息:
微信圖片_20170619133710.jpg

TranHdl 287的Sts爲G,表明佔有鎖;TranHdl 272的Sts爲W*,表明正在等待。接着根據Locks being waited on:段映射TranHdl和AppHandl,知道272的AppHandl爲111774 。
微信圖片_20170619133739.jpg

而111774 當前執行語句信息爲C-AnchID和C-StmtUID爲781和1,根據這兩個值定位到Dynamic SQL Statements:段
微信圖片_20170619133805.png

可以發現執行語句爲LOCK TABLE t_base_qwdzlsb IN EXCLUSIVE MODE 。

同樣可以在Application:段中查看更詳細信息:
微信圖片_20170619133829.jpg
微信圖片_20170619133840.png

至此,可以總結導致鎖超時的root cause:

PTSDAYOFFPUB執行了SELECT * from T_BASE_QWDZLSB語句,對錶加了IS鎖;而後在CLP中又執行了LOCK TABLE t_base_qwdzlsb IN EXCLUSIVE MODE語句(之後發現由IMPORT操作引起),請求一個X表鎖。而IS和X鎖是不兼容的,X鎖會一直等待IS鎖釋放,超過系統設置的30秒超時時間,從而發生鎖超時。
QQ截圖20170619133934.png
QQ截圖20170619133953.png

總結

1、定位造成鎖超時的語句後,我們讓項目組修改了package中的查詢遊標,加上WITH UR,但是鎖超時依舊在報?這是爲什麼呢?

因爲雖然顯式地指定了SQL 語句的隔離級別爲UR,但是,由於DB2中的遊標是模糊遊標 (沒有顯式地聲明遊標是隻讀的還是可更新的),因而系統會默認地將這個模糊遊標當成可更新遊標處理,在 UR 下,可更新遊標的工作方式就像隔離級別爲CS一樣。要避免這種升級,可以採用以下辦法:

修改應用程序中的遊標,使遊標變成非模糊遊標。將 SELECT 語句更改爲SELECT * from table_name FOR READ ONLY WITH UR子句。

2、在報告中看到了Lock Requestor的LOCK TABLE語句,未在腳本或程序裏發現,是什麼引起的?

經過分析,發現該語句是由IMPORT Utility引起。

IMPORT支持兩種表鎖定方式:脫機或ALLOW NO ACCESS方式;以及聯機或ALLOW WRITE ACCESS方式。ALLOW NO ACCESS方式會阻止並行應用程序訪問表數據,ALLOW WRITE ACCESS方式允許並行應用程序同時對導入目標表進行讀寫訪問。如果未顯示指定任何方式,那麼IMPORT默認爲ALLOW NO ACCESS,同時,默認情況下會使用RS綁定數據庫,因此可以改造IMPORT語句:

  1. IMPORT FROM xx.ixf of ixf ALLOW WRITE ACCESS COMMITCOUNT 5000 INSERT INTO table_name

如上所述分析鎖超時的步驟還是很繁瑣的,而且需要一定的技巧和概念基礎,需要:

  • 知道如何抓取鎖超時
  • 瞭解不同隔離級別的區別
  • 瞭解DB2鎖機制
  • 掌握IMPORT,CURSOR等基本操作

但只要多分析,多查資料,就可以將整個分析過程進行流程化,後期就能和自動化運維工作結合起來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章