sql server中死锁排查的全过程分享
前言 记得以前客户在使用软件时,有偶发出现死锁问题,因为发生的时间不确定,不好做问题的重现,当时解决问题有点棘手了。 死锁的四个必要条件:
现总结下查看死锁的常用二种方式:第一种是图形化监听: sqlserver -->工具--> sql server profiler 登录后在跟踪属性中选择如下图: 监听到的死锁图形如下图 这里的描述大致是:有二个进程 一个进程ID是96, 另一个ID是348. 系统自动kill 掉了进程ID:96,保留了进程ID:348 的事务Commit。 上面死锁是由于批量更新出现PAG范围锁, 双方进程在同一分区索引资源上。ID96,348都请求想获取更新锁(U),各占排它锁(x)不释放,直到锁超时。 第二种是使用日志跟踪(errorlog) 以全局方式打开指定的跟踪标记 DBCC TRACEON(1222,-1) DBCC TRACEON(1204,-1) 使用 PAGE: 7:1:5692366 CleanCnt:2 Mode:U Flags: 0x3 Grant List 3: Owner:0x0000000D12099B80 Mode: U Flg:0x40 Ref:0 Life:00000001 SPID:64 ECID:0 XactLockInfo: 0x000000136B4758F0 SPID: 64 ECID: 0 Statement Type: UPDATE Line #: 108 Input Buf: RPC Event: Proc [Database Id = 7 Object Id = 907150277] -------- node:1 部分显示的几个关键信息: PAGE 7:1:6229275 (所在数据库ID 7, 1分区, 6229275行数) Mode: IX 锁的模式 意向排它锁 SPID: 219 进程ID Event: exec proc_PUB_StockDataImport 执行的存储过程名 -------node:2 部分显示的几个关键信息 PAGE 7:1:5692366 (所在数据库ID 7, 1分区,5692366行数) Mode:U 锁的模式 更新锁 RPC Event: Proc 远程调用 SPID: 64 进程ID 从上面的信息能看到kill 掉的是进程id是process956f4c8, 进程spid=64 executionStack 执行的堆信息: 存储名 语句 clientapp 发起事件的来源 最后总结 避免死锁的解决方法 按同一顺序访问对象。 优化索引,避免全表扫描,减少锁的申请数目. 避免事务中的用户交互。 使用基于行版本控制的隔离级别。 将事务默认隔离级别的已提交读改成快照 使用nolock去掉共享锁,但死锁发生在u锁或x锁上,则nolock不起作用 升级锁颗粒度(页锁,表锁),以阻塞还代替死锁 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对编程之家的支持。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |