译码阻塞和死锁的等待资源
常用等待资源介绍
以下表格列出了常用等待资源的格式和意义。
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 ) |
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
输出结果的部分截图如下:
根据ObjectId可以通过系统函数object_name()系统函数匹配到一个表。
SELECT object_name(1573580644)
以上是这个死锁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。
参考: