使用 SQL SERVER PROFILER 监测死锁
作为DBA,可能经常会遇到有同事或者客户反映经常发生死锁,影响了系统的使用。此时,你需要尽快侦测和处理这类问题。
死锁是当两个或者以上的事务互相阻塞引起的。在这种情况下两个事务会无限期地等待对方释放资源以便操作。下面是死锁的示意图:

本文将使用SQLServer Profiler来跟踪死锁。
准备工作:
为了侦测死锁,我们需要先模拟死锁。本例将使用两个不同的会话创建两个事务。
步骤:
1、 打开SQLServer Profiler
2、 选择【新建跟踪】,连到实例。
3、 然后选择【空白】模版:

4、 在【事件选择】页中,展开Locks事件,并选择以下事件:
1、 Deadlock graph
2、 Lock:Deadlock
3、 Lock:Deadlock Chain

5、 然后打开TSQL事件,并选择以下事件:
1、 SQL:StmtCompleted
2、 SQL:StmtStarting

6、 点击【列筛选器】,在跟踪属性中,选择数据库名为需要侦测的数据库,这里使用AdventureWorks。

7、 在【组织列】中,调整顺序,如下:

8、 点击运行。
9、 然后打开SQLServer,并打开两个连接。
10、 在第一个窗口中输入并执行下面脚本:
- USE AdventureWorks
- GO
- SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
- GO
- BEGIN TRANSACTION
- SELECT *
- FROM Sales.SalesOrderDetail
- WHERE SalesOrderDetailID = 121316
11、 然后在第二个窗口中输入并执行下面脚本:
- USE AdventureWorks
- GO
- SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
- BEGIN TRANSACTION
- SELECT *
- FROM Sales.SalesOrderDetail
- WHERE SalesOrderDetailID = 121317
12、现在回到第一个窗体,并运行下面的脚本:
- UPDATE Sales.SalesOrderDetail
- SET OrderQty=2
- WHERE SalesOrderDetailID=121317
13、在第二个窗口输入下面语句:
- UPDATE Sales.SalesOrderDetail
- SET OrderQty=2
- WHERE SalesOrderDetailID=121316
14、 然后在第二个窗口就会看到下面的消息:

15、切换到SQLServer Profiler,可以看到下面的截图:

16、 点击【Deadlock graph】时间,会显示死锁的图像:

17、可以保存死锁图像,右键然后选择导出事件数据,并另存为xdl文件:

下面是其XML格式:

