linuxsir首页 LinuxSir.Org | Linux、BSD、Solaris、Unix | 开源传万世,因有我参与欢迎您!
网站首页 | 设为首页 | 加入收藏
您所在的位置:主页 > Linux数据库 >

记录SQL Server中一次无法重现的死锁

时间:2019-11-20  来源:未知  作者:admin666
begin insert into TestDeadLock values (concat('X0000000000',@i),cast(rand()*10 as int),'test') set @i = @i+1 end

测试表的索引对象Id

以delete from TestDeadLock where col2 in ( 'X00000000003','X000000000020')为例,这里先拿到其伪列Id

理论上,这句sql的执行,会走col2 上的索引进行查找,然后再进行删除(delete本来就是先查找再删除的过程),测试case也是预期地,走了col2 上的索引

查看锁的申请与释放过程

可以发现

1,删除多条数据的时候,是一条一条加锁然后删除的

2,对于第一条记录(32a1976b7833),也即col2 = 'X000000000089'的记录,删除的加锁过程如下

2.1 对(32a1976b7833),即col2 = 'X000000000089'的记录记录所在的page加共享排它锁,对(32a1976b7833)记录所在的行加U锁

2.2  对(32a1976b7833)记录对应的主键所在的page加IX锁,主键行加RID级别的U锁

2.3 对2.2 对(32a1976b7833)记录对应的RID所在的page加IX锁,主键行加RID级别的X锁

2.4 对2.2 对(32a1976b7833)记录对应的主键所在的page加IX锁,主键行加RID级别的U锁

    2.5 对2.2 对(32a1976b7833)记录对应的主键所在的page加IX锁,主键行加KEY级别的X锁

2.6 释放KEY与Page级别的X锁和IX锁

2.7 重复2.1对(32a1976b7833)记录所在的page加共享排它锁,对(32a1976b7833)记录所在的行加U锁

2.8 释放(32a1976b7833)以及其所在page的X锁和IX锁

2.9 对(d12bea8cbd9f)这个记录,也即Col3字段上的索引依次加page上的IX锁,key上的X锁

2.10(反向)依次释放Col3 key上的X锁,page上的IX锁

2.11 依次释放上述其他的锁

简而言之,遵循两段锁协议(2PL),以行为基础,加锁与释放所过程独立,互不干扰。
因为走了Col2上的索引,这个过程大概是:先申请Col2上的U锁,找到其RID和主键索引,然后依次删除这RID和主键索引,然后再删除Col2上索引的key,最后删除对应的Col3上的索引key
最后释放所有上面申请的锁

上述是删除多条数据其中一条数据的加锁以及释放锁的过程,很清楚的看到,Col2上的U锁只是在第一步申请的,Col3上根本没有申请U锁,而是直接申请的X锁,然后删除,然后再释放
因为死锁双方的数据是互不交叉的,U锁又是单独只在Col2索引上申请的,那么为什么会出现死锁双方相互等待Col2与Col3上的U锁,从而造成死锁?
之前没有想明白,是因为就存在一种想当然的推断过程,两个session的删除语句都走col2上的索引,当然不会出现两个session相互申请Col2与Col3上的U锁
一旦存在Session1走Col2上的索引,Session2走Col3上的索引,才有可能出现ession相互申请Col2与Col3上的U锁的可能性

对于Session1和Session2

1,session1 执行delete from TableA where col2 in (x,y,z);
2,session2 执行delete from TableA where col2 in (l,m,n);

理论上说,或者相当然地说,都会走col2上的索引,但是不能完全肯定一定都会走Col2上的索引,或许有可能走全表扫描,或者有可能走Col3上的索引扫描
比如如下的强制索引提示,走任何一种执行计划,都是可能的,尽管可能会在主观上认为某些执行计划是不好的,但是这个语句在没有任何索引提示的时候,不能臆测一定会走col2上的索引
否则不会出现session双方持有了Col2索引上的U索引,申请Col3索引上的U锁,否则这个死锁就解释不通。

实际上,上述死锁,有可能是一个执行计划走了Col2上的索引查找方式删除,需要先在Col2索引上加U锁
一个是走了走了全表扫描造成的,类似于delete t from TestDeadLock t with(index(0)) where Col2 in ( 'X000000000089','X000000000095')的执行计划
后者先在Col3上加U锁,然后找到其对应的RID,主键索引,Col2上的索引,依次加U锁,加X索引,这样才潜在死锁的可能性

