如何捕获和记录SQL Server中发生的死锁
方法一:利用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是我的示例数据库,你可以根据实际情况修改。
go
create table deadlocklog (
id int identity (1, 1) not null,
logdate datetime,
processinfo varchar(10),
errortext varchar(max)
)
go
3.建立job
新建一个job(假设名称为deadlockjob),在"步骤"中新建一步骤,随便写一个步骤名称,数据库为"cole"(见2.建表),在"命令"栏中输入以下语句:
sql code
--新建临时表
if object_id('tempdb.dbo.#errorlog') is not null
drop table #errorlog
create table #errorlog (id int identity (1, 1) not null, a datetime, b varchar(10), c varchar(max))
--将当前日志记录插入临时表
insert into #errorlog exec master.dbo.sp_readerrorlog
--将死锁信息插入用户表
insert deadlocklog
select a, b, c
from #errorlog
where id >= (select max(id) from #errorlog where c like '%deadlock encountered%')
drop table #errorlog
4.新建警报
在"新建警报"窗体的"常规"选项卡中,进行以下设置:
名称:可根据实际自行命名,这里我用deadlockalert
类型:选择"sql server性能条件警报"
对象:sqlserver:locks
计数器:number of deadlocks/sec
实例:_total
计数器满足以下条件时触发警报:高于
值:0
设置完成后,应该如下图所示:
在"响应"选项卡中,选中"执行作业",并选择步骤3中我们新建的作业(即deadlockjob)
到这里为止,我们已经完成了全部步骤,以后,你就可以随时查询deadlocklog表,来显示死锁信息了。
方法二:利用服务器端跟踪。
具体实现步骤如下:
1.编写如下脚本,并执行
sql code
-- 定义参数
declare @rc int
declare @traceid int
declare @maxfilesize bigint
set @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 @on bit
set @on = 1
--下述语句中的148指的是locks:deadlock graph事件(参见sys.trace_events),12指的是spid列(参见sys.trace_columns)
exec sp_trace_setevent @traceid, 148, 12, @on
exec sp_trace_setevent @traceid, 148, 11, @on
exec sp_trace_setevent @traceid, 148, 4, @on
exec sp_trace_setevent @traceid, 148, 14, @on
exec sp_trace_setevent @traceid, 148, 26, @on
exec sp_trace_setevent @traceid, 148, 64, @on
exec sp_trace_setevent @traceid, 148, 1, @on
-- 启动跟踪
exec sp_trace_setstatus @traceid, 1
-- 记录下跟踪id,以备后面使用
select traceid = @traceid
goto 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,就可以看到以图形形式展现的死锁信息了。
推荐阅读
-
如何捕获和记录SQL Server中发生的死锁
-
如何捕获和记录SQL Server中发生的死锁
-
如何捕获和记录SQL Server中发生的死锁_MySQL
-
SQL Server中的锁如何控制并发和控制死锁(内含pb的处理要点)
-
SQL Server中的锁如何控制并发和控制死锁(内含pb的处理要点)
-
SQL Server遍历表中记录的2种方法(使用表变量和游标)
-
SQL Server遍历表中记录的2种方法(使用表变量和游标)
-
SQL Server如何查找表名或列名中包含空格的表和列
-
如何捕获和记录SQL Server中发生的死锁_MySQL
-
SQL Server遍历表中记录的2种方法(使用表变量和游标)