大家好,欢迎回到性能调优培训今天讨论SQL Server里的死锁(Deadlocking),第5个月的培训就结束了。当2个查询彼此等待,没有查询可以继续它的工作就会发生死锁。第一步我会概括介绍下SQL Server如何处理死锁。最后我会向你展示下SQL Server里一些特定死锁,还有你如何避免并解决它们。

死锁处理(Deadlock Hanging)

死锁的好处是SQL Server会自动检测并解决它们。为了解决死锁,SQL Server需要回滚最便宜的2个事务。在SQL Server上下文里,最便宜的事务是写入事务日志,字节数更少的事务。

SQL Server在后台进程里使用所谓的Deadlock Monitor来实现死锁检测。这个后台进程每5秒钟运行一次,为死锁检查当前的死锁情况。最坏的情况,因此死锁应该不会超过5秒钟。回滚的查询收到1205号错误。死锁的"好处"是你可以从那个错误情形里完全还原,而不需要用户互动。一个聪明的开发人员必须做下列事情来从死锁中恢复:

  • 当异常抛出时,检查下1205错误号
  • 暂停应用程序给其他查询一些时间来完成它的事务并释放它已获得的锁
  • 重新提交被SQL Server回滚的查询

查询重新提交后,查询应该继续没有问题,因为其它阻塞的查询已经完成它的事务。当然,你应该保持再次死锁的跟踪,这样的话,你就不用反复重试你的事务。

你可以在不同方式里故障排除死锁。SQL Server Profiler提供你Deadlock Graph事件,死锁一旦发生就会检测到。如果你在SQL Server 2008及更高的版本,你也可以用扩展事件(Extended Events)来故障排除死锁情形。扩展时间提供你system_health事件会话,它更总自上次SQL Server重启后发生过的死锁。使用启用1222跟踪标志(trace flag),SQL Server会把死锁信息写入错误日志。

死锁类型

在SQL Server里可以发生多个类型的死锁。在这个部分我想详细谈下最常见的几个。

几乎在每个SQL Server里都会看到的一个经典死锁是著名的书签查找死锁(Bookmark Lookup Deadlock),当你同时对聚集和非聚集索引进行读写是会发生。这个是主要是因为不好的索引设计的死锁。在我的日常生活里,作为SQL Server的故障排除者,我可以说至少所有死锁的90%可以通过应用更好的索引设计到你工作中来避免。书签查找死锁可以通过第8周性能调优培训里介绍的提供覆盖非聚集索引来轻松剔除。

另一个常见的死锁是所谓的循环死锁(Cycle Deadlock),在你的各个查询以不同的顺序访问表里发生。为了避免那个特定死锁,你总要确保查询在同样的顺序访问表。另外在SQL Server里可以发生的“最好”死锁是所谓的内部并行死锁(Intra-Parallelism Deadlock),在并行运算符(Distribute Streams, Gather Streams, Repartition Streams)已经在各自线程间内部死锁。下图显示了一个典型的死锁图。

图片本身就是个很高雅的艺术品(pure art),因为你命中SQL Server里的1个BUG才发生。遗憾的是这样的BUG微软不会去修正,因为会引入回归(regressions)的可能。因此你要确保引起这个死锁的查询,在SQL Server里都是单线程运行的。你可以通过多个选项来获得执行计划的单线程执行:

  • 在索引设计上做工作,这样的查询成本低于当前的并行开销阈值(默认5)
  • 使用查询提示MAXDOP 1让SQL Server以单线程运行你有问题的查询

另一个死锁的特效疗法(miracle cure)是启用乐观并发控制(optimistic concurrency),尤其是读提交快照隔离(Read Committed Snapshot Isolation (RCSI)),这个2个星期前就已经讨论过,它对你的程序是完全透明的(completely transparent)。使用乐观并发控制,共享锁(S)就消失了,这意味这你可以剔除SQL Server里大量的典型死锁。

小结

死锁通过SQL Server回滚最便宜的事务来自动处理。但是你必须确保死锁尽可能小,因为每个回滚的事务都会负面影响你的终端用户。 死锁可以通过好的索引设计来避免,使用乐观并发控制对它们也可以是特效疗法。

下个星期,我们会开始性能调优培训的最后一个月,我们会讨论SQL Server里性能调优和故障排除的一切。请和我一起期待火力全开的最后一个月!

围观PPT:

1109_20_死锁.rar

