使用預設system_health分析死結(Deadlock),oracle死結

來源:互聯網
上載者:User

使用預設system_health分析死結(Deadlock),oracle死結

在2008之前我們分析死結需要用profiler trace或者trace flag 1222,1204.在2008中引入了一個新功能:Extended Events(擴充事件),可以監控Deadlock事件,並且效能更好。 

 

而且2008內建了一個預設擴充事件會話system_health,如果你運行在2008或者之上版本可以執行下面查詢: 

 

 select * from sys.dm_xe_sessions

 

其中system_health會收集很多重要的資訊,之後出現問題可以用來分析。system_health會話收集資訊參考http://msdn.microsoft.com/en-us/library/ff877955.aspx。其中一項內容是:Any deadlocks that are detected. 

 

 

也就是SQL Server會自動收集deadlock的資訊,並記錄在ring_buffer。通過分析ring_buffer就可以找到死結原因,這樣就不需要使用profiler或者Trace Flag收集資訊。

 

使用下面的代碼查看deadlock_report的內容:

 

SELECT    xed.value('@timestamp','datetime')as Creation_Date,         xed.query('.')AS Extend_Event FROM    (   SELECT   CAST([target_data]ASXML)AS Target_Data             FROM    sys.dm_xe_session_targetsAS xt                     INNER JOIN sys.dm_xe_sessionsAS xs                     ON xs.address= xt.event_session_address             WHERE    xs.name=N'system_health'                     AND xt.target_name=N'ring_buffer') AS XML_Data CROSS APPLY Target_Data.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]')AS XEventData(xed) ORDER BY Creation_DateDESC


 

 

 

 

預設的system_health在不影響效能的情況下將一些重要事件記錄下來,方便我們後期做分析,這是一個非常好的功能。避免了之前可能由於沒有及時監控而找不到原因的狀況。

 

 


dump 怎分析死結

1、首先構造死結,代碼如下:
public class Deadlocker { private static Object lock_1 = new int[1]; private static Object lock_2 = new int[1]; public class Thread1 extends Thread { @Override public void run() { System.out.println("thread 1 start"); synchronized (lock_1) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread 1 get lock 1 need lock 2"); synchronized (lock_2) { } } System.out.println("thread 1 end"); } } public class Thread2 extends Thread { @Override public void run() { System.out.println("thread 2 start"); synchronized (lock_2) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread 2 get lock 2 need lock 1"); synchronized (lock_1) { } } System.out.println("thread 2 end"); } } public static void main(String[] args) { Thread1 thread1 = new Deadlocker().new Thread1(); Thread2 ......餘下全文>>
 
deadlocks(死結)是什?

在兩個或多個任務中,如果每個任務鎖定了其他任務試圖鎖定資源,此時會造成這些任務永久阻塞,從而出現死結。例如:

事務 A 擷取了行 1 的共用鎖定。

事務 B 擷取了行 2 的共用鎖定。

現在,事務 A 請求行 2 的獨佔鎖定,但在事務 B 完成並釋放其對行 2 持有的共用鎖定之前被阻塞。

現在,事務 B 請求行 1 的獨佔鎖定,但在事務 A 完成並釋放其對行 1 持有的共用鎖定之前被阻塞。

事務 A 必須在事務 B 完成之後才能完成,但事務 B 被事務 A 阻塞。這種情況也稱為循環相依性關係:事務 A 依賴於事務 B,而事務 B 又依賴於事務 A,從而形成了一個迴圈。

除非某個外部進程斷開死結,否則死結中的兩個事務都將無限期等待下去。Microsoft SQL Server Database Engine 死結監視器定期檢查陷入死結的任務。如果監視器檢測到循環相依性關係,將選擇其中一個任務作為犧牲品,然後終止其事務並提示錯誤。這樣,其他任務就可以完成其事務。對於事務以錯誤終止的應用程式,它還可以重試該事務,但通常要等到與它一起陷入死結的其他事務完成後執行。

在應用程式中使用特定編碼約定可以減少應用程式導致死結的機會。有關詳細資料,請參閱將死結減至最少。

死結經常與正常阻塞混淆。事務請求被其他事務鎖定資源的鎖時,發出請求的事務一直等到該鎖被釋放。預設情況下,SQL Server 事務不會逾時(除非設定了 LOCK_TIMEOUT)。因為發出請求的事務未執行任何操作來阻塞擁有鎖的事務,所以該事務是被阻塞,而不是陷入了死結。最後,擁有鎖的事務將完成並釋放鎖,然後發出請求底事務將擷取鎖並繼續執行。

死結有時稱為抱死。

不只是關聯式資料庫管理系統,任何多線程系統上都會發生死結,並且對於資料庫物件的鎖之外的資源也會發生死結。例如,多線程作業系統中的一個線程要擷取一個或多個資源(例如,記憶體塊)。如果要擷取的資源當前為另一線程所擁有,則第一個線程可能必須等待擁有線程釋放目標資源。這就是說,對於該特定資源,等待線程依賴於擁有線程。在資料庫引擎 執行個體中,當擷取非資料庫資源(例如,記憶體或線程)時,會話會死結。

在中,對於 Part 表鎖資源,事務 T1 依賴於事務 T2。同樣,對於 Supplier 表鎖資源,事務 T2 依賴於事務 T1。因為這些依賴關係形成了一個迴圈,所以在事務 T1 和事務 T2 之間存在死結。
 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.