sql server deadlock跟踪的四种方法
最近写程序常会遇到deadlock victim,每次一脸懵逼。研究了下怎么跟踪,写下来记录下。
建测试数据
- CREATE DATABASE testdb;
- GO
- USE testdb;
- CREATE TABLE table1
- (
- id INT IDENTITY PRIMARY KEY,
- student_name NVARCHAR(50)
- )
- INSERT INTO table1 values ('James')
- INSERT INTO table1 values ('Andy')
- INSERT INTO table1 values ('Sal')
- INSERT INTO table1 values ('Helen')
- INSERT INTO table1 values ('Jo')
- INSERT INTO table1 values ('Wik')
- CREATE TABLE table2
- (
- id INT IDENTITY PRIMARY KEY,
- student_name NVARCHAR(50)
- )
- INSERT INTO table2 values ('Alan')
- INSERT INTO table2 values ('Rik')
- INSERT INTO table2 values ('Jack')
- INSERT INTO table2 values ('Mark')
- INSERT INTO table2 values ('Josh')
- INSERT INTO table2 values ('Fred')
第一段sql,先运行只更新table1部分
- USE testdb;
- -- Transaction1
- BEGIN TRAN
- UPDATE table1
- SET student_name = student_name + 'Transaction1'
- WHERE id IN (1,2,3,4,5)
- UPDATE table2
- SET student_name = student_name + 'Transaction1'
- WHERE id = 1
- COMMIT TRANSACTION
第二段sql,只运行更新table2部分
- USE testdb;
- -- Transaction2
- BEGIN TRAN
- UPDATE table2
- SET student_name = student_name + 'Transaction2'
- WHERE id = 1
- UPDATE table1
- SET student_name = student_name + 'Transaction2'
- WHERE id IN (1,2,3,4,5)
- COMMIT TRANSACTION
再运行,第一段sql更新table2,运行第二段sql更新table1,死锁问题重现。
说下跟踪死锁的方法:
1.使用trace log跟踪,执行如下sql开启1222和1204 flag,死锁信息会在sql server 日志中输出。
- DBCC TRACEON (1204, -1)
- DBCC TRACEON (1222, -1)
下图是1204输出的信息
下图是1222输出的信息
2.使用sql server profiler进行跟踪
点击Tools -> sql server profiler 选择sql locks模板
运行当发生死锁时会自动捕获,点击dead lock paragraph查看死锁
3.使用扩展事件跟踪,方法只适用于sql server 2012版本,08r2版本无法直接使用。
依次点击Management -> Extended Events – >system health – >package0.event_file
输入deadlock回车,可以点击details 把内容另存为xdl文件再打开,或点击deadlock查看图
4.使用windows性能计数器检测到死锁再去sql中查询
命令行输入:perfmon 或者 perfmon /sys
选择实例:SQL Server :Locks \\ Number of DeadLocks/sec \\ _Total
实时查看:
下面的查询提供了自从上次重启以来在本服务器上发生的所有死锁:
SELECT cntr_value AS NumOfDeadLocks
FROM sys.dm_os_performance_counters
WHERE object_name = ‘SQLServer:Locks’
AND counter_name = ‘Number of Deadlocks/sec’
AND instance_name = ‘_Total’