Technical Article

DB Blocking Automated E-mail Alerting with Blocker SP ID & query's

,

 

step 1.  To enable the blocking alert, you have to create the one monitoring DB with any name, replace the name accordingly in script

 

step 2. create the table DBA_Block_SP_ID

 

step 3. Create the Procedure DBA_spWho2CaptureAlert_Blocking with required change like email ID

 

step 4. Create the procedure DBA_spSendMail with required mail profile update

 

step 5. Create Job (Blocked SP_ID Alerts) 

 

Job will be disabled default, please enable it after checking it end to and test it first at testing environments.

 

Final E_mail will be look like this.

USE [MonitorDB]
GO

/****** Object:  Table [dbo].[DBA_Block_SP_ID]   17-03-2018 ******/
SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[DBA_Block_SP_ID](
[SPID] [int] NULL,
[Status] [varchar](500) NULL,
[Login] [varchar](500) NULL,
[HOSTNAME] [varchar](500) NULL,
[BLKBY] [varchar](500) NULL,
[DBName] [varchar](500) NULL,
[Command] [varchar](500) NULL,
[CPUTime] [bigint] NULL,
[DiskIO] [bigint] NULL,
[LastBatch] [varchar](500) NULL,
[ProgramName] [varchar](500) NULL,
[SPID2] [bigint] NULL,
[REQUESTID] [int] NULL,
[dtCreated] [datetime] NOT NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO





--Create the Procedure

USE [MonitorDB]
GO
/****** Object:  StoredProcedure [dbo].[DBA_spWho2CaptureAlert_Blocking]    Script Date: 22-03-2018 16:19:12 ******/SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*************************************************************************************
AUTHOR:Subhash Chandra
DATE:17-03-2018
PURPOSECAPTURE SP_WHO2 DATA TO TABLE AND ALERT ABOUT BLOCKING

TESTING:
EXEC DBO.DBA_spWho2CaptureAlert_Blocking 
@db = 'Master'
, @TO = 'SOMEONE@SOMEWHERE.COM'

SP_WHO2
select * from DBA_Block_SP_ID 
*************************************************************************************/CREATE PROCEDURE [dbo].[DBA_spWho2CaptureAlert_Blocking]
@DB AS VARCHAR(500) = NULL
, @TO VARCHAR(500) = NULL
AS

SET NOCOUNT ON;

BEGIN TRY
 DROP TABLE #WHO2
END TRY
BEGIN CATCH
 --do nothing
END CATCH

CREATE TABLE #WHO2 (
 SPID INT
 , Status VARCHAR(500)
 , [Login] VARCHAR(500)
 , HOSTNAME VARCHAR(500)
 , BLKBY VARCHAR(500)
 , DBName VARCHAR(500)
 , Command VARCHAR(500)
 , CPUTime BIGINT
 , DiskIO BIGINT
 , LastBatch VARCHAR(500)
 , ProgramName VARCHAR(500)
 , SPID2 BIGINT
 , REQUESTID INT
 ) 

  BEGIN
 select count(*) as 'Total_active_sessions' from sys.dm_exec_requests where session_id>50
  END
DECLARE @SQL VARCHAR(MAX)
SELECT @SQL = 'SP_WHO2'

INSERT INTO #WHO2
EXEC(@SQL)

DELETE FROM DBA_Block_SP_ID
WHERE dtcreated <= DATEADD(DAY,-14,GETDATE())

INSERT INTO DBA_Block_SP_ID --SELECT * FROM DBA_Block_SP_ID
(
SPID
, Status
 , [Login]
 , HOSTNAME
 , BLKBY
 , DBName
 , Command
 , CPUTime
 , DiskIO
 , LastBatch
 , ProgramName
 , SPID2
 , REQUESTID
, dtCreated
)
SELECT 
SPID
, Status
 , [Login]
 , HOSTNAME
 , BLKBY
 , DBName
 , Command
 , CPUTime
 , DiskIO
 , LastBatch
 , ProgramName
 , SPID2
 , REQUESTID