写不下去了,钻研SQL Server的人实在太少了,如果是MySQL,一定会有大神回去做深入的分析,这个case笔者多次尝试重现它,包括使用Python多线程的方式模拟当时的场景,都无疾而终,无法重现
发生死锁的这个真实情况下的场景,也不会经常出现,笔者也只是偶尔捞到死锁的xml_deadlock_report尝试作分析,均无果。

这个死锁,是笔者遇到的不多的无法重现或者模拟出来的死锁,但愿有高手感兴趣的话,进一步做分析尝试,即便是推翻笔者猜测的结论,得出更有说服力的结果。

以上。

linux 基于Redis扩展模块的布隆过滤器使用 MySQL 8.x 新版本JDBC连接方式
友情链接
  • Mozilla发布Firefox 67.0.4,修复沙箱逃逸漏洞
  • 蚂蚁金服正式成为CNCF云原生计算基金会黄金会员
  • Firefox 68将采用Microsoft BITS安装更新
  • OpenSSH增加对存储在RAM中的私钥的保护
  • 谷歌想实现自己的curl,为什么?
  • Raspberry Pi 4发布:更快的CPU、更大的内存
  • Firefox的UA将移除CPU架构信息
  • Ubuntu放弃支持32位应用程序实属乌龙,Steam会否重回Ubuntu怀抱
  • Qt 5.13稳定版发布:引入glTF 2.0、改进Wayland以及支持Lottie动
  • 红帽企业Linux 7现已内置Redis 5最新版
  • Slack进入微软内部禁用服务清单,GitHub也在其列?
  • 安全的全新编程语言V发布首个可用版本
  • Windows Terminal已上架,快尝鲜
  • 阿里巴巴微服务开源生态报告No.1
  • 面世两年,Google地球将支持所有基于Chromium的浏览器
  • 推进企业容器化持续创新,Rancher ECIC千人盛典完美收官
  • CentOS 8.0最新构建状态公布,或于数周后发布
  • Debian移植RISC
  • 微软拆分操作系统的计划初现雏形
  • Oracle发布基于VS Code的开发者工具,轻松使用Oracle数据库
  • Ubuntu 19.10停止支持32位的x86架构
  • 微软为Windows Terminal推出全新logo
  • 联想ThinkPad P系列笔记本预装Ubuntu系统
  • 微软发布适用于Win7/8的Microsoft Edge预览版
  • 启智平台发布联邦学习开源数据协作项目OpenI纵横
  • 经过六个多月的延迟,微软终于推出Hyper
  • ZFS On Linux 0.8.1 发布,Python可移植性工作
  • DragonFly BSD 5.6.0 发布,HAMMER2状态良好
  • Linux Kernel 5.2
  • CentOS 8.0 看起来还需要几周的时间
  • 百度网盘Linux版正式发布
  • PCIe 6.0宣布:带宽翻倍 狂飙至256GB/s
  • PHP 7.4 Alpha 发布,FFI扩展,预加载Opcache以获得更好的性能
  • Canonical将在未来的Ubuntu版本中放弃对32位架构的支持
  • Scala 2.13 发布,改进的编译器性能
  • 微软的GitHub收购了Pull Panda,并且使所有订阅完全免费
  • Windows Subsystem for Linux 2 (WSL 2)现在适用于Windows 10用
  • Debian 10 “Buster”的RISC
  • MariaDB宣布发布MariaDB Enterprise Server 10.4
  • DXVK 1.2.2 发布,带来微小的CPU开销优化
  • DragonFlyBSD 5.6 RC1 发布,VM优化,默认为HAMMER2
  • PrimeNG 8.0.0 发布,支持Angular 8,FocusTrap等
  • GIMP 2.10.12 发布,一些有用的改进
  • 清华大学Anaconda 镜像服务即将恢复
  • Debian GNU/Linux 10 “Buster” 操作系统将于2019年7月6日发布
  • 时时彩论坛
  • 五星体育斯诺克
  • 北单比分直播
  • 河北11选5走势图
  • 福建体彩36选7开奖结果
  • 九龙图库下载