如何捕获和记录SQL Server中发生的死锁

 更新时间:2013年06月27日 15:40:36   作者:  
本篇文章是对如何捕获和记录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,就可以看到以图形形式展现的死锁信息了。

相关文章

  • MySQL系列之十五 MySQL常用配置和性能压力测试

    MySQL系列之十五 MySQL常用配置和性能压力测试

    今天给大家带来一篇教程关于MySQL常用配置和性能压力测试的知识,文中配置参数以32内存的服务器为例,通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2021-07-07
  • MySQL深入浅出掌握触发器用法

    MySQL深入浅出掌握触发器用法

    触发器是SQLserver提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,事件是在 MySQL 5.1后引入的,有点类似操作系统的计划任务,但是周期性任务是内置在MySQL服务端执行的
    2022-05-05
  • ubuntu系统中安装mysql5.6(通过二进制)

    ubuntu系统中安装mysql5.6(通过二进制)

    今天工作中需要对一台ubantu的系统安装mysql,因为以前一直使用的是centos,虽然它也是类unix但是和redhat或centos命令上还是有点差别。所以通过网上查阅资料,终于安装成功了,现在将步骤分享给大家,有需要的朋友们可以参考借鉴。
    2016-10-10
  • MySQL配置了双主,是如何避免出现数据回环冲突的

    MySQL配置了双主,是如何避免出现数据回环冲突的

    这篇文章主要介绍了MySQL配置了双主,是如何避免出现数据回环冲突的,帮助大家更好的理解和使用MySQL数据库,感兴趣的朋友可以了解下
    2021-01-01
  • MySQL中delimiter关键字的使用解读

    MySQL中delimiter关键字的使用解读

    这篇文章主要介绍了MySQL中delimiter关键字的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • mysql缓冲和缓存设置详解

    mysql缓冲和缓存设置详解

    本文主要给大家讲解的是mysql优化过程中比较重要的2个参数缓冲和缓存的设置,希望大家能够喜欢
    2016-12-12
  • MySQL启动错误解决方法

    MySQL启动错误解决方法

    本文给大家分享的是mysql启动时报错的排查过程及方法,非常实用,有相同问题的小伙伴可以来参考下
    2016-12-12
  • MySQL数据表分区技术PARTITION详解

    MySQL数据表分区技术PARTITION详解

    在处理大规模数据时,数据库性能的优化变得尤为重要,MySQL提供了一种称为“分区”(Partitioning)的技术,可以显著提高查询效率和管理大型数据库表的能力,本文将详细介绍MySQL中的数据表分区技术,包括其基本概念、类型以及如何实现和维护,需要的朋友可以参考下
    2025-02-02
  • MySQL提高分页效率

    MySQL提高分页效率

    本文分享的这段代码是大数据量时提高分页的效率的测试代码,感兴趣的小伙伴可以参考一下
    2015-10-10
  • MySQL通过存储过程来添加和删除分区的过程(List分区)

    MySQL通过存储过程来添加和删除分区的过程(List分区)

    这篇文章主要介绍了MySQL-通过存储过程来添加和删除分区(List分区),本文通过创建存储过程来添加和删除分区,可以避免在分区存在时添加分区报错,或者分区不存在时删除分区报错的问题,需要的朋友可以参考下
    2023-09-09

最新评论