分析:
在本文中,首先创建一个Profiler空白模版,然后选择下面的事件进行监控:
1、 Deadlock graph
2、 Lock:Deadlock
3、 Lock:Deadlock Chain
4、 SQL:StmtCompleted
5、 SQL:StmtStarting
然后通过限定数据库,来限制监控过得对象范围。
在配置好之后,运行跟踪,并在ssms中运行脚本。SQLServer会自动处理和侦测这种类型的死锁。然后会在第二个窗体中收到1205的错误。
在SQLServer Profiler中,演示了如何收集死锁事件,在跟踪结果中可以看到两个事务尝试在一个拥有共享锁的键上添加排它锁。通过死锁图像,可以看到死锁发生的细节。
为了避免或者最小化死锁的发生,有一些建议可以参考:
1、 确保你的事务尽可能地小,这里指范围。
2、 使用较低隔离级别的事务。
3、 对于可能的查询,使用NOLOCK查询提示。
4、 规范化数据库设计。
5、 在需要的列上创建索引,以便是表不需要经常扫描,减少锁问题的发生。
6、 控制数据库对象访问的顺序是相同的顺序。
ps:我用了这个例子,结果没出现死锁,用下面这个例子可以:
在一个窗口输入以下语句:
BEGIN TRAN
USE TEST;
UPDATE T6 SET time3='2013-12-31 00:00:00.000'
WHERE time3='9999-09-09 00:00:00.000'
WAITFOR DELAY '0:0:15'
UPDATE T3 SET VALUE=5
WHERE ID=10
COMMIT TRAN
在另一个窗口输入以下语句:
BEGIN TRAN
USE TEST;
UPDATE T3 SET VALUE=5
WHERE ID=10
WAITFOR DELAY '0:0:15'
UPDATE T6 SET time3='2013-12-31 00:00:00.000'
WHERE time3='9999-09-09 00:00:00.000'
COMMIT TRAN
在第一个窗口执行后,在15秒之内执行第二个窗口的查询。
会发生死锁。
事务的执行过程:
①:窗口1要更新T6的数据,需要向数据库引擎申请T6的排他锁。
②:窗口2要更新T3的数据,需要向数据库引擎申请T3的排他锁。
因为请求锁的对象不同,所以它们可以同时得到想要的锁。
③:在窗口2还没有完成对T3更新前,窗口1完成了对T6的更新,然后想要更新T3的数据,此时需要请求T3的排他锁。由于排他锁与窗口2上面的T3上面的排他锁不兼容,所以窗口1必须等待窗口2执行完事务,然后放在T3上面的排他锁后,才能获得对T3的排他锁。
④:窗口2想要申请T6上的排他锁同上面道理一样。
双方都等待对方释放资源,才能继续事务操作,从而形成死锁。
例子中使用WAITFOR语句在执行两条语句间休息5秒,可以增加死锁的概率。
数据库引擎会定期检索死锁,一旦发现问题,会选取其中一个事务作为牺牲品,终止事务的运行,从而释放资源。
被牺牲的事务会显示如下信息:
(1 行受影响)
消息 1205,级别 13,状态 45,第 7 行
事务(进程 ID 55)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
‘1行受影响’表示第一个UPDATE语句已经执行成功。但是由于事务没有成功提交,所以回滚掉了。
本篇文章转自:
使用 SQL SERVER PROFILER 监测死锁的更多相关文章
- Sql Server Profiler跟踪死锁
Sql Server Profiler一个很重要的应用场景就是监视分析死锁. 下面通过一个例子来学习Profiler是如何监视死锁的. 1. 创建测试数据模拟死锁, 创建表Table_A和Table_ ...
- SQL Server Profiler监控SQL Server性能
全面掌握SQL Server Profiler 1. 原理与相关概念介绍 SQL Server Profiler,大家已经非常熟悉.常常在性能优化中使用,本文档详细介绍SQL Server ...
- SQL Server Profiler的简单使用
SQL Server Profiler可以检测在数据上执行的语句,特别是有的项目不直接使用sql语句,直接使用ORM框架的系统处理数据库的项目,在调试sql语句时,给了很大的帮助. 之前写了使用SQL ...
- SQL Server Profiler的简单使用(监控mssql)
SQL Server Profiler可以检测在数据上执行的语句,特别是有的项目不直接使用sql语句,直接使用ORM框架的系统处理数据库的项目,在调试sql语句时,给了很大的帮助. 之前写了使用SQL ...
- SQL2005 : 如何在SQL Server Profiler (事件查看器)中 跟踪查看死锁恢复
SQL Profiler 通过 SQL Profiler 工具程序,可监控应用程序如何访问数据库引擎.普通来说,当系统性能需要优化或是应用程序对数据库访问的结果不合预期,都可以使用该工具确认视图问题所 ...
- 通过SQL Server Profiler来监视分析死锁
在两个或多个SQL Server进程中,每一个进程锁定了其他进程试图锁定的资源,就会出现死锁,例如,进程process1对table1持有1个排它锁(X),同时process1对table2请求1个排 ...
- 数据库性能监测工具——SQL Server Profiler
使用SQL Server Profiler 进行sql监控需要一些设置: 其他的就是进行分析了~ 清除SQL SERVER缓存 常用的方法: DBCC DROPCLEANBUFFERS 从缓冲池中删除 ...
- Sql性能检测工具:Sql server profiler和优化工具:Database Engine Tuning Advisor
原文:Sql性能检测工具:Sql server profiler和优化工具:Database Engine Tuning Advisor 一.工具概要 数据库应用系统性能低下,需要对其进行优化 ...
- SQL Server Profiler
一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收集查询信息: 分析性能: 诊断像死锁之类的问 ...
随机推荐
- C++_异常2-返回错误码
一种比异常终止更灵活的办法是,使用函数的返回值来指出问题. 例如,ostream类的get(void)成员通常返回下一个输入字符的ASCII码,但到达文件尾时,将返回EOF. 对hmean()来说,这 ...
- JAVA数据结构--冒泡排序
冒泡排序(英语:Bubble Sort,台湾另外一种译名为:泡沫排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行 ...
- 洛谷 P3157 [CQOI2011]动态逆序对(树套树)
题面 luogu 题解 树套树(树状数组套动态开点线段树) 静态使用树状数组求逆序对就不多说了 用线段树代替树状数组,外面套树状数组统计每个点逆序对数量 设 \(t1[i]\)为\(i\)前面有多少个 ...
- 鼠标拖动div,div跟随鼠标移动效果
<div id="boxDiv" style='width:20px;height:20px;position:absolute;background:red;'> ...
- SPOJ - REPEATS RMQ循环节
题意:求重复次数最多的重复子串(并非长度最长) 枚举循环子串长度\(L\),求最多能连续出现多少次,相邻的节点往后的判断可以使用\(LCP\)得到值为\(K\),那么得到一个可能的解就是\(K/L+1 ...
- hibernateUtil类
package com.test.Util; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfi ...
- python 可迭代对象,迭代器和生成器,lambda表达式
分页查找 #5.随意写一个20行以上的文件(divmod) # 运行程序,先将内容读到内存中,用列表存储. # l = [] # 提示:一共有多少页 # 接收用户输入页码,每页5条,仅输出当页的内容 ...
- 1.rabbitmq 集群版安装及使用nginx进行四层负载均衡设置
1.安装erlang 需要注意erlang的版本是否满足rabbitmq的需求 这里用到的版本是:Erlang 19.0.4 RabbitMQ 3.6.15 wget http://www.rab ...
- 里氏替换原则(Liskov Substitution Principle) LSP
using System; using System.Collections.Generic; using System.Text; namespace LiskovSubstitutionPrinc ...
- Docker_network相关指令
docker network create创建docker网卡docker network create -d overlay --ip-range=192.168.2.0/24 --gateway= ...