博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
捕获和记录SQL Server中发生的死锁
阅读量:7191 次
发布时间:2019-06-29

本文共 3289 字,大约阅读时间需要 10 分钟。

经带在论坛上看到有人在问怎么捕获和记录死锁信息,在这里,我将自己的一些心得贡献出来,与大家分享,也请各位指正。

我们知道,可以使用SQL Server自带的Profiler工具来跟踪死锁信息。但这种方式有一个很大的敝端,就是消耗很大。据国外某大神测试,profiler甚至可以占到服务器总带宽的35%,所以,在一个繁忙的系统中,使用profiler显然不是一个好主意,下面我介绍两种消耗比较少的方法。其中第二种的消耗最小,在最繁忙的系统中也可使用。第一种最为灵活,可满足多种应用。
方法一:利用SQL Server代理(Alert+Job)
具体步骤如下:
1.首先使用下面的命令,将有关的跟踪标志启用。

 

SQL code
DBCC TRACEON (3605,1204,1222,-1)

说明:
3605 将DBCC的结果输出到错误日志。
1204 返回参与死锁的锁的资源和类型,以及受影响的当前命令。
1222 返回参与死锁的锁的资源和类型,以及使用了不符合任何 XSD 架构的 XML 格式的受影响的当前命令(比1204更进一步,SQL 2005及以上可用)。
-1 以全局方式打开指定的跟踪标记。
以上跟踪标志作用域都是全局,即在SQL Server运行过程中,会一直发挥作用,直到SQL Server重启。
如果要确保SQL Server在重启后自动开启这些标志,可以在SQL Server服务启动选项中,使用 /T 启动选项指定跟踪标志在启动期间设置为开。(位于SQL Server配置管理器->SQL Server服务->SQL Server->属性->高级->启动参数)
在运行上面的语句后,当SQL Server中发生死锁时,已经可以在错误日志中看到了,但还不够直观(和其它信息混在一起)。(SSMS -> SQL Server实例 -> 管理 -> SQL Server日志)
2.建表,存放死锁记录

SQL code
USE[Cole]--Cole是我的示例数据库,你可以根据实际情况修改。 GOCREATETABLE DeadLockLog ( id intIDENTITY (1, 1) NOTNULL, LogDate DATETIME, ProcessInfo VARCHAR(10), ErrorText VARCHAR(MAX) ) GO

 
3.建立JOB
新建一个JOB(假设名称为DeadLockJob),在"步骤"中新建一步骤,随便写一个步骤名称,数据库为"Cole"(见2.建表),在"命令"栏中输入以下语句:

SQL code
--新建临时表 IFOBJECT_ID('tempdb.dbo.#ErrorLog') ISNotNullDROPTABLE #ErrorLog CREATETABLE #ErrorLog (Id intIDENTITY (1, 1) NOTNULL, a DATETIME, b VARCHAR(10), c VARCHAR(MAX)) --将当前日志记录插入临时表 INSERTINTO #ErrorLog EXEC master.dbo.sp_readerrorlog --将死锁信息插入用户表 insert DeadLockLog select a, b, c from #ErrorLog where id >= (selectMAX(id) from #ErrorLog WHERE c Like'%Deadlock encountered%') DROPTABLE #ErrorLog

4.新建警报
在"新建警报"窗体的"常规"选项卡中,进行以下设置:
名称:可根据实际自行命名,这里我用DeadLockAlert
类型:选择"SQL Server性能条件警报"
对象:SQLServer:Locks
计数器:Number of Deadlocks/sec
实例:_Total
计数器满足以下条件时触发警报:高于
值:0
设置完成后,应该如下图所示:
在"响应"选项卡中,选中"执行作业",并选择步骤3中我们新建的作业(即DeadlockJob)
到这里为止,我们已经完成了全部步骤,以后,你就可以随时查询DeadLockLog表,来显示死锁信息了。
方法二:利用服务器端跟踪。
具体实现步骤如下:
1.编写如下脚本,并执行

SQL code
-- 定义参数 declare@rcintdeclare@TraceIDintdeclare@maxfilesizebigintset@maxfilesize=5-- 初始化跟踪 exec@rc= sp_trace_create @TraceID output, 0, N'e:\DbLog\deadlockdetect', @maxfilesize, NULL--此处的e:\dblog\deadlockdetect是文件名(可自行修改),SQL会自动在后面加上.trc的扩展名 if (@rc!=0) goto error -- 设置跟踪事件 declare@onbitset@on=1--下述语句中的148指的是locks:deadlock graph事件(参见sys.trace_events),12指的是spid列(参见sys.trace_columns) exec sp_trace_setevent @TraceID, 148, 12, @onexec sp_trace_setevent @TraceID, 148, 11, @onexec sp_trace_setevent @TraceID, 148, 4, @onexec sp_trace_setevent @TraceID, 148, 14, @onexec sp_trace_setevent @TraceID, 148, 26, @onexec sp_trace_setevent @TraceID, 148, 64, @onexec sp_trace_setevent @TraceID, 148, 1, @on-- 启动跟踪 exec sp_trace_setstatus @TraceID, 1-- 记录下跟踪ID,以备后面使用 select TraceID =@TraceIDgoto finish error: select ErrorCode=@rc finish: go

运行上述语句后,每当SQL Server中发生死锁事件,都会自动往文件e:\DbLog\deadlockdetect.trc中插入一条记录。
2.暂停和停止服务器端跟踪
如果要暂停上面的服务器端跟踪,可运行下面的语句:

SQL code
exec sp_trace_setstatus 1, 0--第一个参数表示TraceID,即步骤1中的输出参数。第二个参数表示将状态改为0,即暂停

如果要停止上面的服务器端跟踪,可运行下面的语句:

SQL code
exec sp_trace_setstatus 1, 2--第一个参数表示TraceID,即步骤1中的输出参数。第二个参数表示将状态改为2,即停止

3.查看跟踪文件内容
对于上面生成的跟踪文件(e:\DbLog\deadlockdetect.trc),可通过两种方法查看:
1).执行t-sql命令

SQL code
select*from fn_trace_gettable('e:\DbLog\deadlockdetect.trc',1)

 
结果中的TextData列即以XML的形式返回死锁的详细信息。
2).在SQL Server Profiler中打开。
依次 进入Profiler -> 打开跟踪文件 ->选择e:\DbLog\deadlockdetect.trc,就可以看到以图形形式展现的死锁信息了。

转载于:https://www.cnblogs.com/zhangchenliang/p/3147151.html

你可能感兴趣的文章
16位纯数字MD5
查看>>
腾讯面试
查看>>
数据备份就用多备份
查看>>
企业如何进行IT基础设施规划
查看>>
我的友情链接
查看>>
iOS面试题第一波
查看>>
在centos中安装puppet和安装过程的一些错误解决
查看>>
html元素
查看>>
使用kaptcha生成验证码
查看>>
Maven学习总结(四)——Maven核心概念
查看>>
python 连接mongodb ,并将EXCEL文档导入mongodb
查看>>
第三节 在shell脚本中进行for循环
查看>>
Java Script 中定义对象的几种方式
查看>>
mysql编译安装完成后,启动时报错The server quit without updating PID file
查看>>
MySQL 错误总结续
查看>>
Nginx并发连接限制
查看>>
BGP的状态
查看>>
javascript声明二维数组
查看>>
ssh 操作 esxi 基本命令
查看>>
微软携手均衡科技提供箱包行业ERP解决方案
查看>>