第20/24周 死锁(Deadlocking)的更多相关文章

  1. 第0/24周 SQL Server 性能调优培训引言

    大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤浅,博而不专,到现在我才发现自己的兴趣所在,于 ...

  2. 2016年12月3日 星期六 --出埃及记 Exodus 20:24

    2016年12月3日 星期六 --出埃及记 Exodus 20:24 "`Make an altar of earth for me and sacrifice on it your bur ...

  3. 分享Kali Linux 2017年第24周镜像文件

     分享Kali Linux 2017年第24周镜像文件  Kali Linux官方于6月11日发布2017年的第24周镜像.这次维持了11个镜像文件的规模.默认的Gnome桌面的4个镜像,E17.KD ...

  4. 第4/24周 页面限制8060 bytes

    恭喜您!在你面前就只剩下几页了,然后你就可以完成第1个月的SQL Server性能调优培训了.今天我将讲下页的一些限制,还有为什么你会喜欢这些限制,同时也会讨厌这些限制. 正如你在第2周学到的,数据页 ...

  5. 第16/24周 SQL Server 2014中的基数计算

    大家好,欢迎回到性能调优培训.上个星期我们讨论在SQL Server里基数计算过程里的一些问题.今天我们继续详细谈下,SQL Server 2014里引入的新基数计算. 新基数计算 SQL Serve ...

  6. 第17/24周 悲观并发控制(Pessimistic Concurrency)

    大家好,欢迎回到性能调优培训.今天标志着第5个月培训的开始,这个月我们会谈论SQL Server里的锁.阻塞和死锁(Locking, Blocking, and Deadlocking). SQL S ...

  7. 第19/24周 锁升级(Lock Escalations)

    大家好,欢迎回到性能调优培训.上2个星期我们已经讨论了SQLServer里的悲观和乐观锁.今天我想谈下SQL Server里对于锁的一个特殊现象:所谓的锁升级(Lock Escalations).在我 ...

  8. Java(20~24)

    1.Collection中的集合称为单列集合,Map中的集合称为双列集合(键值对集合). 2.Map常用方法:map.put()   map.get()   map.remove()   map.ke ...

  9. 第3/24周 区_SQL Server中管理空间的基本单位

    哇哦,SQL Server性能调优培训已经进入第3周了!同时你已经对SQL Server内核运行机制有了很好的认识.今天我会讲下SQL Server中的区管理,因为这是个很重要的话题,我们会在第23周 ...

随机推荐

  1. Windows Phone App的dump 文件分析

    前言 我们在发布了自己的App以后,Windows Phone的Error Report机制会帮助我们收集程序的崩溃信息并发送到微软的服务器上,这可以辅助开发者提高App的稳定性. 那么如何利用这些d ...

  2. ASP.NET一般处理程序访问Session问题

    我们在使用一般处理程序的时候,访问Session会出现如下错误: 解决方案如下: //引用命名空间 using System.Web.SessionState; //继承IRequiresSessio ...

  3. FusionCharts简单教程(四)-----基本数字格式

          在统计图例中什么是最基本,最重要的元素?那就是数据.一个数据的统计图像那就是一堆空白.但是数据存在多种形式,比如小数,比如千分位等等.又如若一个数据是12.000000001,对于数据要求 ...

  4. [每日电路图] 8、三轴加速度计LIS3DH电路图及功耗等指标

    看TI的官网资料:http://www.st.com/web/en/catalog/sense_power/FM89/SC444/PF250725 一.初次接触关注的信息: 1.1.概述中的关键信息 ...

  5. Node.js使用fs.renameSync报cross-device link not permitted错误

    在Node.js中,我们可以使用formidable模块来轻松地实现文件上传功能,代码如下: var Q = require('q'); var util = require('util'); var ...

  6. ehcache2拾遗之write和load

    问题描述 在cache系统中writeThrough和writeBehind是两个常用的模式. writeThrough是指,当用户更新缓存时,自动将值写入到数据源. writeBehind是指,在用 ...

  7. C# 加密–RSA前端与后台的加密&解密

    1. 前言 本问是根据网上很多文章的总结得到的. 2. 介绍 RSA加密算法是一种非对称加密算法. 对极大整数做因数分解的难度决定了RSA算法的可靠性.换言之,对一极大整数做因数分解愈困难,RSA算法 ...

  8. IoC组件Unity再续~根据类型字符串动态生产对象

    回到目录 这个根据类型字符串动态去生产一个接口的对象,在实现项目中用途很广,这即省去了配置config文件的麻烦,又使用生产对象变更可配置,你完全可以把这种多态持久化到数据库里或者XML文件里,在使用 ...

  9. Piwik延迟加载脚本

    piwik有时候会卡页面,为了不影响页面,可以将Piwik代码放到最后加载 <!-- Piwik --> <script type="text/javascript&quo ...

  10. java 线程协作 join()

    在实际开发中我们往往会遇到这样的情况一个线程的执行需要依赖另一个线程执行后的结果.即主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他 ...