提到sql server,想必最让人头疼的当属锁机制了。在默认的read committed隔离模式下,连最基本的select操作都要申请各种粒度的锁,而且在读取数据过程中会不断有锁升级、转化。在非未提交读的隔离级别中,一个select操作会对每一条读到的记录或键值加S锁(何时释放还要视记录是否返回以及隔离级别而定),对每一条用到的Index上的键值加S锁,对读过的每个page和table上加IS锁...update、insert、delete操作申请锁的量和复杂度就更大了。
死锁和阻塞都是sql server要实现事务隔离的产物。有时候在同一个表上的事务隔离,并发度高一点会发生死锁;并发度低一点发生的是阻塞。所以死锁的问题定位和解决与阻塞有想通的地方,解决死锁最关键的就是要找到死锁双方或多方共同争抢的资源是哪个。下面分享一个最近碰到的真实生产环境上的案例,解析死锁抓取以及解决过程。
 
某外资物流公司
操作系统:Windows Server 2012 Enterprise x64
数据库   :SQL Server 2014 Enterprise X64
数据量   :300GB左右日常事务并发量比较高
现状        :由于一个业务sp的大量并行运行导致死锁,死锁发生一方作为牺牲资源后回滚过程很漫长导致重要业务表被锁,业务中断
解决排查过程:
首先必须找到死锁资源:
1)通过SQL Server Profiler新建一个trace,事件选择可以精简点便于我们观察死锁,选择“Locks”事件
下的Lock:Deadlock和Deadlock graph即可,trace文件大小设置为100M上限以便分析
2)一段时间后停止抓取,很直观看到死锁一直出现,且点开所有deadlock graph得到死锁图形分析,死锁都是发生在同一资源上:

到这一步为止我们只是能确认死锁发生了,而且发生在同一资源上,还没能获取具体的死锁语句和资源信息,问题还不能得到根本解决。

 
3)为了查看死锁信息,数据库引擎提供了监视工具:跟踪标识(1222)。打开这个跟踪开关,所有获取的死锁信息会写到SQL Server的错误日志中供我们进一步分析。这一步打开这个开关,在SSMS中运行
DBCC TRACEON(1222,-1);
 
4)从trace的死锁图形看死锁发生很频繁,为了不让日志增长过大,过2至3分钟后将开关关掉。在SSMS中运行
DBCC TRACEOFF(1222,-1),这一步很重要;
 
5)打开SQL Server errorlog,找到死锁输出信息,这个输出内容很丰富而且比较复杂,这里只把我们所需的几个重要点挑出来

死锁信息始于 deadlock-list关键字(倒着看),deadlock victim显示死锁的牺牲方,process id显示进程id号,由于截图没那么齐全,还包含很多死锁信息,比如可以查看进程spid号,事务隔离级别,当前正进行的批处理操作,当前正在运行的语句,申请中的资源等等。

通过对错误日志的分析得到死锁批处理和死锁语句:exec usp_obal_import_so,查到死锁语句:delete from t_po_detail where po_number in(select po_number from t_so_po where so_number=@v_vchSOID and whid=@v_vchWHID) and whid=@v_vchWHID,这是usp_obal_import_so中的一段语句,锁资源:表tbl_po_detail_generic(用户脚本定时执行获得) ,但是这个sp的执行根本不会操作tbl_po_detail_generic ,是不是哪里出问题了呢?
       6)我们可以在SSMS中看看这条语句的执行计划,运行语句之前在SSMS中运行
     set statistics profile on或者在“查询”子菜单中选择“包括实际的执行计划”,我们用第二种更直观,如下

很明显在执行计划中可以看到tbl_po_detail_generic有个全表扫描操作,再与t_po_detail表做hash连接。全表扫描导致每次语句执行会获取该表的表锁,深究原因发现tbl_po_detail_generic的外键约束导致每次删除t_po_detail数据会操作tbl_po_detail_generic表。

       7)到这里剖析死锁工作基本结束,后面解决方法有两种:一是根据执行计划在tbl_po_detail_generic建立适当索引避免表扫描;二是如果业务逻辑许可,删掉外键约束。
总结:
       要真正做到从源头上降低死锁发生几率,还是要从程式本身做好。如果不能去修改程式,可以考虑从另外几个方面消除死锁:

1 调整索引来调整执行计划,减少锁的申请数目;

2 使用'nolock'参数,让SELECT语句不要申请S锁,减少锁申请数目

3 升级锁粒度,将死锁转化成阻塞问题

4 使用快照隔离级别SNAPSHOT LEVEL

 

