分析DB2數據庫的鎖等待

************所用命令***********

db2pd -d [DBNAME] -locks show detail
db2pd -db [DBNAME] -transactions
db2pd -db [DBNAME] -applications
db2pd -db [DBNAME] -dynamic

db2pd -d [DBNAME] -agents

 

 

  鎖,一個讓人覺得安全又不太方便的技術,在數據庫中發揮着他無可替代的作用,但是,不同的數據庫對其有不同的實現方式。當你習慣一個數據庫的使用方式,去接觸另外一個數據庫時,就會感覺到諸多的不便。每個開始接觸DB2的人,或多或少的都有這樣的感受,數據庫中有那麼多類型的鎖,S,IS,NS,X,IX,SIX,NX,U,Z….從名字上看,很多差不多,如果你能都弄懂他的含義,並且在設計中考慮到,那當然是好的;如果你不是很理解他,沒關係,大多數使用DB2數據庫開發的人都不能完全理解他們,所以,你不用擔心。作爲一個DB2數據庫使用比較習慣的人,這裏分享下如何處理DB2數據庫中的鎖等待問題,幫助大家解決使用DB2過程中遇到的鎖問題。

  下面,使用一個簡單的例子來介紹下如何分析數據庫的中的鎖等待問題。

  場景,查找數據庫鎖等待的根源:

  創建一個簡單的表:

  DB2 "create table test_lock (col int, col2 char(10))"

  開3個命令行的窗口

  在窗口一執行:

  DB2 +c "insert into test_lock values(1,'aaa')"

  DB20000I SQL命令成功完成。

  在窗口二執行:

  DB2 "select * from test_lock"

  我們看到了,很長時間沒有返回,這就是很多人曾經問的一個問題,我執行了一個很簡單的操作,數據庫卡死,不返回,爲什麼?

  我們使用窗口三進行分析:

  DB2 list applications show detail

  XUXIAOF DB2bp.exe 22 *LOCAL.DB2.090817071951 00012 1 0 4764 UOW 正在等待 2009-08-18 10:52:08.685167 IBM-L3F6 SAMPLE C:DB2NODE0000SQL00001

  XUXIAOF DB2bp.exe 68 *LOCAL.DB2.090817075736 00003 1 0 4464 鎖定等待 2009-08-18 10:53:24.329893 IBM-L3F6 SAMPLE C:DB2NODE0000SQL00001

  這個命令永遠是你看鎖問題最簡單實用的一步,數據庫中到底現在存在不存在鎖等待,一看就知道,如果有較長時間Lock-waiting(英文環境)狀態或者鎖定等待(中文環境)狀態,則數據庫存在鎖定等待的應用,如上所示,窗口2不返回的原因可能是鎖等待引起的,現在,我們用DB2pd這個工具,來分析下具體鎖在哪兒,也許,這纔是我們最關心的。

  DB2pd -d sample -locks show detail

  Address TranHdl Lockname Type Mode Sts Owner Dur HoldCount Att ReleaseFlg

  0x7F8911B0 8 03000500040080020000000052 Row .NS W 2 1 0 0x00 0x00000001 TbspaceID 3 TableID 5 PartitionID 0 Page 640 Slot 4

  執行這個命令後,你也許會看到很多的鎖,我爲什麼會找出這條呢?記住,你分析的入手點一定是正在等待的應用程序,也就是上面所列,狀態(Sts)爲W(waiting)的應用,也許在你的環境中你看到了很多,可以逐個分析。

  在這一行中,我們可以得到這些有用信息,Transaction handle爲8 (TranHdl)的應用正在等待03000500040080020000000052(Lockname)這個鎖,這個鎖正被Transaction handle爲2(Owner)的應用佔有。請求的鎖類型爲行上的NS鎖,請求鎖的行是3號表空間中的5號表上,在表空間的第640頁中的第4個槽位。現在,我們看下誰持有這個鎖。

  DB2pd -d sample -locks show detail |find "03000500040080020000000052"

  0x7F890AB0 2 03000500040080020000000052 Row ..X G 2 1 0 0x08 0x40000000 TbspaceID 3 TableID 5 PartitionID 0 Page 640 Slot 4

  0x7F8911B0 8 03000500040080020000000052 Row .NS W 2 1 0 0x00 0x00000001 TbspaceID 3 TableID 5 PartitionID 0 Page 640 Slot 4

  看到如上2行結果,其中一行,是我們剛纔看到的正在等待的應用,而另外一個,狀態爲G(Granted),Transction handler爲2,正是我們要找的,持有鎖沒釋放的根源。如果你看到其他的狀態爲W的鎖,是可能的,因爲可能很多應用都在等這個鎖,我們要找的是持有鎖的應用,通過上一個命令的分析,是Transction handler爲2的應用。

  到此,我們已經找到了是Transaction handle爲2的應用在佔用鎖沒有釋放,可以使用下面的命令來查看下,他到底在執行什麼。

  DB2pd –d sample –transactions

  Transactions:

  Address AppHandl [nod-index] TranHdl Locks State Tflag Tflag2

  Firstlsn Lastlsn LogSpace SpaceReserved TID AxRegCnt GXID

  0x7FC21A80 22[000-00022] 2 3 WRITE 0x00000000 0x00000000 0x000002C1D098 0x000002C1D098 110 174 0x00000000185E 1 0

  查找TranHdl爲2的應用,我們可以看到這樣的信息,這個應用application handle爲22,當前持有3個鎖,狀態爲寫。注意,當LogSpace不爲0的時候,這個應用一定有未提交的更改操作,這個應用使用日誌爲110。下面我們查下這個應用在執行什麼。

  DB2pd -d sample -applications

  Address AppHandl [nod-index] NumAgents CoorEDUID Status C-AnchID C-StmtUID L-AnchID L-StmtUID Appid WorkloadID WorkloadOccID

  0x7AED8080 22[000-00022] 1 4764 UOW-Waiting 0 0 64 1 *LOCAL.DB2.090817071951 1 1

  找application handle爲22的應用,然後查找當前語句的句柄標識和上條語句的句柄標識,我們看到,當前這個應用沒有正在執行的語句,執行的上條語句是L-AnchID爲64, L-StmtUID爲1的語句。我們看下這個語句是什麼?

  DB2pd -d sample –dyn

  Address AnchID StmtUID NumEnv NumVar NumRef NumExe Text

  0x7EAF4370 64 1 0 0 1 1 insert into test_lock values(1,'aaa')。

  通過動態語句的對應(AnchID StmtUID分別爲64和1),我們已經找到了鎖定的根源,正式上面的語句佔用了鎖沒有釋放,導致你執行的查詢語句沒有返回,中間,我們也理解的一些DB2pd的輸出,並會利用這些信息分析問題,如果你使用的是9.5或以上的版本,還可以利用更簡單的方法知道,這個鎖到底在哪一行上,如上面所分析,請求的鎖在3號表空間中的5號表上,在表空間的第640頁中的第4個槽位。現在我們看下,是鎖了哪個對象的哪行記錄:

  DB2 "select tabname from syscat.tables where tbspaceid = 3 and tableid = 5"

  TABNAME

  ------------------------------------------------

  TEST_LOCK

  鎖在TEST_LOCK這個表上,具體是在這個表上的哪行記錄呢?根據數據庫ROWID的組成,pages爲640和slot爲4,如果是large tablespace,則rowid轉換爲整數爲:640*65536+4,如果是regular tablespace,則rowid轉換爲整數爲640*256+4,我使用的是large表空間,所以rowid爲640*65536+4=41943044。

  根據表和rowid可以直接找到這條記錄:

  DB2 "select * from test_lock where rid(test_lock)= 41943044 with ur"

  COL COL2

  ----------- ----------

  1 aaa

  結果和上面分析的一樣,在TEST_LOCK表上的1’aaa’這行記錄上產生的鎖等待。注意,上面的語句要使用with ur來執行,否則,你也同樣鎖等待了。。。。。

  補充一點:

  很多情況下知道數據庫的applications handle後,需要知道到底是業務的哪個進程連接過來執行的,可以使用下面的方法來查:

  DB2pd -d smaple –agents

  Address AppHandl [nod-index] AgentEDUID Priority Type State ClientPid Userid ClientNm Rowsread Rowswrtn LkTmOt DBName

  0x7AB97A90 22[000-00022] 4764 0 Coord Inst-Active 5120

  XUXIAOF DB2bp.exe 245 48 NotSet SAMPLE

  查找application handle爲22的應用,對應的ClientPid爲5120,就是你連接到數據庫上執行這個操作的應用的進程,應用程序的名字(ClientNm)爲DB2bp.exe。

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