前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SQL Server 中的死锁检测

SQL Server 中的死锁检测

原创
作者头像
保持热爱奔赴山海
发布2024-01-20 10:42:32
1340
发布2024-01-20 10:42:32

从 SQL Server 2012 (11.x) 开始,xml_deadlock_report应使用扩展事件 (xEvent),而不是 SQL 跟踪或 SQL 事件探查器中的死锁图事件类。

同样从 SQL Server 2012 (11.x) 开始,当发生死锁时,system_health会话已捕获xml_deadlock_report包含死锁图的所有 xEvent。由于system_health会话默认启用,因此不需要配置单独的 xEvent 会话来捕获死锁信息。无需执行任何其他操作即可使用 xEvent 捕获死锁信息xml_deadlock_report。

注意:

SQL Profiler 创建跟踪,该跟踪已于 2016 年弃用并由扩展事件取代。与跟踪相比,扩展事件的性能开销要少得多,并且可配置性要高得多。考虑使用扩展事件死锁事件而不是跟踪。

案例演示

代码语言:sql
复制
create database test;

use test;

create table tableA(
id int,
value char(100));
create table tableB(
id int,
value char(100));

insert into tableB values(1,'BBB');
insert into tableA values(1,'AAA');

会话1:

代码语言:sql
复制
use test;
BEGIN TRAN

UPDATE tableB
set [value] = 'C2'
WHERE id = 1;

WAITFOR DELAY '00:00:05'

UPDATE tableA
set [value] = 'C1'
WHERE id = 1;

会话2

代码语言:sql
复制
use test;
BEGIN TRAN;

UPDATE tableA
set [value] = 'C1'
WHERE id = 1;

WAITFOR DELAY '00:00:05'

UPDATE tableB
set [value] = 'C2'
WHERE id = 1;

先运行会话1,稍等5秒,再执行会话2, 会话2会提示出现死锁

从2012开始,可以直接在扩展事件里面查看到死锁日志。

方法如下:

右击,筛选器里面填写下面的过滤条件

最后一条这个就是刚才我们模拟的死锁的日志记录

可以看到sql明细

也可以使用下面的sql, 以下查询可以查看system_health会话环形缓冲区捕获的所有死锁事件:

代码语言:sql
复制
SELECT xdr.value('@timestamp', 'datetime') AS [Date],
 xdr.query('.') AS [Event_Data]
FROM (SELECT CAST([target_data] AS XML) AS Target_Data
 FROM sys.dm_xe_session_targets AS xt
 INNER JOIN sys.dm_xe_sessions AS xs ON xs.address = xt.event_session_address
 WHERE xs.name = N'system_health'
 AND xt.target_name = N'ring_buffer'
 ) AS XML_Data
CROSS APPLY 
Target_Data.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData(xdr)
ORDER BY [Date] DESC;

注意这里的date时间是UTC时区,需要加8小时。

最大限度地减少死锁

代码语言:plaintext
复制
尽管无法完全避免死锁,但遵循某些编码约定可以最大程度地减少产生死锁的机会。最大限度地减少死锁可以提高事务吞吐量并减少系统开销,因为更少的事务:
	回滚,撤消事务执行的所有工作。
	由应用程序重新提交,因为它们在死锁时被回滚。
为了帮助最大限度地减少死锁:
	以相同的顺序访问对象。
	避免交易中的用户交互。- 保持交易简短并集中进行。
	使用较低的隔离级别。
	使用基于行版本控制的隔离级别。
	将数据库选项设置READ_COMMITTED_SNAPSHOT为启用以启用读提交事务以使用行版本控制。
	当READ_COMMITTED_SNAPSHOT数据库选项设置为 ON 时,在读已提交隔离级别下运行的事务在读操作期间使用行版本控制而不是共享锁。
	快照隔离还使用行版本控制,它在读取操作期间不使用共享锁。在事务可以在快照隔离下运行之前,ALLOW_SNAPSHOT_ISOLATION必须设置数据库选项ON。
	实现这些隔离级别可以最大限度地减少读取和写入操作之间可能发生的死锁。
	使用快照隔离。
	使用绑定连接。

参考:

https://learn.microsoft.com/en-us/sql/relational-databases/sql-server-deadlocks-guide?view=sql-server-ver16

https://www.mssqltips.com/sqlservertip/5658/capturing-sql-server-deadlocks-using-extended-events/

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 案例演示
    • 会话1:
      • 会话2
        • 先运行会话1,稍等5秒,再执行会话2, 会话2会提示出现死锁
        • 最大限度地减少死锁
        相关产品与服务
        云数据库 SQL Server
        腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档