【高并发高性能高可用之海量数据MySQL实战-22】-MySQL死锁原理与分析

本文前面的部分,基本上已经涵盖了MySQL/InnoDB所有的加锁规则。深入理解MySQL如何加锁,有两个比较重要的作用:

可以根据MySQL的加锁规则,写出不会发生死锁的SQL;

可以根据MySQL的加锁规则,定位出线上产生死锁的原因;

1:示例分析

下面,来看看两个死锁的例子 (一个是两个Session的两条SQL产生死锁;另一个是两个Session的一条SQL,产生死锁)

上面的两个死锁用例。第一个非常好理解,也是最常见的死锁,每个事务执行两条SQL,分别持有了一把锁,然后加另一把锁,产生死锁。

第二个用例,虽然每个Session都只有一条语句,仍旧会产生死锁。要分析这个死锁,首先必须用到本文  前面提到的MySQL加锁的规则。针对Session 1,从name索引出发,读到的[hdc,1],[hdc,6]均满足条件,不仅会加name索引上的记录X锁,而且会加聚簇索引上的记录X锁,加锁顺序为先[1,hdc,100],后[6,hdc,10]。而Session 2,从pubtime索引出发,[10,6],[100,1]均满足过滤条件,同样也会加聚簇索引上的记录X锁,加锁顺序为[6,hdc,10],后[1,hdc,100]。发现没有,跟Session 1的加锁顺序正好相反, 如果两个Session恰好都持有了第一把锁,请求加第二把锁,死锁就发生了。

2.结论 

死锁的发生与否,并不在于事务中有多少条SQL语句,
【死锁的关键在于】:两个(或以上)的Session
【加锁的顺序】不一致。
而使用本文上面提到的,分析MySQL每条SQL语句的加锁规则,分析出每条语句的加锁顺序,
然后检查多个并发SQL间是否存在以相反的顺序加锁的情况,就可以分析出各种潜在的死锁情况,
也可以分析出线上死锁发生的原因。

3.如何避免死锁呢

MySQL默认会主动探知死锁,并回滚某一个影响最小的事务。等另一事务执行完成之后,再重新执行该事务。

如何避免死锁

1、注意程序的逻辑

根本的原因是程序逻辑的顺序,最常见的是交差更新

Transaction 1: 更新表A -> 更新表B

Transaction 2: 更新表B -> 更新表A

Transaction 获得两个资源

2、保持事务的轻量

越是轻量的事务,占有越少的锁资源,这样发生死锁的几率就越小

3、提高运行的速度

避免使用子查询,尽量使用主键等等

4、尽量快提交事务,减少持有锁的时间越早提交事务,锁就越早释放

如果您觉得文章好看,欢迎点赞收藏加关注,一连三击呀,您的肯定是我持续输出的动力,感谢!!☺☻ 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不要迷恋发哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值