译码阻塞和死锁的等待资源


常用等待资源介绍


以下表格列出了常用等待资源的格式和意义。

Resource

Format

Example

Table

DatabaseID:ObjectID:IndexID

TAB: 5:261575970:1          
In this case, database ID 5 is the pubs sample database and object ID 261575970 is the titles table and 1 is the clustered index.

Page

DatabaseID:FileID:PageID

PAGE: 5:1:104          
In this case, database ID 5 is pubs, file ID 1 is the primary data file, and page 104 is a page belonging to the titles table.            
To identify the object id that the page belongs to, use the DBCC PAGE (dbid, fileid, pageid, output_option) command, and look at the m_objId. For example:

DBCC TRACEON ( 3604 )          
DBCC PAGE ( 5 , 1 , 104 , 3 )

Key

DatabaseID:Hobt_id (Hash value for index key)

KEY: 5:72057594044284928 (3300a4f361aa)          
In this case, database ID 5 is Pubs, Hobt_ID 72057594044284928 corresponds to non clustered index_id 2 for object id 261575970 (titles table). Use the sys.partitions catalog view to associate the hobt_id to a particular index id and object id. There is no way to unhash the index key hash to a specific index key value.

Row

DatabaseID:FileID:PageID:Slot(row)

RID: 5:1:104:3          
In this case, database ID 5 is pubs , file ID 1 is the primary data file, page 104 is a page belonging to the titles table, and slot 3 indicates the row's position on the page.

Compile

DatabaseID:ObjectID `COMPILE`

TAB: 5:834102012 `COMPILE` This is not a table lock, but rather a compile lock on a stored procedure. Database ID 5 is pubs, object ID 834102012 is stored procedure usp_myprocedure. See Knowledge Base Article 263889 for more information on blocking caused by compile locks.


等待资源示例分析


我们开启blocked process report捕获阻塞信息,通过system_health捕获死锁信息。在分析捕获的XML结果时发现,除非将不同类型的等待资源匹配到一个表或索引,否则没有意义。这里,我来完整的分析一个死锁XML文件(见附件),解释下如何将等待资源匹配到一个表或索引。


键等待资源


以下是第一个进程的信息:


键等待资源KEY: 10:72057594048217088的第一部分是数据库id,第二部分是Hobt_Id。根据数据库id通过DB_NAME()函数得到数据库名为CSTS。Hobt是Heap Or B Tree的首字母缩写词。Hobt_id可以通过sys.partitions匹配到sys.indexes和sys.objcets。以下脚本可以匹配键等待资源到相应的索引和表。

USE CSTS
GO
SELECT
o.name AS TableName,
i.name AS IndexName,
SCHEMA_NAME(o.schema_id) AS SchemaName
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 = 72057594048217088


结果如下:


查询原表结构如下:


页等待资源


以下是第二个进程的信息:


页等待资源PAGE: 10:1:5533603的第一部分是数据库id,第二部分是文件id,第三部分是页号。通过以下步骤与这个页相关的对象id。

DBCC traceon (3604)
GO
DBCC page (10, 1, 5533603) --Database_id,file_id,page_id


输出结果的部分截图如下:

译码阻塞和死锁的等待资源_第1张图片


根据ObjectId可以通过系统函数object_name()系统函数匹配到一个表。

SELECT object_name(1573580644)

clip_p_w_picpath009


以上是这个死锁XML的两个进程等待资源。当然,还有其他一些等待资源。


对象等待资源


对象等待资源类似waitresource=”OBJECT: 10:1365579903:22”,第一部分为数据库id,第二部分为对象id,第三部分为锁分区id。对象id可以通过系统函数object_name()匹配到一个对象。锁分区id在阻塞和死锁问题排查中不是很有用。只有当服务器有多于16个CPU时该值才有价值。


行等待资源


行等待资源类似waitresource=”RID: 5:1:166:0”多为堆表行资源,共有4个值,第一部分为数据库id,第二部分为文件id,第三部分为页id,第四部分为槽位号。


表等待资源


表等待资源类似waitresource=”TAB: 5:261575970:1”,第一部分为数据库id,第二部分为对象id,第三部分为索引id。


编译等待资源


编译等待资源类似waitresource=”TAB: 5:834102012 `COMPILE`”,这不是一个表锁,而是一个存储过程上的编译锁。第一部分为数据库id,第二部分为对象id。


参考:

https://support.microsoft.com/en-us/help/224453/inf-understanding-and-resolving-sql-server-blocking-problems