数据越来越和我们的生活离不开,数据在生命周期的各个阶段有着不同的痛点和需求以及特殊场景。

CURD是数据的四大基本需求:写入,更新,读取,删除.

今天,来谈一谈死锁问题

死锁是高并发下MySQL不可回避的一个问题。

这句话可以引申四个问题:

1.什么是死锁?

2.MySQL什么时候会检测死锁?

3.数据库系统如何处理死锁?

4.有哪些典型的高并发死锁场景?

1.我们先来看看什么是死锁。

在《数据库系统实现》第八章第二节这样定义死锁

并发执行的事务由于竞争资源而到达一个存在死锁的状态:若干事务的每一个事务都在等待被其他事务占用的资源,因而每个事务都不能取得进展。

这个描述貌似很拗口,我们举两个例子来形象化认识一下:

1.两位木匠钉地板,一位只握一把斧头,而另一位没有榔头,却有钉子

2.堵车现象

看完死锁的定义描述和形象化认识,那对于MySQL,什么时候会进行死锁检测?

 

2.MySQL的死锁检测和回滚

这里谈论MySQL的死锁检测,目前仅讨论InnoDB的处理,暂不涉及MyRocks的死锁检测处理。

当InnoDB事务尝试获取(请求)加一个锁,并且需要等待时,InnoDB会进行死锁检测.

正常的流程如下:

1.InnoDB的初始化一个事务,当事务尝试获取(请求)加一个锁,并且需要等待时(wait_lock),innodb会开始进行死锁检测(deadlock_mark)

2.进入到lock_deadlock_check_and_resolve ,名字很明显了,要检测死锁和解决死锁

3.检测死锁过程中,也是有计数器来进行限制的

4.死锁检测的逻辑之一是等待图的处理过程,如果通过锁的信息和事务等待链构造出一个图,如果图中出现回路,就认为发生了死锁。

5.死锁的回滚,内部代码的处理逻辑之一是比较undo的数量

3.数据库系统如何处理死锁

我们回头继续看《数据库系统实现》里面提到的死锁处理

1.超时死锁检测:当存在死锁时,想所有事务都能同时继续执行通常是不可能的,因此,至少一个事务必须中止并重新开始。超时是最直接的办法,对超出活跃时间的事务进行限制和回滚

2.等待图:等待图的实现,是可以表明哪些事务在等待其他事务持有的锁,可以在数据库的死锁检测里面加上这个机制来进行检测是否有环的形成。

3.通过元素排序预防死锁:这个想法很美好,但现实很残酷,通常都是发现死锁后才去想办法解决死锁的原因

4.通过时间戳检测死锁:对每个事务都分配一个时间戳,根据时间戳来进行回滚策略。

这里贴一下等待图的示例

4.有哪些典型的高并发死锁场景?

1.秒杀场景,每个秒杀都是针对同一行的活跃事务,源源不断的事务发现自己加锁的那一行已经被人锁了,这时候InnoDB会进入一个蛋疼的没必要的死锁检测,后续给大家讲讲怎么解决

2.使用二级索引去高并发更新二级索引记录(很拗口吧?),MySQL的索引计划不是100%准确的,我手上有case在并发更新不同记录的时候,因为索引计划走错了,导致某一个事务用了二级索引读记录,另外一个事务用主键来读记录,进而产生了死锁,这个案例后续也会整理出来。

最后 MySQL的源码如何进行死锁检测和处理?

这个问题是后续的关键,但没整理完,先歇一歇...

建议先读一读上一篇《InnoDB事务结构体代码变量列表》,因为死锁是在活跃事务等待锁的情况下才会去检测,要先去了解InnoDB事务结构体的trx_lock_t

最新文章

  1. 崽崽帮www.zaizaibang.com精选14
  2. 强制QQ好友
  3. powershell,系统学习的第一种脚本语言
  4. 如何将angularJs项目与requireJs集成
  5. Ajax从服务器端获取数据---原生态Ajax
  6. JSON 数字排序 多字段排序
  7. Clone Graph 解答
  8. WP8加入自己定义铃声
  9. SpringBoot JPA实现增删改查、分页、排序、事务操作等功能
  10. Python自然语言处理学习笔记之信息提取步骤&分块(chunking)
  11. win10 uwp 拖动控件
  12. poj 1228 稳定凸包
  13. MySQL InnoDB 日志管理机制中的MTR和日志刷盘
  14. vue组件导航栏动态添加class
  15. 【Windows】cmd条件判断
  16. 线程之threading
  17. cron表达式增加一段时间变为新的表达式
  18. 团队冲刺--Seven
  19. Vue学习计划基础笔记(五) - 表单输入绑定、组件基础
  20. BZOJ 4036: [HAOI2015]按位或 集合幂函数 莫比乌斯变换 莫比乌斯反演

热门文章

  1. 合成/聚合复用原则(Composite/Aggregate Reuse Principle, CARP)
  2. day9--队列queue
  3. git shell 命令大全
  4. python中的协程:greenlet和gevent
  5. BZOJ1087 [SCOI2005]互不侵犯King 状态压缩动态规划
  6. 098实战 Job的调度
  7. 类 __new__方法实现单例
  8. HDU - 1392 凸包求周长(模板题)【Andrew】
  9. 51Nod-1006【LCS】+【输出路径】模板题
  10. setting.xml配置文件