在两个或多个SQL Server进程中,每一个进程锁定了其他进程试图锁定的资源,就会出现死锁,例如, 进程process1对table1持有1个排它锁(X),同时process1对table2请求1个排它锁(X), 进程process2对table2持有1个排它锁(X),同时process2对table1请求1个排它锁(X)
类似这种情况,就会出现死锁,除非当某个外部进程断开死锁,否则死锁中的两个事务都将无限期等待下去。

Microsoft SQL Server 数据库引擎死锁监视器定期检查陷入死锁的任务。

如果监视器检测到循环依赖关系,将选择其中一个任务作为牺牲品(通常是选择占资源比较小的进程作为牺牲品),然后终止其事务并提示错误1205

这里我们通过SQL Server Profiler来监视分析死锁的发生过程,那样我们就会深刻理解死锁的成因。

1.创建测试表。

在 Microsoft SQL Server Management  Studio上,新建一个查询,写创建表DealLockTest_1 & DealLockTest_2两个表:

脚本:

use Test--创建分析死锁使用到的两个表DealLockTest_1 & DealLockTest_2
go
Set Nocount On
Go
if object_id('DealLockTest_1') Is Not NullDrop Table DealLockTest_1
go
Create Table DealLockTest_1
(ID int Identity(1,1) Primary Key,Name nvarchar(512)
)if object_id('DealLockTest_2') Is Not NullDrop Table DealLockTest_2
go
Create Table DealLockTest_2
(ID int Identity(1,1) Primary Key,Name nvarchar(512)
)Go--插入一些测试数据
Insert Into DealLockTest_1(Name)Select name From sys.all_objectsInsert Into DealLockTest_2(Name)Select name From sys.all_objects
Go

  

创建好表和插入测试数据后,先执行脚本代码(因为我们不需要跟踪该代码),紧接着,我们就模拟两个会话,一个会话里面包含一个事务。这里我们就新建两个查询,其中第一个会话,是更新DealLockTest_1表后,等待5秒钟,更新DealLocktest_2.

Use Test
Go--第一个会话Begin TranUpdate DealLockTest_1Set Name=N'test1'Where ID >0/*这里的Waitfor等待,是为了容易获取死锁的发生*/        Waitfor Delay '00:00:05'Update DealLockTest_2Set Name=N'test2'Where ID >0        Commit TranGo

代码写好后,我们先不要执行代码,接下来就写第二个会话代码; 第二个会话更新表的顺序,刚好与第一个会话相反,是更新DealLockTest_2表后,等待5秒钟,更新DealLocktest_1.

代码

Use Test
Go--第二个会话Begin TranUpdate DealLockTest_2Set Name=N'test1'Where ID >0/*这里的Waitfor等待,是为了容易获取死锁的发生*/                Waitfor Delay '00:00:05'            Update DealLockTest_1Set Name=N'test2'Where ID >0        Commit TranGo

第二个会话代码,也先不要执行。

2.启动SQL Server Profiler,创建Trace(跟踪).

启动SQL Server Profiler工具(在Microsoft SQL Server Management  Studio的工具菜单上就发现它),创建一个Trace,Trace属性选择主要是包含:

Deadlock graph Lock: Deadlock Lock: Deadlock Chain RPC:Completed SP:StmtCompleted SQL:BatchCompleted SQL:BatchStarting

点执行按钮,启动Trace。

3.执行测试代码&监视死锁。

转到 Microsoft SQL Server Management  Studio界面,执行第一个会话&第二个会话的代码,稍稍等待5秒钟,我们就会发现其中一个会话收到报错消息

我们再切换到SQL Server Profiler界面,就能发现SQL Server Profiler收到执行脚本过程发生死锁的信息。

OK,这里就先停止SQL Server Profiler上的“暂停跟踪” Or "停止跟踪"按钮,下面我们具体分析死锁发生过程。

4.分析死锁

如下图,我们可以看到第一个会话在SPID 54,第二个会话在SPID 55,一旦SQL Server发现死锁,它就会确定一个优胜者,可成功执行,和另一个作为牺牲品,要回滚。

可以到看到EventClass列中,两条SQL:BatchCompleted事件紧跟在Lock:DealLock后面,其中一条,它就是作为牺牲品,它会被回滚.而另一条SQL:BatchCompleted将会是优胜者,成功执行。

那么,谁是优胜者,谁是牺牲品呢? 不用着急,通过DealLock graph事件,所返回来的信息,我们可以知道结果。

