zoukankan      html  css  js  c++  java
  • 数据库出现阻塞及时邮件预警提醒(下)

    数据库出现阻塞及时邮件预警提醒(上)中我们新建存放阻塞记录的表和收集阻塞的存储过程并配置发送邮件测试ok等事项。

    第四步:创建发送邮件的存储过程,有两种模式,可以根据需要选择

    创建发送阻塞邮件的存储过程

    ---第一种是有附件模式(监控阻塞)
    USE azure_monitor; 
    GO 
    
    IF OBJECT_ID('monitor_p_sent_mail', 'P') IS NOT NULL
        DROP PROCEDURE monitor_p_sent_mail;
    GO
    ----监控库 sql server blocking 的存储过程例子
    /*=============================================
    -- Author:    jil.wen
    -- Create date: 2016/11/16
    -- Description:   新建存储过程发送关于阻塞的邮件;
    -- demo :   exec dbo.monitor_p_sent_mail 
     ============================================= */
    CREATE PROCEDURE monitor_p_sent_mail
    AS
        BEGIN 
    --注意替换库名的修改
            SET NOCOUNT ON;
            IF EXISTS ( SELECT  1
                        FROM    azure_monitor..Monitor_blocking
                        WHERE   blocking_date = ( CONVERT([VARCHAR](100), GETDATE(), ( 23 )) )
                                AND confirm_flag = 0
                                AND [database] = N'替换成实际被监控的库名' )   --替换成实际的库名
                BEGIN 
                    DECLARE @getdate VARCHAR(200);
                    DECLARE @xiangmu VARCHAR(200);
                    SELECT  @xiangmu='某某项目名称'    --替换成实际的项目名称
                    SELECT  @getdate =@xiangmu + '【' + CONVERT(VARCHAR(12), GETDATE(), 112)
                            + ' 出现阻塞预警】';
                    EXEC msdb.dbo.sp_send_dbmail @profile_name = 'monitor_blocking',
                        @recipients = '某某@qq.com;',  ---收件人,多个邮箱用【;】区分
                        @copy_recipients = 'someone@163.com;',  --抄送人
                        @query = 'SELECT  [lock type], [database], [blk object], [lock req], [waiter sid], [wait time], waiter_batch, waiter_stmt, [blocker sid], blocker_stmt, time, blocking_date
        FROM azure_monitor..monitor_blocking WHERE blocking_date=(CONVERT([varchar](100),GETDATE(),(23))) and confirm_flag = 0 and [database]=N''替换成实际被监控的库名''',
                        @subject = @getdate,
                        @body = '各位好,
        数据库已出现阻塞了,如需查看阻塞语句请使用下述脚本:
    		 SELECT [lock type] ,
    				[database] ,
    				[blk object] ,
    				[lock req] ,
    				[waiter sid] ,
    				[wait time] ,
    				waiter_batch ,
    				waiter_stmt ,
    				[blocker sid] ,
    				blocker_stmt ,
    				time ,
    				blocking_date
    		 FROM   azure_monitor..monitor_blocking
    		 WHERE  blocking_date = ( CONVERT([varchar](100), GETDATE(), ( 23 )) ) and confirm_flag = 0 and [database]=N''替换成实际被监控的库名''  --请替换成实际的库名
        
        请及时响应并更改已处理阻塞的处理状态,不然会一直发送预警邮件,建议处理阻塞状态脚本如下语句:
        例如:
    		UPDATE  azure_monitor..Monitor_blocking
    			SET     confirm_flag = 1 ,         --处理标志
    					confirm_user = N''张三'' ,  --更新人
    					confirm_date = GETDATE()    --处理时间
    			WHERE   blocking_date = ( CONVERT([VARCHAR](100), GETDATE(), ( 23 )) ) --阻塞日期
    					AND [database] = N''替换成实际被监控的库名''     --替换成实际的库名
    					AND [time] < DATEADD(MINUTE, -15, GETDATE());             ---当前时间向前推15分钟                                      ',
    			        @attach_query_result_as_file = 1;   
                END; 
            SET NOCOUNT OFF; 
        END; 
    

      

    ---第二种是HTML格式(监控阻塞)

    USE azure_monitor; 
    GO 
    IF OBJECT_ID('monitor_p_sent_mail', 'P') IS NOT NULL
        DROP PROCEDURE monitor_p_sent_mail;
    GO
    ----监控库 sql server blocking 的存储过程例子
    /*=============================================
    -- Author:    jil.wen
    -- Create date: 2016/11/16
    -- Description:   新建存储过程发送关于阻塞的邮件;
    -- demo :   exec dbo.monitor_p_sent_mail 
     ============================================= */
    CREATE PROCEDURE [dbo].[monitor_p_sent_mail]
    AS
        BEGIN 
    --注意替换库名的修改
            SET NOCOUNT ON;
            IF EXISTS ( SELECT  1
                        FROM    azure_monitor..Monitor_blocking
                        WHERE   blocking_date = ( CONVERT([VARCHAR](100), GETDATE(), ( 23 )) )
                                AND confirm_flag = 0
                                AND [database] = N'替换成实际库名' )   --替换成被监控的实际库名
                BEGIN 
                    DECLARE @xml NVARCHAR(MAX);
                    DECLARE @body NVARCHAR(MAX);
                    SET @xml = CAST(( SELECT    [lock type] AS 'td' ,
                                                '' ,
                                                [database] AS 'td' ,
                                                '' ,
                                                [blk object] AS 'td' ,
                                                '' ,
                                                [lock req] AS 'td' ,
                                                '' ,
                                                [waiter sid] AS 'td' ,
                                                '' ,
                                                [wait time] AS 'td' ,
                                                '' ,
                                                waiter_batch AS 'td' ,
                                                '' ,
                                                waiter_stmt AS 'td' ,
                                                '' ,
                                                [blocker sid] AS 'td' ,
                                                '' ,
                                                blocker_stmt AS 'td' ,
                                                '' ,
                                                [time] AS 'td' ,
                                                '' ,
                                                blocking_date AS 'td'
                                      FROM      azure_monitor..Monitor_blocking
                                      WHERE     confirm_flag = 0
                                                AND [database] = N'替换成实际库名'
                                                AND blocking_date = CONVERT([VARCHAR](100), GETDATE(), ( 23 ))
                                    FOR
                                      XML PATH('tr') ,
                                          ELEMENTS
                                    ) AS NVARCHAR(MAX));
                    SET @body = '<html><body><H3>某某项目_Write_DB Blocking Info</H3>
    <table border = 1> 
    <tr>
    <th> lock type </th> <th> database </th> <th> blk object </th> <th> lock req </th><th> waiter sid </th><th> wait time </th><th> waiter_batch </th><th> waiter_stmt </th><th> blocker sid </th><th> blocker_stmt </th><th> time </th><th> blocking_date</th></tr>';    
     
                    SET @body = N'各位好,' + CHAR(13) + CHAR(10)
                        + N'  数据库已出现阻塞了,如需查看阻塞语句请使用下述脚本:' + CHAR(13) + CHAR(10)
                        + N'SELECT [lock type] ,' + CHAR(13) + CHAR(10)
                        + N'[database] ,' + CHAR(13) + CHAR(10)
                        + N'[blk object] ,' + CHAR(13) + CHAR(10)
                        + N'[lock req] ,' + CHAR(13) + CHAR(10)
                        + N'[waiter sid] ,' + CHAR(13) + CHAR(10)
                        + N'[wait time] ,' + CHAR(13) + CHAR(10)
                        + N'waiter_batch ,' + CHAR(13) + CHAR(10)
                        + N'waiter_stmt ,' + CHAR(13) + CHAR(10)
                        + N'[blocker sid] ,' + CHAR(13) + CHAR(10)
                        + N'blocker_stmt ,' + CHAR(13) + CHAR(10) + N'time ,'
                        + CHAR(13) + CHAR(10) + N'blocking_date' + CHAR(13)
                        + CHAR(10) + N' FROM   azure_monitor..monitor_blocking'
                        + CHAR(13) + CHAR(10)
                        + N' WHERE  blocking_date = ( CONVERT([varchar](100), GETDATE(), ( 23 )) ) and confirm_flag = 0 and [database]=N''替换实际库名'''
                        + CHAR(13) + CHAR(10)
                        + N' 请及时响应并更改已处理阻塞的处理状态,不然会一直发送预警邮件,建议处理阻塞状态脚本如下语句:'
                        + CHAR(13) + CHAR(10) + N' 例如:' + CHAR(13) + CHAR(10)
                        + N'	UPDATE  azure_monitor..Monitor_blocking' + CHAR(13)
                        + CHAR(10) + N'		SET     confirm_flag = 1 ,         '
                        + CHAR(13) + CHAR(10)
                        + N'				confirm_user = N''张三'' ,  ' + CHAR(13)
                        + CHAR(10) + N'				confirm_date = GETDATE()    '
                        + CHAR(13) + CHAR(10)
                        + N'		WHERE   blocking_date = ( CONVERT([VARCHAR](100), GETDATE(), ( 23 )) ) '
                        + CHAR(13) + CHAR(10)
                        + N'				AND [database] = N''替换成实际库名''     '
                        + CHAR(13) + CHAR(10) + +@body + @xml
                        + '</table></body></html>';
                    DECLARE @getdate VARCHAR(200);
                    SELECT  @getdate = '【' + CONVERT(VARCHAR(12), GETDATE(), 112)
                            + ' 出现阻塞预警】';
                    EXEC msdb.dbo.sp_send_dbmail @profile_name = 'monitor_blocking',
                        @recipients = '某A@163.com;某B@263.com;某C@QQ.com ;',  ---收件人
                        @copy_recipients = '某D@139.com;',  --抄送人
                        @body = @body, @body_format = 'HTML', @subject = @getdate;
                END; 
            SET NOCOUNT OFF; 
        END; 
    

    第五步:在Agent创建job通过计划定时执行第二步和第四步的存储过程

     

     

    总结

    1.邮件配置设置很重要,密码、端口是否正确,是否有防火墙等,提前验证邮件是否能正常发送成功;可以参考如下脚本辅助排查。
    --SENT MESSAGES LOG
    SELECT TOP 20 *
    FROM [msdb].[dbo].[sysmail_sentitems]
    ORDER BY [send_request_date] DESC--FAILED MESSAGES LOG
    SELECT TOP 20 *
    FROM [msdb].[dbo].[sysmail_faileditems]
    ORDER BY [send_request_date] DESC--ALL MESSAGES – REGARDLESS OF STATUS
    SELECT TOP 20 *
    FROM [msdb].[dbo].[sysmail_allitems]
    ORDER BY [send_request_date] DESC
     
     
    2.邮件能否重复发送基于Agent代理是否正常运转;
    3.如有实例中有多个库,细分对应的人员不同,可以根据数据库名称不同,在job中定义多个step来处理;
    4.注意调用上述脚本的数据库用户权限问题;
    5.注意及时响应,并处理阻塞表中confirm_flag标志问题,避免多次重复发送邮件或已处理阻塞的信息;
    6.如果当前捕获的阻塞或长查询量非常大,可能会造成发送邮件失败,注意关注job历史记录情况;


    参考资料

  • 相关阅读:
    PAT 甲级 1128 N Queens Puzzle
    HDU 1995 R-汉诺塔V
    PAT L1-039 古风排版
    PAT L2-028 秀恩爱分得快
    ZOJ 2060 A-Fibonacci Again
    HDU 2079 选课时间
    HDU 1016 Prime Ring Problem
    理论相关概念原理
    单播字符、字符串收发
    OSAL的原理
  • 原文地址:https://www.cnblogs.com/jil-wen/p/6798892.html
Copyright © 2011-2022 走看看