, GETDATE() [dtCreated]
FROM #WHO2
WHERE SPID IN (SELECT ISNULL(REPLACE(REPLACE(CAST(BLKBY AS VARCHAR),' ',''),'.',''),'') [SPID] FROM #WHO2)
OR ISNULL(REPLACE(REPLACE(CAST(BLKBY AS VARCHAR),' ',''),'.',''),'') <> ''
ORDER BY BLKBY, SPID

DECLARE @RECCOUNT INT

IF ISNULL(@DB,'') = ''
 BEGIN
SELECT @RECCOUNT = (
SELECT COUNT(*)
FROM #WHO2
WHERE (SPID IN (SELECT ISNULL(REPLACE(REPLACE(CAST(BLKBY AS VARCHAR),' ',''),'.',''),'') [SPID] FROM #WHO2)
OR ISNULL(REPLACE(REPLACE(CAST(BLKBY AS VARCHAR),' ',''),'.',''),'') <> '')
AND (CAST(SPID AS VARCHAR) <> CAST(BLKBY AS VARCHAR)
AND CAST(BLKBY AS VARCHAR) NOT LIKE '%.%')
)
 END
ELSE
 BEGIN
SELECT @RECCOUNT = (
SELECT COUNT(*)
FROM #WHO2
WHERE (SPID IN (SELECT ISNULL(REPLACE(REPLACE(CAST(BLKBY AS VARCHAR),' ',''),'.',''),'') [SPID] FROM #WHO2)
OR ISNULL(REPLACE(REPLACE(CAST(BLKBY AS VARCHAR),' ',''),'.',''),'') <> '')
AND (CAST(SPID AS VARCHAR) <> CAST(BLKBY AS VARCHAR)
AND CAST(BLKBY AS VARCHAR) NOT LIKE '%.%'
AND DBNAME = @DB)
)
 END

IF @RECCOUNT > 0
 BEGIN

DECLARE @BODY VARCHAR(MAX)
, @POS INT
, @CNTR INT
, @SPID VARCHAR(500)
, @BLKBY VARCHAR(500)
, @EventInfo VARCHAR(MAX)
, @LASTSPID VARCHAR(500)
, @LASTBLKBY VARCHAR(500)
, @LOGIN VARCHAR(500)
, @DBNAME VARCHAR(500)

DECLARE @WHO2MAIL TABLE(
[ID] INT IDENTITY(1,1)
, SPID INT
, BLKBY VARCHAR(500)
, [LOGIN] VARCHAR(500)
, [DBNAME] VARCHAR(500)
) 

INSERT INTO @WHO2MAIL(SPID, BLKBY, [LOGIN], [DBNAME])
SELECT SPID, BLKBY, [LOGIN], [DBNAME]
FROM #WHO2
WHERE SPID IN (SELECT ISNULL(REPLACE(REPLACE(CAST(BLKBY AS VARCHAR),' ',''),'.',''),'') [SPID] FROM #WHO2)
OR ISNULL(REPLACE(REPLACE(CAST(BLKBY AS VARCHAR),' ',''),'.',''),'') <> ''
ORDER BY BLKBY, SPID

BEGIN TRY 
DROP TABLE #INPUTBUFFER
END TRY
BEGIN CATCH
END CATCH

CREATE TABLE #INPUTBUFFER (
EventType VARCHAR(MAX)
, Parameters VARCHAR(MAX)
, EventInfo VARCHAR(MAX)
)

SELECT @POS = 1, @CNTR = MAX([ID]), @BODY = '', @LASTSPID = '', @LASTBLKBY = ''
, @LOGIN = ''
, @DBNAME = ''
FROM @WHO2MAIL
---Put email where you required the DB blocking alering E-mail
SELECT @TO = ISNULL(@TO,'SOMEONE@SOMEWHERE.COM')

WHILE @POS <= @CNTR
  BEGIN
SELECT @SPID = CAST(SPID AS VARCHAR)
, @BLKBY = CAST(BLKBY AS VARCHAR)
, @LOGIN = CAST(ISNULL([LOGIN],'') AS VARCHAR)
, @DBNAME = CAST(ISNULL([DBNAME],'') AS VARCHAR)
FROM @WHO2MAIL
WHERE ID = @POS

TRUNCATE TABLE #INPUTBUFFER

--IF @POS = 1 
-- BEGIN
----Code to capture first person and include in the email can be added here. 
 --END

SELECT @SQL = 'DBCC INPUTBUFFER(' + @SPID + ')'

PRINT @SQL

INSERT INTO #INPUTBUFFER(EventType, Parameters, EventInfo)
EXEC(@SQL)

SELECT @EventInfo = ISNULL(EventInfo,'')
FROM #INPUTBUFFER

if @BODY is not null or @BODY<>''
begin

IF @LASTBLKBY = @BLKBY AND @LASTSPID = @SPID
 BEGIN
SELECT @BODY = @BODY
 END
ELSE
 BEGIN 
SELECT @BODY = @BODY + '<BR><b>' 
+ @SPID + ' IS BEING BLOCKED BY ' + @BLKBY 
+ ' Login: </B style="color:red">' + @LOGIN
+ ' <B style="color:red">DBName: </B>' + @DBNAME
+ '<BR> <B style="color:red">SQL_QUERY:</b> ' + @EventInfo + '<BR>'
, @LASTBLKBY = @BLKBY 
, @LASTSPID = @SPID
 END

 END

SELECT @POS = @POS + 1
 END
  EXEC DBO.DBA_spSendMail-- <--Whatever proc you use to send email... This proc is included below.
@TO = @TO
, @SUBJECT = 'DBA_BLOCKED SPIDS ALERT!!!'
, @BODY = @Body
 END



BEGIN TRY
DROP TABLE #WHO2
END TRY
BEGIN CATCH
END CATCH

BEGIN TRY 
DROP TABLE #INPUTBUFFER
END TRY
BEGIN CATCH
END CATCH



*************************************

--------------------------------------------------------------------------------------------------------
--Proc for sending email using DBMail... You can use yours if you have one instead.
--------------------------------------------------------------------------------------------------------

/**************************************************************************************
NAME:        SUBHASH CHANDRA
DATE:        17-03-2018
PURPOSE:    SEND EMAIL. 

MODIFICATIONS:
    JAW - 17-03-2018 - INITIAL CREATION

NOTES:
    [ @file_attachments = ] 'file_attachments'
Is a semicolon-delimited list of file names to attach to the e-mail message. Files in the list must be specified as absolute paths. 

TESTING:
EXEC DBO.DBA_spSendMail
@TO = 'SOMEONE@SOMEWHERE.COM'
, @SUBJECT = 'TESTING'
, @BODY = 'This is a test'
--, @CC = 'SOMEONE@SOMEWHERE.COM'
--, @BCC = 'SOMEONE@SOMEWHERE.COM'
, @file_attachments = 'C:\SOMEFILE.log'
**************************************************************************************/CREATE PROCEDURE [dbo].[DBA_spSendMail]
@TO VARCHAR(8000)
, @SUBJECT VARCHAR(255)
, @BODY NVARCHAR(max)
, @CC VARCHAR(8000) = NULL
, @BCC VARCHAR(8000) = NULL
, @profile_name VARCHAR(255) = 'PROFILE_NAME'
, @file_attachments NVARCHAR(max) = NULL

AS

SET NOCOUNT ON

-----------------------------------------------------------------------------------------------------
--SELECT @BODY = @BODY + '<br><br>*** SYSTEM ACCOUNT: PLEASE DO NOT REPLY TO THIS MESSAGE ***'
SELECT @BODY = @BODY + '<br><br>*** SYSTEM ACCOUNT (' + CAST(@@SERVERNAME AS VARCHAR) + '): PLEASE DO NOT REPLY TO THIS MESSAGE THANKS DBA TEAM ***'
-----------------------------------------------------------------------------------------------------


--Create Job

----------------------------------------------------------------------------------
-- Job for running this proc every 2 minutes.
----------------------------------------------------------------------------------
GO

USE [msdb]
GO
/****** Object: Job [[MAINT]] Blocked Process ALERT] Script Date: 03/17/2018 10:22:21 ******/BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** Object: JobCategory [[Uncategorized (Local)]]] Script Date: 03/17/2018 10:22:21 ******/IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

END

DECLARE @jobId BINARY(16)
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'Blocked Process Alerts', 
        @enabled=0, --ENABLE THE JOB ONCE YOU GOT EVERYTHING IN PLACE... DEFAULT IS DISABLED.
        @notify_level_eventlog=0, 
        @notify_level_email=2, 
        @notify_level_netsend=0, 
        @notify_level_page=0, 
        @delete_level=0, 
        @description=N'No description available.', 
        @category_name=N'[Uncategorized (Local)]', 
        @owner_login_name=N'sa', 
        @notify_email_operator_name=N'OperatorName', @job_id = @jobId OUTPUT -- <--Your operator name here... 
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object: Step [DUMMY START] Script Date: 03/17/2018 10:22:21 ******/EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'START', 
        @step_id=1, 
        @cmdexec_success_code=0, 
        @on_success_action=3, 
        @on_success_step_id=0, 
        @on_fail_action=3, 
        @on_fail_step_id=0, 
        @retry_attempts=0, 
        @retry_interval=0, 
        @os_run_priority=0, @subsystem=N'TSQL', 
        @command=N'--DO NOTHING', 
        @database_name=N'master', 
        @flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object: Step [EXEC PROC] Script Date: 03/17/2018 10:22:21 ******/EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'EXEC PROC', 
        @step_id=2, 
        @cmdexec_success_code=0, 
        @on_success_action=3, 
        @on_success_step_id=0, 
        @on_fail_action=2, 
        @on_fail_step_id=0, 
        @retry_attempts=1, 
        @retry_interval=1, 
        @os_run_priority=0, @subsystem=N'TSQL', 
        @command=N'EXEC DBO.DBA_spWho2CaptureAlert_Blocking', 
        @database_name=N'master', --Your DB Name where this runs here... 
        @flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object: Step [DUMMY CLOSE] Script Date: 03/17/2018 10:22:21 ******/EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'STOP', 
        @step_id=3, 
        @cmdexec_success_code=0, 
        @on_success_action=1, 
        @on_success_step_id=0, 
        @on_fail_action=1, 
        @on_fail_step_id=0, 
        @retry_attempts=0, 
        @retry_interval=0, 
        @os_run_priority=0, @subsystem=N'TSQL', 
        @command=N'--DO NADA', 
        @database_name=N'master', 
        @flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'EVERY 2 MIN FROM 7 TO 7 - 1', 
        @enabled=1, 
        @freq_type=8, 
        @freq_interval=62, 
        @freq_subday_type=4, 
        @freq_subday_interval=2, 
        @freq_relative_interval=0, 
        @freq_recurrence_factor=1, 
        @active_start_date=20180320, 
        @active_end_date=99991231, 
        @active_start_time=70000, 
        @active_end_time=190000
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
    IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
---------------------------------------------------------------------------------------------------

Rate

2.5 (4)

You rated this post out of 5. Change rating

Share

Share

Rate

2.5 (4)

You rated this post out of 5. Change rating