SQL Server 死锁案例分析

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: 当应用程序频繁读写某个表或者资源时,很容易出现死锁现象。出现死锁时,SQL Server会选择终止其中一个事务,并且向发起该事务的客户端发送下面的错误信息。Msg 1205, Level 13, State 47, Line 1Transaction (Process ID 53) was dead

概述

当两个或者多个进程相互阻塞时,形成一个复杂的阻塞链,参与的进程都在等待其他进程放弃其获取到的锁,没有系统的干预,无法解开这个阻塞链,这种情况就是死锁。

有些死锁是意料之内的,可以说是故意为之的。 例如,为了一致性,使用死锁来防止丢失更新。 有一些死锁是意料之外的,由于缺少索引或者事务运行时间较长导致,我们遇到的大部分都是意料之外的死锁。 

SQL Server内部有个死锁的检测机制,当发生死锁时,SQL Server根据会话优先级以及工作量进行评估, 选择终止其中一个事务,解开死锁,并且向发起该事务的客户端发送下面的错误信息。

Error Message

Msg 1205, Level 13, State 47, Line 1Transaction (Process ID 53) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.


死锁发生原理

死锁其实本质上是两个或者多个session互相阻塞。 阻塞的发生,实际上是不同的连接申请的锁互相不兼容而产生的。例如,当一个连接持有X锁时,另外一个连接想要来申请同一资源上面的其他任意的锁,都会被阻塞。SQL Server中锁的兼容性表如下。


案例分析

1. 收集死锁信息

如果是ECS上自建的SQL Server实例,那么很幸运,有种便捷的方法,可以开启trace flag 1222,将死锁实时记录在错误日志中。

DBCC TRACEON(1222,-1)

 

对于RDS SQL Server死锁信息的采集方法,之前在 RDS for SQL Server 死锁处理方法中有详细的描述,例如sys.sysprocesses和SQL Server Profiler,详细步骤在此就不赘述了。

2. 死锁日志分析

一般来说,SQL Server Profiler和1222记录下来的死锁日志是比较全面的。SQL Server Profiler收集死锁日志,消耗性能较高,但是自动显示出死锁图谱,便于分析。
1
对于1222在错误日志中收集死锁信息,可以一直开启,只会在发生死锁是记录在日志中,对性能影响较小,不过分析稍微复杂些。错误日志的分析过程如下:

死锁发生的主要时间段是6月3号10:00至11:38, 10:00:06.16发生的死锁的进程,锁和资源信息如下:

1

进程process89a9a6748 在资源pageid=227126上面持有IX锁,此时process43c824748想要申请该page上的U锁,被阻塞。 同时process43c824748持有pageid=11768上持有U锁,此时process89a9a6748需要申请该页上的U锁,被阻塞。此时,两个进程互相阻塞,形成死锁。

死锁资源 资源1 资源2
资源类型 pagelock pagelock
具体内容 pageid=11768 dbid=37 pageid=227126 dbid=37
持有资源进程 process43c824748 process89a9a6748
等待资源进程 process89a9a6748 process43c824748

进程process89a9a6748执行语句
UPDATE C SET TaskTitle=T.TaskTitle FROM WF.C***Task AS C
INNER JOIN @complateTask AS T
ON T.TaskID=C.TaskID
EXEC WF.PROC_UpdateTask_Opin  @INTRANSACTION,@processID,@isClearUnread,@task,@complateTask,@opin

进程process43c824748执行语句

UPDATE C SET TaskTitle=T.TaskTitle FROM WF.***Task AS C
INNER JOIN @complateTask AS T
ON T.TaskID=C.TaskID
EXEC WF.PROC_**Task_Opin  @INTRANSACTION,@processID,@isClearUnread,@task,@complateTask,@opin

3. 解决意见

上述的死锁问题,根据观察表结构和语句执行计划等信息,建议在表WF.CompletedTask的TaskID字段上面加一个非聚集索引,提升update执行速度,减少U锁的持有时间。


