sqlserver监控阻塞(死锁)具体情况(转)
公司sqlserver的监控系统主要是采用zabbix监控,但是zabbix的监控只能通过性能计数器给出报警,而无法给出具体的阻塞情况,比如阻塞会话、语句、时间等,所以需要配合sqlserver的一些特性来进行监控,这里给出一个方案:
1.创建阻塞日志表,用于记录阻塞情况
2.新建作业,用于将阻塞情况记录到阻塞日志表中,并发送邮件(如果没有配置邮件,或者不需要发送邮件,可以忽略此步骤)
3.创建警报,当阻塞大于阈值时,触发上面作业
在数据库阻塞值大于阈值时,在原有zabbix的监控上,将阻塞报警以短信和邮件方式发送给dba,同时将阻塞信息记录到阻塞记录表中,将阻塞的具体信息通过邮件形式发送给aba,帮助dba进行系统诊断。
查询阻塞情况依赖于以下sql:

--查询阻塞
SELECT R.session_id AS BlockedSessionID ,
S.session_id AS BlockingSessionID ,
Q1.text AS BlockedSession_TSQL ,
Q2.text AS BlockingSession_TSQL ,
C1.most_recent_sql_handle AS BlockedSession_SQLHandle ,
C2.most_recent_sql_handle AS BlockingSession_SQLHandle ,
S.original_login_name AS BlockingSession_LoginName ,
S.program_name AS BlockingSession_ApplicationName ,
S.host_name AS BlockingSession_HostName
FROM sys.dm_exec_requests AS R
INNER JOIN sys.dm_exec_sessions AS S ON R.blocking_session_id = S.session_id
INNER JOIN sys.dm_exec_connections AS C1 ON R.session_id = C1.most_recent_session_id
INNER JOIN sys.dm_exec_connections AS C2 ON S.session_id = C2.most_recent_session_id
CROSS APPLY sys.dm_exec_sql_text(C1.most_recent_sql_handle) AS Q1
CROSS APPLY sys.dm_exec_sql_text(C2.most_recent_sql_handle) AS Q2

对sql进行测试,表t中只有一条数据。会话1中执行以下sql

会话2执行sql后产生阻塞

用该sql查询的结果:

对于该sql的字段很简单,blocked开头的表示被阻塞的,blocking表示阻塞的。
一.创建阻塞日志表,用于记录阻塞情况

USE etcp_alert
GO
CREATE TABLE [dbo].[BlockLog]
(
Id INT IDENTITY(1, 1)
NOT NULL
PRIMARY KEY ,
[BlockingSessesionId] [smallint] NULL ,
[ProgramName] [nchar](128) NULL ,
[HostName] [nchar](128) NULL ,
[ClientIpAddress] [varchar](48) NULL ,
[DatabaseName] [sysname] NOT NULL ,
[WaitType] [nvarchar](60) NULL ,
[BlockingStartTime] [datetime] NOT NULL ,
[WaitDuration] [bigint] NULL ,
[BlockedSessionId] [int] NULL ,
[BlockedSQLText] [nvarchar](MAX) NULL ,
[BlockingSQLText] [nvarchar](MAX) NULL ,
[dt] [datetime] NOT NULL
)
ON [PRIMARY]
GO

二、新建作业,用于将阻塞情况记录到阻塞日志表中,并发送邮件


在新建作业步骤中,选择数据库tempdb,并插入代码:

