欢迎投稿

今日深度:

使用默认system_health分析死锁(Deadlock),oracle死锁

使用默认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 之间存在死锁。
 

www.htsjk.Com true http://www.htsjk.com/shujukunews/2632.html NewsArticle 使用默认system_health分析死锁(Deadlock),oracle死锁 在 2008 之前我们分析死锁需要用 profiler trace 或者 trace flag 1222,1204. 在 2008 中引入了一个新功能: Extended Events( 扩展事件 ) ,可以监控 De...
评论暂时关闭