死锁调优建议

由于形成死锁的原因有很多,例如事务运行时间长,导致锁持有时间长或者应用访问资源的顺序混乱,造成频繁锁冲突等。针对常见的死锁情况,建议按照下面的几点进行调优。


1. 查看是否有长时间未提交的事务,及时提交事务。

2. 是否缺少合适索引,导致语句运行较慢。

3. 检查应用程序逻辑,按顺序访问某个资源。

4. 对于S锁参与的情况,使用with(nolock)查询hint,避免申请S锁。例如 select * from table with(nolock)。



相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
3月前
|
SQL 数据库
数据库数据恢复—SQL Server数据库报错“错误823”的数据恢复案例
SQL Server附加数据库出现错误823,附加数据库失败。数据库没有备份,无法通过备份恢复数据库。 SQL Server数据库出现823错误的可能原因有:数据库物理页面损坏、数据库物理页面校验值损坏导致无法识别该页面、断电或者文件系统问题导致页面丢失。
114 12
数据库数据恢复—SQL Server数据库报错“错误823”的数据恢复案例
|
27天前
|
SQL 数据库
gbase 8a 数据库 SQL优化案例-关联顺序优化
gbase 8a 数据库 SQL优化案例-关联顺序优化
|
1月前
|
SQL 数据库 UED
SQL性能提升秘籍:5步优化法与10个实战案例
在数据库管理和应用开发中,SQL查询的性能优化至关重要。高效的SQL查询不仅可以提高应用的响应速度,还能降低服务器负载,提升用户体验。本文将分享SQL优化的五大步骤和十个实战案例,帮助构建高效、稳定的数据库应用。
63 3
|
2月前
|
存储 数据挖掘 数据库
数据库数据恢复—SQLserver数据库ndf文件大小变为0KB的数据恢复案例
一个运行在存储上的SQLServer数据库,有1000多个文件,大小几十TB。数据库每10天生成一个NDF文件,每个NDF几百GB大小。数据库包含两个LDF文件。 存储损坏,数据库不可用。管理员试图恢复数据库,发现有数个ndf文件大小变为0KB。 虽然NDF文件大小变为0KB,但是NDF文件在磁盘上还可能存在。可以尝试通过扫描&拼接数据库碎片来恢复NDF文件,然后修复数据库。
|
1月前
|
SQL 缓存 监控
SQL性能提升指南:五大优化策略与十个实战案例
在数据库性能优化的世界里,SQL优化是提升查询效率的关键。一个高效的SQL查询可以显著减少数据库的负载,提高应用响应速度,甚至影响整个系统的稳定性和扩展性。本文将介绍SQL优化的五大步骤,并结合十个实战案例,为你提供一份详尽的性能提升指南。
51 0
|
2月前
|
SQL 存储 数据可视化
手机短信SQL分析技巧与方法
在手机短信应用中,SQL分析扮演着至关重要的角色
|
2月前
|
SQL 大数据 API
大数据-132 - Flink SQL 基本介绍 与 HelloWorld案例
大数据-132 - Flink SQL 基本介绍 与 HelloWorld案例
60 0
|
3月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
4月前
|
前端开发 Java JSON
Struts 2携手AngularJS与React:探索企业级后端与现代前端框架的完美融合之道
【8月更文挑战第31天】随着Web应用复杂性的提升,前端技术日新月异。AngularJS和React作为主流前端框架,凭借强大的数据绑定和组件化能力,显著提升了开发动态及交互式Web应用的效率。同时,Struts 2 以其出色的性能和丰富的功能,成为众多Java开发者构建企业级应用的首选后端框架。本文探讨了如何将 Struts 2 与 AngularJS 和 React 整合,以充分发挥前后端各自优势,构建更强大、灵活的 Web 应用。
65 0
|
4月前
|
SQL 数据采集 数据挖掘
为什么要使用 SQL 函数?详尽分析
【8月更文挑战第31天】
63 0