SET NOCOUNT ON;
DECLARE @dt DATETIME= GETDATE();
-- 阻塞时间
DECLARE @HtmlContent NVARCHAR(MAX);
--邮件发送的阻塞日志(表格形式) IF OBJECT_ID('tempdb.dbo.#BlockLog') IS NOT NULL
DROP TABLE #BlockLog;
--将当前日志记录插入临时表
BEGIN
SELECT wt.blocking_session_id AS BlockingSessesionId ,
sp.program_name AS ProgramName ,
COALESCE(sp.LOGINAME, sp.nt_username) AS HostName ,
ec1.client_net_address AS ClientIpAddress ,
db.name AS DatabaseName ,
wt.wait_type AS WaitType ,
ec1.connect_time AS BlockingStartTime ,
wt.WAIT_DURATION_MS / 1000 AS WaitDuration ,
ec1.session_id AS BlockedSessionId ,
h1.TEXT AS BlockedSQLText ,
h2.TEXT AS BlockingSQLText ,
@dt dt
INTO #BlockLog
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id
LEFT OUTER JOIN master.dbo.sysprocesses sp ON SP.spid = wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2;
--将临时表数据插入日志表
INSERT INTO etcp_alert.dbo.BlockLog
( BlockingSessesionId ,
ProgramName ,
HostName ,
ClientIpAddress ,
DatabaseName ,
WaitType ,
BlockingStartTime ,
WaitDuration ,
BlockedSessionId ,
BlockedSQLText ,
BlockingSQLText ,
dt
)
SELECT BlockingSessesionId ,
ProgramName ,
HostName ,
ClientIpAddress ,
DatabaseName ,
WaitType ,
BlockingStartTime ,
WaitDuration ,
BlockedSessionId ,
BlockedSQLText ,
BlockingSQLText ,
dt
FROM #BlockLog;
END;
--以html表格方式发送邮件,如果不发送邮件,则删除以下代码
BEGIN
SET @HtmlContent = N'<head>'
+ N'<style type="text/css">h2, body {font-family: Arial, verdana;} table{font-size:11px; border-collapse:collapse;} td{ border:1px solid black; padding:3px;} th{background-color:#99CCFF;}</style>'
+ N'<table border="1">' + N'<tr>
<th>BlockingSessesionId</th>
<th>ProgramName</th>
<th>HostName</th>
<th>ClientIpAddress</th>
<th>DatabaseName</th>
<th>WaitType</th>
<th>BlockingStartTime</th>
<th>WaitDuration</th>
<th>BlockedSessionId</th>
<th>BlockedSQLText</th>
<th>BlockingSQLText</th>
<th>dt</th>
</tr>' + CAST(( SELECT BlockingSessesionId AS TD ,
'' ,
ProgramName AS TD ,
'' ,
HostName AS TD ,
'' ,
ClientIpAddress AS TD ,
'' ,
DatabaseName AS TD ,
'' ,
WaitType AS TD ,
'' ,
BlockingStartTime AS TD ,
'' ,
WaitDuration AS TD ,
'' ,
BlockedSessionId AS TD ,
'' ,
BlockedSQLText AS TD ,
'' ,
BlockingSQLText AS TD ,
'' ,
dt AS Td ,
''
FROM #BlockLog
FOR
XML PATH('tr') ,
TYPE
) AS NVARCHAR(MAX)) + N'</table>';
IF @HtmlContent IS NOT NULL
BEGIN
DECLARE @ProfileName VARCHAR(100)= 'db_mail'; --邮箱公用账户名称
DECLARE @RecipientsLst VARCHAR(100)= '123@123.cn'; --收件人,以";"分隔
DECLARE @subject VARCHAR(100)= '数据库阻塞警报'; --主题
EXEC msdb.dbo.sp_send_dbmail @profile_name = @ProfileName,
@recipients = @RecipientsLst, @subject = @subject,
@body = @HtmlContent, @body_format = 'HTML';
END;
begin
DROP TABLE #BlockLog;
END;
END;

注意,如果没有配置邮箱账号,需要配置邮箱功能,如下:

三、创建警报,当阻塞大于阈值时,触发上面作业
名称:可根据实际自行命名,这里我用数据库阻塞报警
类型:选择"SQL Server性能条件警报"
对象:SQLServer:General Statistics
计数器:Processes blocked
计数器满足以下条件时触发警报:高于
值:2,根据系统具体定

在"响应"中配置,一定将执行作业指向上面创建的job

四、测试
为了测试方便,我将报警阈值调整为高于0个,即当1个阻塞发生时就会触发对应的job,还是采用之前的两个会话,查看报警。
邮箱收到报警:

结果表已经插入数据:

转:
https://www.cnblogs.com/datazhang/p/4773823.html
sqlserver监控阻塞(死锁)具体情况(转)的更多相关文章
- sqlserver监控阻塞(死锁)具体情况
公司sqlserver的监控系统主要是采用zabbix监控,但是zabbix的监控只能通过性能计数器给出报警,而无法给出具体的阻塞情况,比如阻塞会话.语句.时间等,所以需要配合sqlserver的一些 ...
- 第十六章——处理锁、阻塞和死锁(3)——使用SQLServer Profiler侦测死锁
原文:第十六章--处理锁.阻塞和死锁(3)--使用SQLServer Profiler侦测死锁 前言: 作为DBA,可能经常会遇到有同事或者客户反映经常发生死锁,影响了系统的使用.此时,你需要尽快侦测 ...
- SQLServer中的死锁的介绍
简介 什么是死锁? 我认为,死锁是由于两个对象在拥有一份资源的情况下申请另一份资源,而另一份资源恰好又是这两对象正持有的,导致两对象无法完成操作,且所持资源无法释放. 什么又是阻塞? 阻塞是 ...
- SQLServer 查询数据死锁语句
SQLServer 查询数据死锁语句 我们可以通过以下SQL 语句用来查询,当前数据中存在的死锁语句,定位数据库出现死锁的根本原因. --每秒死锁数量 SELECT * FROM sys.dm ...
- SQLSERVER——查看阻塞信息(sp_who_lock优化无误版)
经常会需要分析SQLSERVER的阻塞情况,尤其是某些SQL操作异常缓慢从而怀疑是有人在搞事情的情况下.网上有许多一模一样的帖子,是关于sp_who_lock这个存储过程的,然而,网上流传的这个是略有 ...
- 【SQL Server DBA】日常巡检语句3:特定监控(阻塞、top语句、索引、作业)
原文:[SQL Server DBA]日常巡检语句3:特定监控(阻塞.top语句.索引.作业) 1.查询阻塞信息.锁定了哪些资源 --1.查看阻塞信息 select spid,loginame,wai ...
- 30分钟全面解析-SQL事务+隔离级别+阻塞+死锁
以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础] ...
- SQLSERVER监控复制并使用数据库邮件功能发告警邮件
SQLSERVER监控复制并使用数据库邮件功能发告警邮件 最近熬出病来了,都说IT行业伤不起,不说了,说回今天的正题 正题 上个月月底的时候因为要搬迁机房,需要将一个数据信息数据库先搬到我们的机房,然 ...
- [译]async/await中阻塞死锁
这篇博文主要是讲解在async/await中使用阻塞式代码导致死锁的问题,以及如何避免出现这种死锁.内容主要是从作者Stephen Cleary的两篇博文中翻译过来. 原文1:Don'tBlock o ...
随机推荐
- 2018.10.12 NOIP模拟 数据结构(线段树)
传送门 sb线段树题居然还卡常. 修改操作直接更新区间最小值和区间标记下传即可. 询问加起来最多5e65e65e6个数. 因此直接询问5e65e65e6次最小值就行了. 代码
- 2018.09.26 bzoj1015: [JSOI2008]星球大战starwar(并查集)
传送门 并查集经典题目. 传统题都是把删边变成倒着加边,这道题是需要倒着加点. 处理方法是将每个点与其他点的边用一个vector存起来,加点时用并查集统计答案就行了. 代码: #include< ...
- 2018.09.15 hdu1599find the mincost route(floyd求最小环)
传送门 floyd求最小环的板子题目. 就是枚举两个相邻的点求最小环就行了. 代码: #include<bits/stdc++.h> #define inf 0x3f3f3f3f3f3f ...
- 2018.07.18 [NOI2018]归程(return)(kruskal重构树)
传送门 新鲜出炉的noi2018试题. 下面讲讲这题的解法: 首先要学习一个叫做kruskal重构树的东东. 听名字就知道跟kruskal算法有关,没错,原来的kruskal算法就是用并查集实现的,但 ...
- 实现WIFI MAC认证与漫游
前言 单位里有10来个网件的AP(WNAP210),需要对接入端(主要是手机)进行MAC认证,原来采用AP本地MAC认证,但是人员经常变动(离职),另外人员的岗位(流水线)也经常调整,这样就需在变动后 ...
- hdu 1205 吃糖果【鸽巢原理】
题目 这道题不难,看别人博客的时候发现大家都说用鸽巢原理,这是个什么鬼,于是乎百度之. 1.把某种糖果看做隔板,如果某种糖果有n个,那么就有n+1块区域,至少需要n-1块其他种糖果才能使得所有隔板不挨 ...
- 高并发Web
hadoop适合处理分布式集群系统,本身是支持高速并发海量数据的写入和读取的.解决大量用户并发访问的方案有很多,给你个千万pv的参考方案:1)架构中直接引入软件名称的模块,是个人推荐使用的,如Hapr ...
- js插件开发的一些感想和心得
起因 如果大家平时做过一些前端开发方面的工作,一定会有这样的体会:页面需要某种效果或者插件的时候,我们一般会有两种选择:1.上网查找相关的JS插件,学习其用法2.自己造轮子,开发插件. 寻找存在的插件 ...
- spring mvc配置ObjectMapper忽略无法识别的字段,以及一些博客推荐
通过Spring的MethodInvokingFactoryBean类实现的调用configure方法,此方法返回调用该方法的本身实例. 配置完毕后,可以在spring mvc的消息处理器中使用,为了 ...
- SQL Server 错误:924 解决方法
USE master; GO DECLARE @SQL VARCHAR(MAX); SET @SQL='' SELECT @SQL=@SQL+'; KILL '+RTRIM(SPID) FROM ma ...