[鎖死] 從日誌檔中找出 dead lock

[鎖死] 從日誌檔中找出 dead lock

簡單的說 Data lock 有2種, Table lock & Row lock, 如其名差別在於鎖定範圍的不同,

詳請參考 GIPI大: [Software Architecture]談資料鎖定(Data Lock) , Chris: DB2 deadlock monitor

今天分享的場景是

1. 使用者次日才反應

2. 資料庫沒有開Monitor機制

3. 手頭只有應用系統寫出來的SQL日誌檔

4. 案例以DB2為例,且流量不大的企業內部交易系統

 

所以, 我們要做的是依SQL日誌檔來推敲災難現場

要找的是:同時想對某一筆資料做維護的交易。

 

(1) 確認SQL 日誌檔, 除insert/update/delete語法外亦有將Parameter內容印出.

(2) 找到事件發生時間, 即Exception

這個錯誤訊息很清楚,但沒有提到那一個Table 那一筆資料被lock了.

 

範圍就大了,必須以發生時間點, 向前找Timeout的時間, 可以去查DB2的參數: LOCKTIMEOUT

如:13:00:10發生, LOCKTIMEOUT=5, 要捉到 13:00:00 (詳請看參考1)

 

先從同一時間的SQL當成犯人偵訊起,

如:delete from Amount where id = 1268

Table Name:Amount

Column Name:ID

Column Value:1268

 

第一招 先以Column Value的關鍵字, 向上尋找. 運氣好的話可能會到

如:update Amount set price=1000 where id = 1268

然後再確認是不是同一Transaction, 如果不是, 則有8成的把握, 就是他了.

 

第二招 如果第一招沒找到犯人, 應該是交易不是用鍵值維護資料,

因為沒有Snapshot的內容, 就很難找了, 不過不能放棄,

接著我們用Table Name為關鍵字, 向上尋找, UltraEdit的 List Lines Containing String可以幫上很多忙

如:update Amount set price=price+100 where id < 1000

在過程中維護者大腦要把資料的Model記下來, 並有填入可能的資料, 一般用單一鍵值維護的SQL語法還算好處理,

但如果遇到多個條件式進行維護的SQL語法, 就在挑戰自己大腦的記憶體空間及邏輯處理能力.

 

PS. 如果是NULL 如: 1268 這筆資料不存在, 是不會產生Lock的.

 

一般而言, Deadlock是正常的, 但過於頻繁的話, 就很有可能是程式設計的問題,

如: 一個交易(transaction)跑太久, 而它又用到太多的主要資料表. 這時就需要turning將transaction包裝的小而美.

另外, 當Deadlock發生因沒有Monitor機制也沒有Snapshot資料, 用日誌去追蹤其實還是有他的限度, 很難做到100%把握.

所以我們會提問 How to find out the SQL statements causing deadlock? ... 等

再下一題, 就是要加Deadlock的Monitor機制, 不過還是要考慮效能空間等問題.

推一本Diagnose and resolve lock problems with DB2 for Linux, UNIX, and Windows

 

 

參考1: Tuning deadlock and timeout processing

參考2: 請教SQL2005 deadlock 的等待時間