SQL Server死锁排查经历 -基于SqlProfiler的更多相关文章

  1. SQL Server死锁排查

    1. 死锁原理 根据操作系统中的定义:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态. 死锁的四个必要条件:互斥条件(Mutua ...

  2. sql server 死锁排查

    记得以前客户在使用软件时,有偶发出现死锁问题,因为发生的时间不确定,不好做问题的重现,当时解决问题有点棘手了. 现总结下查看死锁的常用二种方式: 第一种是图形化监听: sqlserver --> ...

  3. SQL Server死锁

    SQL Server死锁 多个事务之间互相等待对方的资源,导致这些事务永久等待 注意是永久等待,而非长事务 死锁的4个条件 互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程 ...

  4. SQL Server的镜像是基于物理块变化的复制 镜像Failover之后数据的预热问题

    SQL Server的镜像是基于物理块变化的复制 镜像Failover之后数据的预热问题 基于物理块变化的复制,没有并行也是很快的. 逻辑复制的日志是按事务结束的时间排序的,而物理复制是与事务无关的, ...

  5. SQL Server死锁的解除方法

    如果想要查出SQL Server死锁的原因,下面就教您SQL Server死锁监控的语句写法,如果您对此方面感兴趣的话,不妨一看. 下面的SQL语句运行之后,便可以查找出SQLServer死锁和阻塞的 ...

  6. Update导致SQL Server死锁的典型方法(转载)

    此文为转载文章,描述的很好,没有验证过. 最近遇到了一个看上去很奇怪,分析起来很有意思的死锁问题.这个死锁看上去难以理解.而分析过程中,又使用了很多分析SQL Server死锁的典型方法.记录下来整个 ...

  7. Sql Server性能排查和优化懒人攻略

    转载自作者zhang502219048的微信公众号[SQL数据库编程]:Sql Server性能排查和优化懒人攻略 很多年前,笔者那时刚从广东技术师范学院(现为广东技术师范大学,以前为广东民族学院)的 ...

  8. SQL Server死锁总结

    1. 死锁原理 根据操作系统中的定义:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态. 死锁的四个必要条件:互斥条件(Mutua ...

  9. SQL Server死锁总结 [转]

    1. 死锁原理 根据操作系统中的定义:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态. 死锁的四个必要条件:互斥条件(Mutua ...

随机推荐

  1. MVC文件上传04-使用客户端jQuery-File-Upload插件和服务端Backload组件实现多文件异步上传

    本篇使用客户端jQuery-File-Upload插件和服务端Badkload组件实现多文件异步上传.MVC文件上传相关兄弟篇: MVC文件上传01-使用jquery异步上传并客户端验证类型和大小  ...

  2. java二分查找法

    //二分查找法.必须有前提:数组中的元素要有序. public static int halfSeach_2(int[] arr,int key){ int min,max,mid; min = ; ...

  3. iOS抽屉效果

    源代码下载 抽屉效果第三方类库下载 所需第三方类库下载 側拉栏抽屉效果图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTUhUaW9z/font/5a6L ...

  4. Visual Studio 2017 简体中文企业正式版全量离线安装包下载地址

    Visual Studio 2017 简体中文企业正式版全量离线安装包下载地址:magnet:?xt=urn:btih:199993649B1834C50FE7BDD204502CC23C7A4611 ...

  5. 计算均值mean的MapReduce程序Computing mean with MapReduce

    In this post we'll see how to compute the mean of the max temperatures of every month for the city o ...

  6. FLume监控文件夹,将数据发送给Kafka以及HDFS的配置文件详解

    详细配置文件flume-conf.properties如下: ############################################ # producer config ###### ...

  7. Objective-C:NSArray的常见操作

    NSArray不可变字符串的主要操作有:创建.枚举.排序.与NSString之间的相互转换 注意: NSArray可以存对象,不可以存基本数据类型.结构体.数组.指针.nil.NULL NSArray ...

  8. Objective-C:MRC手动释放对象内存举例(引用计数器)

    手机内存下的类的设计练习: 设计Book类, 1.三个成员变量:    title(书名)author(作者).price(价格) 2.不使用@property,自己完成存取方法(set方法,get方 ...

  9. HTML5 Canvas,WebGL,CSS Shaders,GLSL的暧昧关系 【转】

    HTML5 Canvas,WebGL,CSS Shaders,GLSL的暧昧关系 这篇文章发布于 2011年10月10日,星期一,17:14,归类于 canvas相关. 阅读 58013 次, 今日 ...

  10. Leaf - 一个由 Go 语言编写的开发效率和执行效率并重的开源游戏服务器框架

    转自:https://toutiao.io/posts/0l7l7n/preview Leaf 游戏服务器框架简介 Leaf 是一个由 Go 语言(golang)编写的开发效率和执行效率并重的开源游戏 ...