天天看點

關于如何判斷與解決deadlock的問題

目前應用時常會出現deadlock的alert記錄,關于如何判斷與解決deadlock的問題,有一些介紹性的文章值得閱讀。

How to Identify ORA-00060 Deadlock Types Using Deadlock Graphs in Trace (文檔 ID 1507093.1)

        當Oracle檢測到死鎖後,會取消目前檢測到死鎖的SQL執行,并進行語句級復原,以釋放資源,不會阻塞所有活動。檢測到死鎖的session仍舊可用,其它的交易也處于active狀态。如果重複執行這個session的該SQL,那麼會再次檢測到死鎖。

        當檢測到死鎖後,會産生一個trace檔案,其中包含了“Deadlock Graph”(還有别的有用資訊)。

        有時trace中不包含這樣的"Deadlock Graph"節資訊,這種情況下,建議的操作是采集一些額外的診斷資訊(例如10027事件),可參考:Document 1552194.1 ORA-00060 Deadlock Graph Not Matching any Examples: Suggested Next Steps。

"Deadlock Graph“的解釋:

典型的一個"Deadlock Graph"如下:

關于如何判斷與解決deadlock的問題

為了差別不同的類型,可以用鎖類型,以及持有者和等待者的持有/等待模式,為每種類型建立一個辨別。例如,上述圖中展示了如下特征:

1. Deadlock Graph包含超過1行的記錄。

2. 所有的鎖類型都是TX。

3. 持有者和等待者的鎖模式都是X(排它鎖,模式6)。

關注圖中特殊的一些特征:

關于如何判斷與解決deadlock的問題

将會得到如下類型(典型的應用死鎖):

TX X X

注意:對于死鎖類型識别的”關鍵辨別“中最相關的部分就是鎖類型和請求的模式。主要的類型如下表:

關于如何判斷與解決deadlock的問題

注意:如何判斷和診斷不同類型的ORA-00060死鎖的相關資訊,可以參考:Document 1559695.1 How to Diagnose Different ORA-00060 Deadlock Types Using Deadlock Graphs in Trace。

        以上是最常見的類型與原因,極少有不同原因導緻相同現象的情況。如果懷疑特定的非應用死鎖類型或者有其它的deadlock graph,可以送出一個Service Request。

        Oracle鎖類型有如下幾種:

0 - none

1 - null (NULL)

2 - Row Share, also called a subshare table lock  (SS)

3 - Row eXclusive Table Lock, also called a subexclusive table lock (SX)

4 - Share Table Lock (S)

5 - Share Row-eXclusive, also called a share-subexclusive table lock (SSX)

6 - EXclusive (X)

注意:經常可以看到一種混合的deadlock graph:

關于如何判斷與解決deadlock的問題

此時是”Application deadlock“和”Missing Index on Foreign Key (FK) Constraint“的混合。建議先處理非”TX X X“的現象,因為這是一種常見的情況,不常見的FK/ITL/Bitmap可能是根源。

注意:trace檔案中會包含不同的資訊片段,其中有些是和問題相關的,有些則不是。例如,在”Rows Waited on“節,”dictionary objn“的值能用來明确相關的對象,但有時候,會提供毫不相關的資訊。如果資訊有用,那麼就關注它,否則不要依賴于這些資訊。

在目前應用中碰到的死鎖問題是屬于如下類型:

How to Diagnose Different ORA-00060 Deadlock Types Using Deadlock Graphs in Trace (文檔 ID 1559695.1)中介紹了關于”Signature:TX Lock Requesting Mode X (6)(TX X X)"這種類型的鎖:

關于如何判斷與解決deadlock的問題

這種類型deadlock graph的問題有如下特征:

1. Deadlock Graph多于一行。

2. 至少有一行是”TX X X“,例如,鎖類型是TX,鎖的持有者模式是"X",不等待任何。等待者等待"X",不持有任何。

如果deadlock graph包含一些上述未提到的特征,那麼先處理這些問題,因為這些問題可能是根源。

從”Rows waited on“節可以找到”dictionary objn“對應的Object ID。

關于如何判斷與解決deadlock的問題

也可以使用如下SQL查詢Object ID對應的名稱和類型:

關于如何判斷與解決deadlock的問題

trace檔案也應該展示出兩個session正在運作的SQL,還有應用的子產品資訊。在deadlock graph下面的第一部分就是從”Information on the OTHER waiting sessions:"到”End of information on OTHER waiting sessions."之間的部分,展示的是包含于這個deadlock的”Other“ session。

關于如何判斷與解決deadlock的問題

可以抽取如下資訊:

關于如何判斷與解決deadlock的問題
關于如何判斷與解決deadlock的問題

在這節之後,就是檢測到deadlock的session資訊。以及SQL和調用棧(上面圖中最下方),可以從PROCESS STATE節中得到更多關于作業系統程序的資訊。

關于如何判斷與解決deadlock的問題

關于應用、SQL以及運作SQL的程式等等。

關于檢測到deadlock的Oracle和作業系統資訊可以在trace檔案頭中找到。

關于如何判斷與解決deadlock的問題

利用這些資訊可以做什麼?

通過上面的分析,可以得到如下資訊:

1. deadlock中的object名稱。

2. Oracle和作業系統名稱。

3. 作業系統終端與程式細節。

4. 對于持有和等待session運作的SQL。

5. PL/SQL調用棧資訊提供包的細節。

這些資訊可以提供找到包含于deadlock的代碼問題。判斷為什麼會出現deadlock,修改這些代碼或者鎖存儲過程,以至于鎖的順序不會産生deadlock現象。