我们虽然不能明白DealLock graph图示的含义,但通过图中描述的关系,我们知道一些有用的信息。图中左右两旁椭圆形相当一个处理节点(Process Node),当鼠标移动到上面的时候,可以看到内部执行的代码,如Insert,UPdate,Delete.有打叉的左边椭圆形就是牺牲者,没有打叉的右边椭圆形是优胜者。中间两个长方形就是一个资源节点(Resource Node),描述数据库中的对象,如一个表、一行或一个索引。在我们当前的实例中,资源节点描述的是,在聚集索引请求获得排它锁(X)。椭圆形与长方形之间,带箭头的连线表示,处理节点与资源节点的关系,包含描述锁的模式.

接下来我们更详细的看图里面的数据说明。

先看右边作为优胜者的这椭圆形,我们可以看到内容包含有:

服务器进程 ID: 服务器进程标识符 (SPID),即服务器给拥有锁的进程分配的标识符。 服务器批 ID: 服务器批标识符 (SBID)。 执行上下文 ID: 执行上下文标识符 (ECID)。与指定 SPID 相关联的给定线程的执行上下文 ID。ECID = {0,1,2,3, ...n},其中 0 始终表示主线程或父线程,并且 {1,2,3, ...n} 表示子线程。 死锁优先级: 进程的死锁优先级有关可能值的详细信息,请参阅 SET DEADLOCK_PRIORITY (Transact-SQL)。 已用日志: 进程所使用的日志空间量。 所有者 ID: 正在使用事务并且当前正在等待锁的进程的事务 ID。 事务描述符: 指向描述事务状态的事务描述符的指针。

这些数据描述,对于我们理解死锁,只需要知道其中的一些就够,除非我们在专门SQL Server机构工作,才可能要深入理解它们。

下面我们来看左边作为牺牲品的这椭圆形处理节点,它告诉我们以下信息:

1.它是一个失败的事务。(蓝色的交叉表示)

2.它是作为牺牲品的T-SQL代码。

3.它对右下方的资源节点有一个排它锁(X).

4.它对右上方的资源节点请求 一个排它锁(X).

我们再来看中间两个长方形的资源节点,两个处理节点对它们各自都使用权,来执行它们各自的代码,同时又有对对方使用资源请求的动作,从而发生了资源的竞争。

这也就让我们明白死锁发生的原因。

这里说明下资源节点的一些信息:

HoBT:  堆或 B 树。 用于保护没有聚集索引的表中的 B 树(索引)或堆数据页的锁

associated objid: 关联的对象ID,这里只是索引关联的对象ID.

Index name:索引名

让我们再对SQL Server Profiler监视到的数据,作一次整理:

回顾图:

1.在第3行SQL:BatchStarting, SPID 54 (第一个会话启动),在索引PK__DealLock__3214EC274222D4EF获得一个排它锁,再处理等待状态,(因为在这个实例中我设置了Waitfor Delay '00:00:05')

2.在第6行SQL:BatchStarting, SPID 55 (第二个会话启动),在索引PK__DealLock__3214EC2745F365D3获得一个排它锁,再处理等待状态,(因为在这个实例中我设置了Waitfor Delay '00:00:05')

3.两个进程都各自获得一个排它锁(X),几秒过去,它们就开始请求排它锁。

SPID 54 (第一个会话),先对PK__DealLock__3214EC2745F365D3请求一个排它锁(X),但PK__DealLock__3214EC2745F365D3当前已经给SPID 55 (第二个会话)获得。SPID 54要于等待。

同时,

SPID 55 (第二个会话),开始对PK__DealLock__3214EC274222D4EF请求一个排它锁(X),但PK__DealLock__3214EC274222D4EF当前已经给SPID 54 (第一个会话)获得。SPID 55要等待。

这里就出现了进程阻塞,从而发生死锁。

4.SQL Server  检查到这两个进程(第一个&第二个会话)发生死锁,并对占用资源比较少的进程,列入牺牲品名单,将它终止(Kill)。通过左右椭圆形进程节点显示,可以发现已用日志最少的是左边的进程节点。

5. SPID 54 (第一个会话)被回滚(Rollback),SPID 55 (第二个会话)执行成功。

到这里我们已算完成了,对死锁的监视和分析。

