Parsing the Blocked Process report

October 20, 2011

As you know the new blocked process report in SQL Server 2005 and beyond is awesome. Now if you have lots of blocked processes being reported it can be a bit overwheleming. How can you quickly tell if it’s the same senario over and over again or if your hitting multiple scenarios. I don’t know about you but I’m cheap and I don’t want to buy a tool so I’ll tell you how to do this yourself.

1) Run a profiler trace for blocked process event on the SQL Instance in question.
2) Save the profile to a table.
3) You need to save the data again from the table in step 2 as xml just use the textdata column but it needs to be an XML Data Type.

Here is a sample.

select DATEDIFF(ss,Starttime,EndTime)DurationInSec,
StartTime,
CONVERT(xml,textdata) As BlockedRPT, Servername
INTO ALLBLOCKS
from dbo.myProfileTable
where EventClass = 137

4) Run the following SQL to get the distinct Blocking and being Blocked statements

SELECT
distinct
X.x.value(‘data(.)’,'varchar(5000)’) AS BlockedSQLcmd,
Y.x.value(‘data(.)’,'varchar(5000)’) AS BlockingSQLcmd
FROM ALLBLOCKS a
CROSS APPLY
blockedRpt.nodes(‘/blocked-process-report/blocked-process/process’) AS X(x)
CROSS APPLY
blockedRpt.nodes(‘/blocked-process-report/blocking-process/process’) AS Y(x)

4) Run the following SQL to get all the details you need about each blocked process report.

SELECT
convert(date,starttime),
X.x.value(‘@currentdb’, ‘nvarchar(45)’) Blockeddb,
X.x.value(‘@waitresource’, ‘nvarchar(45)’) BlockedObject ,
X.x.value(‘@lockMode’, ‘nvarchar(45)’) BlockedBlockLockMode,
X.x.value(‘@hostname’,'nvarchar(45)’) BlockedFromHOst,
X.x.value(‘@loginname’,'nvarchar(45)’) BlockedFromLogin,
X.x.value(‘@isolationlevel’,'nvarchar(45)’) BlockedFromIso,
X.x.value(‘data(.)’,'varchar(5000)’) AS BlockedSQLcmd,

Y.x.value(‘@waitresource’, ‘nvarchar(45)’) BlockingObject ,
Y.x.value(‘@hostname’,'nvarchar(45)’) BlockingFromHOst,
Y.x.value(‘@loginname’,'nvarchar(45)’) BlockingFromLogin,
Y.x.value(‘@isolationlevel’,'nvarchar(45)’) BlockingFromIso,
Y.x.value(‘data(.)’,'varchar(5000)’) AS BlockingSQLcmd
FROM ALLBLOCKS a
CROSS APPLY
blockedRpt.nodes(‘/blocked-process-report/blocked-process/process’) AS X(x)
CROSS APPLY
blockedRpt.nodes(‘/blocked-process-report/blocking-process/process’) AS Y(x)


Blocking Monitor

October 2, 2009

I wanted to share a little something we put together to monitor blocking on our SQL 2005 servers. Every once in awhile the blocking gets out of control and when it does we get these emails so we can quickly jump in and troubleshoot before the Help desk tickets start rolling in.  Create this in your master database be sure to change the database name where it says YOURDB. Create a SQL Server job that runs constantly. In the Job SQL put the following infinite loop to call the proc below:

declare @count int
set @count = 5000000
WHIle @count > 0
BEGIN
waitfor delay ’00:00:15′
exec [Proc_LeadBlocker] 0, ‘YOUR MAIL PROFILE’, ‘Youremail@email.com’
end

 

CREATE  PROCEDURE [dbo].[Proc_LeadBlocker]
(@maxtime int = 0,@MailProfile varchar(100),@recipients varchar(255) )   
as   
--=======================================================================   
-- Proc Name : sp__leadblocker   
-- Description : This procedure will report processes that are blocking   
--    other processes and processes that are being blocked   
--    
-- Author : Motherofallgeeks.com
--=======================================================================   
 
--DECLARE VARIABLES   
DECLARE @BLKemailmsg varchar(1000)   
DECLARE @WAITemailmsg varchar(1000)   
DECLARE @message varchar(max)
   
--CHECK FOR BLOCKING   
IF EXISTS (select 1 FROM sys.dm_exec_requests  
     WHERE Session_ID in
      (SELECT blocking_session_id 
      FROM sys.dm_exec_requests 
      WHERE (wait_time/15000) > @maxtime))    
BEGIN  
 --BUILD BLOCKING PROCESSES EMAIL MSG   
 select @BLKemailmsg = 'The Following Processes are Blocking other Processes:(BLOCKER)  <br>' 
 select @BLKemailmsg = @BLKemailmsg+    
   '<b> SPID: </b>'+ convert(varchar(5),DR.Session_ID) +  '<br>' +
   '<b> STATUS: </b>' + DS.status +    '<br>' +
   ' <b>CMD: </b>' +DR.command+    '<br>' +
   '<b> DB:</b> '+ db_name(DR.database_id) +    '<br>' +
   '<b> LOGIN:</b> '+ DS.login_name +    '<br>' +
   '<b> HOSTNAME:</b> '+ DS.host_name +    '<br>' +
   '<b> LAST_BATCH_TIME: </b>'+ convert(varchar(20),Ds.last_request_Start_time,113)+   '<br>' +
 '<b> wAIT rESOURCE: </b>'+wait_resource + '<br>' +
 '<b> last_wait_type: </b>'+last_wait_type + '<br>' +
   ' <b> SQL Statement: </b>' +  (select name from [YOURDB].sys.objects where object_id=s2.objectid)+ ' '+ SUBSTRING(s2.text,  statement_start_offset / 2, ( (CASE WHEN statement_end_offset = -1 THEN (LEN(CONVERT(nvarchar(max),s2.text)) * 2) ELSE statement_end_offset END)  - statement_start_offset) / 2)    +  --convert(varchar(8000),s2.text) +   '<br>'
   '<HR>'
FROM sys.dm_exec_requests DR  INNER JOIN sys.dm_exec_sessions DS  ON DR.Session_id = DS.Session_id
CROSS APPLY sys.dm_exec_sql_text(dr.sql_handle) AS s2 
WHERE DR.Session_ID in
 (SELECT blocking_session_id
   FROM sys.dm_exec_requests 
   WHERE (wait_time/15000) > @maxtime)   
         
   
 --BUILD WAITING PROCESSES EMAIL MSG   
 select @WAITemailmsg = ' The Following Processes are Waiting for Resources:(BEING BLOCKED) <br> '
 select @WAITemailmsg = @WAITemailmsg +
   '<b> SPID: </b>'+ convert(varchar(5),DR.Session_ID) +    '<br>' +
   '<b>  CMD: </b>' +DR.command+    '<br>'+
   '<b>  DB:</b> '+ db_name(DR.database_id) +   '<br>' + 
   '<b>  LOGIN:</b> '+ DS.login_name +   '<br>' + 
   ' <b> WAITTIME:</b> '+ convert(varchar(4),DR.wait_time/15000)+   '<br>' +
   ' <b> BLOCKED BY:</b> '+ convert(varchar(5),DR.blocking_session_id) +   '<br>'   + 
 '<b> wAIT rESOURCE: </b>'+wait_resource + '<br>' +
 '<b> last_wait_type: </b>'+last_wait_type + '<br>' +
 ' <b> SQL Statement: </b>' +  (select name from [YOURDB].sys.objects where object_id=s2.objectid)+' '+  SUBSTRING(s2.text,  statement_start_offset / 2, ( (CASE WHEN statement_end_offset = -1 THEN (LEN(CONVERT(nvarchar(max),s2.text)) * 2) ELSE statement_end_offset END)  - statement_start_offset) / 2)    + '<br>' --convert(varchar(8000),s2.text) +   '<br>'
FROM sys.dm_exec_requests DR 
INNER JOIN sys.dm_exec_sessions DS  ON DR.Session_id = DS.Session_id
CROSS APPLY sys.dm_exec_sql_text(dr.sql_handle) AS s2 
WHERE   (DR.wait_time/15000) > @maxtime
 and DR.blocking_session_id <> 0
SELECT @message =  @BLKemailmsg + ' ' + @WAITemailmsg
      exec msdb..sp_send_dbmail  @profile_name =  @MailProfile
     ,  @recipients =  @recipients
     ,  @subject =  'Blocking Processes'
     ,  @body_format =  'HTML'
     ,  @body = @message
  ,@query_result_header = 0
 END
--

Follow

Get every new post delivered to your Inbox.