设为首页 加入收藏

TOP

如何分析SQLServer中的deadlocktrace(一)
2014-11-23 22:21:01 来源: 作者: 【 】 浏览:28
Tags:如何 分析 SQLServer deadlocktrace

关于如何得到deadlock trace,参考:

http://blog.csdn.net/onlyqi/article/details/23172411

首先我们来看一个简单的例子,大结构非常简单:

1,process-list显示了两个进程之间发生了死锁process60fb88和processd11902c8。

2,vistim-list显示了process60fb88被选为了牺牲者。

2,后面的resource-list显示了两个进程争取并导致死锁的资源。


	
		
	
	
		
			
				
				
				
				
			
			

                                    DECLARE @logText NVARCHAR(MAX)

                                    EXEC IntegratedService_ProcessLatestCommand @logText OUTPUT

                                    SELECT @logText   
		
		
			
				
				
				
				
			
			

                                    DECLARE @logText NVARCHAR(MAX)

                                    EXEC IntegratedService_ProcessLatestCommand @logText OUTPUT

                                   SELECT @logText   
		
	
	
		
			
				
			
			
				
			
		
		
			
				
			
			
				
			
		
	
下面是详细分析。

1,victim-list没什么可分析的。

2,process-list中关于各个process的详细信息很重要。

waitresource="KEY: 9:72057597664231424 (7506ff9b7b0d)"

当前process正在等待的资源。通常我们在resource-list中可以看到同样的信息。使用下面的sql查询等待的资源是什么:

SELECT o.name, i.name 
FROM sys.partitions p 
JOIN sys.objects o ON p.object_id = o.object_id 
JOIN sys.indexes i ON p.object_id = i.object_id 
AND p.index_id = i.index_id 
WHERE p.hobt_id = 72057597664231

name name

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

MatchService PK_Matcher_ID
从结果我们就可以知道,等待的资源是一个表MatchService的主键PK_Matcher_ID。考察另外一个process的waitresource我们可以得知等待的资源是同一个表的另外一个索引。

同时可以看到两个process一个是x lock,一个是s lock。因此可以判定发生在该表上的一个修改语句和一个查询语句之间发生了死锁。

另外,上例中可以清晰的看到是keylock导致的死锁,因此查询partitions可以找到对应的object (sys.partitions contains a row for each partition of all the tables and most types of indexes in the database.)。但有时是其他类型的资源发生了死锁,例如pagelock, waitresource="PAGE: 9:1:28440841" 。 9是dbid; 1是fileid; 28440841是pageid。

DBCC TRACEON(3604)
GO
DBCC PAGE (9, 1, 28440841)
GO
DBCC TRACEOFF(3604)
GO
从返回的Metadata: objectId找到对应的objectid。

3,再看process中的inputbuf。这个tag表明了process正在运行的语句,因此对于定位死锁非常重要。但这里有一个问题,比如上例中,inputbuf是一个存储过程,其中又嵌套了很多其他的存储过程,而我们需要在其中找出直接导致死锁的语句并优化,从而解决或减少死锁。自此我们已经有的信息是:导致死锁的语句由inputbuf中的语句调用,同时导致死锁的语句必定是对表MatchService的修改语句。如果存储过程很简单,到此DBA已经能够找到直接导致死锁的sql了,分析过程到此结束。而如果存储过程很复杂,则需要进一步分析。

4,现在再进一步考察tag, executionStack。executionStack表明了死锁发生时,由该process调用的,正在运行的所有sql。上例中有4条sql。同时仔细观察上例可以发生,两个process的executionStack是完全相同的,因此考察一个就可以了。另外,如果procname不为空则直接得到了sql,但上例中该tag为空。

自此我们希望把executionStack中的所有sql显示出来。使用下面的sql找出关于表MatchService的sql的所有sql_handle,然后和executionStack中的sqlhandle对比一下,就找出了导致死锁具体的sql语句。

SELECT sql_handle AS Handle,
SUBSTRING(st.text, (qs.statement_start_offset/2)+1, 
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(st.text)
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS Text
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
WHERE st.text like '%MatcherService%'
order by sql_handle

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

0x030009003D00DA3FA6087C0182A200000100000000000000SELECT TOP 1 @matcherQueueID = lhs.MatcherService_MatcherQueue_ID, @rootOperationUID = Root_Operation_UID FROM MatcherService_MatcherQ

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇SQL语句查询重复字段并按数量排序 下一篇Sqlite3中replace语句用法详解

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: