SQL Server : Number of Deadlocks since Last SQL Server Restart
SELECT sqlserver_start_time AS ServerRestartTime FROM sys.dm_os_sys_info SELECT * FROM sys.dm_os_performance_counters WHERE counter_name = 'Number of Deadlocks/sec' AND instance_name = '_Total' -- Trace Flags to Capture Deadlock Events DBCC TRACESTATUS(1222) DBCC TRACEON(1222,-1) DBCC TRACEOFF(1222,-1)
Extended Events Query:
WITH SystemHealth AS ( SELECT CAST(target_data as xml) AS TargetData FROM sys.dm_xe_session_targets st JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address WHERE name = 'system_health' AND st.target_name = 'ring_buffer') SELECT XEventData.XEvent.query('(data/value/deadlock)[1]') AS DeadLockGraph FROM SystemHealth CROSS APPLY TargetData.nodes('//RingBufferTarget/event') AS XEventData (XEvent) WHERE XEventData.XEvent.value('@name','varchar(4000)') LIKE '%deadlock%'
select XEventData.XEvent.value('(data/value)[1]', 'varchar(max)') as DeadlockGraph, XEventData.XEvent.value('(@timestamp)[1]', 'datetime2') AS TS1 FROM (select CAST(target_data as xml) as TargetData from sys.dm_xe_session_targets st join sys.dm_xe_sessions s on s.address = st.event_session_address where name = 'system_health') AS Data CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent) where XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report'
DEADLOCK Query from Extended Events:
SELECT TOP 10 XEventData.XEvent.value('(data/value)[1]', 'varchar(max)') AS DeadlockGraph , XEventData.XEvent.value('(@timestamp)[1]', 'datetime2') AS TS1 FROM ( SELECT CAST(target_data AS XML) AS TargetData FROM sys.dm_xe_session_targets st WITH ( NOLOCK ) JOIN sys.dm_xe_sessions s WITH ( NOLOCK ) ON s.address = st.event_session_address WHERE name = 'system_health' ) AS Data CROSS APPLY TargetData.nodes('//RingBufferTarget/event') AS XEventData ( XEvent ) WHERE XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report' AND XEventData.XEvent.value('(@timestamp)[1]', 'datetime2') > GETUTCDATE()-2 ORDER BY XEventData.XEvent.value('(@timestamp)[1]', 'datetime2') DESC
Decipher waitresource= “KEY: 27:72057596131278848 (1413e0809b53)”
SELECT DB_NAME(27) AS DatabaseName SELECT OBJECT_NAME(p.object_id) AS TableName , i.name AS IndexName FROM sys.partitions AS p INNER JOIN sys.indexes AS i ON p.object_id = i.object_id AND p.index_id = i.index_id WHERE partition_id = 72057596131278848; -- IF nothing is Changed the key actually exists SELECT * FROM dbo.table1 WHERE %%LOCKRES%% = '{1413e0809b53}'
DBCC Usuage:
DBCC PAGE ( 30 , 1 , 310497 , 2 ) WITH TABLERESULTS DBCC TRACEON ( 3604 ) DBCC PAGE ( 8 , 1 , 591132 , 1 ) DBCC TRACEOFF ( 3604 ) -- PAGE: 8:1:591132 SELECT OBJECT_NAME(1371151930) SELECT OBJECT_NAME(1371151930) -- Proc [Database Id = 8 Object Id = 50099219] -- Proc [Database Id = 8 Object Id = 2021582240] SELECT OBJECT_NAME(50099219) SELECT OBJECT_NAME(2021582240)
SQL Handle to SQL Text :
DECLARE @pStartOffSet INT DECLARE @pEndOffSet INT DECLARE @pSQLHandle VARBINARY(64) SELECT @pSQLHandle = 0x03003800150027147ddafc00dea500000100000000000000 ,@pStartOffSet = 36772,@pEndOffSet = 37296 SELECT SUBSTRING(st.text, (@pStartOffSet/2)+1, ((CASE @pEndOffSet WHEN -1 THEN DATALENGTH(st.text) ELSE @pEndOffSet END - @pStartOffSet)/2) + 1) AS statement_text FROM sys.dm_exec_sql_text(@pSQLHandle) AS st SELECT @pSQLHandle = 0x03003800dcdb3213e1d3fc00dea500000100000000000000 ,@pStartOffSet = 4646,@pEndOffSet = 4896
Object Name from Associated ObjectID:
SELECT OBJECT_NAME(p.object_id) AS TableName , i.name AS IndexName FROM sys.partitions AS p INNER JOIN sys.indexes AS i ON p.object_id = i.object_id AND p.index_id = i.index_id WHERE partition_id = 1611152785;
DBCC Page Results to Object Name:
Paul Randall Blog Link :
http://www.sqlskills.com/blogs/paul/finding-table-name-page-id/
Decipher Waitresource:
Microsoft Link : http://support.microsoft.com/en-us/kb/224453
http://blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleshooting_2c00_-part-1.aspx
This field indicates the resource that a SPID is waiting on. The following table lists common waitresource formats and their meaning:
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:3In 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. |
DeadLock Event Notification
Extended events provide light weight alternative for using profiler. The following example shows how to create queue , service and get notified whenever deadlock occurs.
You get the email notification with the deadlock details attached. Its nice way of knowing the deadlocks in production without pouring over ton of trace logs.
USE msdb GO -- Create a queue to receive messages. CREATE QUEUE queDeadLock_Graph; GO -- Create a service on the queue that references -- the event notifications contract. CREATE SERVICE svcDeadLock_Graph ON QUEUE queDeadLock_Graph ([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]); GO -- Now query the sys.databases for the service_broker_guid of the msdb database. SELECT service_broker_guid FROM sys.databases WHERE name = 'msdb'; CREATE EVENT NOTIFICATION evnDeadLock_Graph ON SERVER WITH FAN_IN FOR DEADLOCK_GRAPH TO SERVICE 'svcDeadLock_Graph' , '36642DC7-A701-4691-8D6A-0E82FE313867'; -- the GUID for msdb goes here USE msdb GO CREATE TABLE dbo.tblDeadLock_Log ( DeadLock_ID int IDENTITY(1,1) CONSTRAINT pk_tblDeadLock_Log PRIMARY KEY , DeadLock_Detected datetime , DeadLock_Graph nvarchar(max) , NoMailReason nvarchar(2048)) GO USE [msdb] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[procReceiveDeadLock_Graph] AS DECLARE @conversation_handle uniqueidentifier DECLARE @message_body xml DECLARE @message_type_name nvarchar(128) DECLARE @deadlock_graph xml DECLARE @event_datetime datetime DECLARE @deadlock_id int DECLARE @DBname sysname BEGIN TRY BEGIN TRAN WAITFOR( RECEIVE TOP(1) @conversation_handle = conversation_handle , @message_body = CONVERT(xml ,message_body) , @message_type_name = message_type_name FROM msdb.dbo.queDeadLock_Graph) , TIMEOUT 10000 -- http://resquel.com/ssb/2010/07/24/ServiceBrokerCanMakeYourTransactionLogBig.aspx -- Validate message IF (@message_type_name = 'http://schemas.microsoft.com/SQL/Notifications/EventNotification' AND @message_body.exist('(/EVENT_INSTANCE/TextData/deadlock-list)') = 1) BEGIN -- Extract the info from the message SELECT @deadlock_graph = @message_body.query('(/EVENT_INSTANCE/TextData/deadlock-list)') , @event_datetime = @message_body.value('(/EVENT_INSTANCE/PostTime)[1]','datetime') , @DBname = DB_NAME(@message_body.value('(//*/process/@currentdb)[1]', 'varchar(10)')) -- Put the info in the table INSERT msdb.dbo.tblDeadLock_Log (DeadLock_Detected, DeadLock_Graph) VALUES (@event_datetime, convert(nvarchar(max),@deadlock_graph) ) SELECT @deadlock_id = SCOPE_IDENTITY() -- Send deadlock alert mail. -- Requires configured database mail, will log an error if not (or anything else goes wrong). BEGIN TRY DECLARE @subj nvarchar(255), @bdy nvarchar(max), @qry nvarchar(max), @attfn nvarchar(255) SELECT @subj = 'A deadlock occurred on ' + @@SERVERNAME + ', on the ' + QUOTENAME(COALESCE(@DBname, 'unknown')) + ' database' , @bdy = 'A deadlock occurred at ' + CONVERT(varchar(50),@event_datetime, 120) + ' on SQL Server: ' + @@SERVERNAME + '. See attached xdl-file for deadlock details.' , @qry = 'SET NOCOUNT ON; SELECT deadlock_graph FROM msdb.dbo.tblDeadLock_Log WITH (READUNCOMMITTED) WHERE DeadLock_ID = ' + CAST(@deadlock_id AS varchar(10)) -- Locking hint is to prevent this dynamic query to be blocked by the lock held by the insert. The dynamic SQL will not come from inside this transaction. , @attfn = @@SERVERNAME + '_' + CAST(@deadlock_id AS varchar(10)) + '.xdl' EXEC sp_send_dbmail @profile_name = 'Raju' , @recipients = '[email protected]' , @subject = @subj , @body = @bdy , @query = @qry , @attach_query_result_as_file = 1 , @query_attachment_filename = @attfn -- http://support.microsoft.com/kb/924345 , @query_result_header = 0 , @query_result_width = 32767 , @query_no_truncate = 1 END TRY BEGIN CATCH UPDATE msdb.dbo.tblDeadLock_Log SET NoMailReason = ERROR_MESSAGE() WHERE DeadLock_ID = @deadlock_id END CATCH END ELSE -- Not an event notification with deadlock-list END CONVERSATION @conversation_handle COMMIT TRAN END TRY BEGIN CATCH ROLLBACK TRAN END CATCH ALTER QUEUE dbo.queDeadLock_Graph WITH STATUS = ON, ACTIVATION ( PROCEDURE_NAME = msdb.dbo.procReceiveDeadLock_Graph, STATUS = ON, MAX_QUEUE_READERS = 1, EXECUTE AS OWNER) GO select * from [dbo].[tblDeadLock_Log create database DeadLock use DeadLock -- Sample Table, which will track individual Orders entered by -- Various Sales Persons create table Orders ( OrderID int, OrderDate datetime, Amount money, SalesPersonID int ) go -- Sample Table, which will track all individual Sales Persons details create table SalesPerson (SalesPersonID int, Name varchar(100), Region varchar(100) ); -- Insert Date in SalesPerson insert SalesPerson Values (1,'Dave Lawlor','California'); insert SalesPerson Values (2,'Mark F','Atlanta'); insert SalesPerson Values (3,'Vivek Pundit','India'); -- Insert Date in Orders Table insert Orders values (101,'2011-01-01', 343,1) insert Orders values (102,'2011-02-01', 35,2) -- TRANSACTION 1 BEGIN TRANSACTION UPDATE Orders SET Amount='100' WAITFOR DELAY'00:00:10' UPDATE SalesPerson SET Region='Bellevue' ROLLBACK TRANSACTION -- TRANSACTION 2 BEGIN TRANSACTION UPDATE SalesPerson SET Region='Bellevue' WAITFOR DELAY '00:00:10' UPDATE Orders SET Amount='100' ROLLBACK TRANSACTION /* Error Message Msg 1205, Level 13, State 45, Line 8 Transaction (Process ID 60) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. */
Deadlock Process Node
In a wait-for graph, the process node contains information about the process. The following table explains the components of a process.
Component DefinitionServer process IdServer process identifier (SPID), a server assigned identifier for the process owning the lock.Server batch IdServer batch identifier (SBID).
Execution context IdExecution context identifier (ECID). The execution context ID of a given thread associated with a specific SPID.ECID = {0,1,2,3, …n}, where 0 always represents the main or parent thread, and {1,2,3, …n} represent the subthreads.
Deadlock priorityDeadlock priority for the process. For more information about possible values, see SET DEADLOCK_PRIORITY (Transact-SQL).
Log UsedAmount of log space used by the process.
Owner Id Transaction ID for the processes which are using transactions and currently waiting on a lock.
Transaction descriptorPointer to the transaction descriptor that describes the state of the transaction.Input bufferInput buffer of the current process, defines the type of event and the statement being executed.
Possible values include:
Language
RPC
None
StatementType of statement. Possible values are:
NOP
SELECT
UPDATE
INSERT
DELETE
Unknown
SQL Handle to SQL Text