详解SQL Server Profiler分析死锁几大步骤相关推荐

  1. 详解SQL Server STUFF的用法

    GPS平台.网站建设.软件开发.系统运维,找森大网络科技! https://cnsendnet.taobao.com 来自森大科技官方博客 http://www.cnsendblog.com/inde ...

  2. SQL Server 2014 Win7 Win10 安装详解 SQL Server 2017 2019 Linux及SQL TSQL ETL实用案例

    SQL Server 2014安装图解与问题分析 简介 SQL Server2014 是Microsoft 公司推出的关系    型数据库管理系统.它用于大规模联机事务处理(OLTP).数据  仓库和 ...

  3. 无可奈何花落去,数据丢失时时来;何当共谈完整性,却话巴山夜雨时----详解SQL Server 数据库库完整性检查和置疑修复

     前情提要 数据库完整性! 这不是SQL Server独有,有点用户认为是SQL Server设计的问题出现数据库不完整,准确的告诉你,所有的数据库系统,都会存在这问题. 就是数据库出现不完整. ...

  4. sqlserver故障转移集群和alwayson的区别_详解SQL Server 2016 + AlwaysOn 无域集群

    搭建 WSFC 配置计算机的 DNS 后缀 1.配置计算机的 DNS 后缀,注意在同个工作组 2.每个节点的机器都要做域名解析,修改 host 文件C:WindowsSystem32driverset ...

  5. sql修改链接服务器名称,链接服务器详解 SQL Server

    一.测试环境 测试环境为SQL Server2000 二.链接服务器的作用 链接服务器能够实现跨数据库或跨服务器的数据查询.链接服务器让用户可以对 OLE DB 数据源进行分布式异类查询.在创建某一链 ...

  6. 详解SQL Server中创建数据仓库已分区表

    在本练习中,您将创建一个分区数据仓库事实数据表.非常大的表经常需要跨几个磁盘卷存储数据.ServerSecurity/Database/'>SQL Server 表无法放置在特定文件中.但是,文 ...

  7. 详解SQL Server 比较带有尾随空格的字符串--【叶子】

    前记:CSDN论坛上多次出现相关问题,总结一下个人对这个问题的看法,欢迎大家共同讨论. 1.问题描述 declare @a varchar(10);set @a='maco ' declare @b ...

  8. 详解SQL Server连接(内连接、外连接、交叉连接)

    在查询多个表时,我们经常会用"连接查询".连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志. 什么是连接查询呢? 概念:根据两个表或多个表的列之间的关系 ...

  9. SQL SERVER性能分析--死锁检测数据库阻塞语句

    http://www.byywee.com/page/M0/S218/218189.html 转载于:https://www.cnblogs.com/BrianLee/p/3250136.html

最新文章

  1. 在Android Studio中搜索整个项目中所有出现的字符串
  2. Run tomcat 5.5 in windows server 2003 x64
  3. 华为交换机的一些OID
  4. jfinal java类型和数据库类型_java下JFinal getModel方法及数据库使用出现问题解决教程...
  5. (99)利用任务task实现单字节乘法功能,面试必问(二十三)(第20天)
  6. c语言sort可以给字符排序吗,字符串排序 (C++代码)sort的第三个参数
  7. ubuntu16.04 下ROS操作系统学习笔记(一)ROS-kinetic安装
  8. 侠客X部分截图 官方论坛开发注册 邀您一起公测。
  9. 最详细的L298N模块使用说明
  10. VMware虚拟机安装xp系统
  11. 苹果系统安装服务器打印机,如何在MAC系统下安装打印机驱动
  12. 嵌入式linux 电容触摸屏驱动框架
  13. 计算机智能化的例子,工程机械智能化技术案例实例.ppt
  14. キュリオ / 库利欧
  15. 大明 VS 满清,明朝的十次机会
  16. python基础===【字符串】所有相关操作
  17. 小学生数学测试软件编写分析,小学数学测试的质量分析
  18. 基于Qt的车载GPS监控系统(2)需求分析
  19. mac os x在PC上安装
  20. windows删除顽固文件

热门文章

  1. 数据传递型情景下事件机制与消息机制的架构设计剖析(目录)
  2. 取得人生成功的40条定律
  3. ModuleNotFoundError: No module named ‘torchversion‘
  4. 【C++笔记】函数的用法:函数的默认参数、占位参数、函数重载
  5. ORB_SLAM2中的疑难杂症
  6. strcpy的用法、c语言实现、及注意点
  7. 计算机无法进系统咋办,详解电脑无法进入系统怎么办
  8. c语言字符输出128,如何将128位整数转换为C中的十进制ASCII字符串?
  9. ios8升级ios12教程_iOS Hello World示例教程
  10. android生命周期_Android片段生命周期