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

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

谈谈MySQL死锁 一的更多相关文章

  1. 谈谈MySQL死锁之二 死锁检测和处理源码分析

    这一篇主要是通过一个实验来进行描述,过程是比较枯燥的. 实验准备 create table test_lock(id int auto_increment primary key ,stock int ...

  2. 谈谈MySQL中的锁

    谈谈MySQL中的锁 锁的定义 ​ 在生活中锁的例子就非常多了,所以应该很容易理解锁的含义.在计算机领域,可以这样来概述,锁是计算机协调多个进行进程并发访问某一资源的机制. ​ 在数据库中,锁也是一个 ...

  3. MySQL 死锁问题分析

    转载: MySQL 死锁问题分析 线上某服务时不时报出如下异常(大约一天二十多次):"Deadlock found when trying to get lock;". Oh, M ...

  4. 为什么MySQL死锁检测会严重降低TPS

    在大量的客户端,更新数据表的同一行时,会造成数据库的吞吐量大幅降低. 很多数据库的前辈和同行分别通过实验和源码的方法,定位到了罪魁祸首----MySQL死锁检测 实验方式:http://blog.cs ...

  5. Mysql 死锁问题

    Innodb锁系统(4) Insert/Delete 锁处理及死锁示例分析 http://mysqllover.com/?p=431 关于innodb死锁 http://afei2.sinaapp.c ...

  6. 谈谈MySQL数据表的类型(转)

    谈谈MySQL数据表的类型 通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合. 我们通常说的MySql数据库,sql server数据库等等其 ...

  7. Mysql死锁问题解决方式 & 聚簇索引、隔离级别等知识

    参考了这篇文章:http://www.cnblogs.com/LBSer/p/5183300.html  <mysql死锁问题分析> 写的不错. 如果Mysql死锁,会报出: 1.1 死锁 ...

  8. 一次MySQL死锁问题解决

    一次MySQL死锁问题解决 一.环境 CentOS, MySQL 5.6.21-70, JPA 问题场景:系统有定时批量更新数据状态操作,每次更新上千条记录,表中总记录数约为500W左右. 二.错误日 ...

  9. MySQL死锁案例分析与解决方案

    MySQL死锁案例分析与解决方案 现象: 数据库查询: SQL语句分析:  mysql. 并发delete同一行记录,偶发死锁.   delete from x_table where id=?   ...

随机推荐

  1. 使用k8s operator安装和维护etcd集群

    关于Kubernetes Operator这个新生事物,可以参考下文来了解这一技术的来龙去脉: https://yq.aliyun.com/articles/685522?utm_content=g_ ...

  2. VMvare虚拟机如何删除安装的ubuntu操作系统

    VMvare虚拟机如何删除安装的ubuntu操作系统呢??? 这个问题其实在我刚开始接触虚拟机和ubuntu操作系统的时候对于如何删除操作系统是一件很苦恼的事情,因为按照书本的步骤,根本看不懂如何操作 ...

  3. private static final long serialVersionUID = 1L这句话到底什么意思?

    变量serialVersionUID称为序列化版本号,这个变量多用于实现了Serializable的类中,试用场景是类的序列化.当我们没有定义这个变量的时候,虚拟机会根据类的属性算出一个独一无二的该变 ...

  4. Codeforces 605C Freelancer's Dreams 凸包 (看题解)

    Freelancer's Dreams 我们把每个二元组看成是平面上的一个点, 那么两个点的线性组合是两点之间的连线, 即x * (a1, b1) + y * (a1, b1) && ...

  5. 6-10 下落的树叶 uva699

    类似第九题  都是属于比较巧妙的题目  ! 用一个p数组来保存水平值   然后开始built 自然就会按照自左而右的顺序来读取!!!!!!这很重要 #include<bits/stdc++.h& ...

  6. hdu 1394 (线段树求逆序数)

    <题目链接> 题意描述: 给你一个有0--n-1数字组成的序列,然后进行这样的操作,每次将最前面一个元素放到最后面去会得到一个序列,那么这样就形成了n个序列,那么每个序列都有一个逆序数,找 ...

  7. C++泛型线性查找算法——find

    C++泛型线性查找算法--find <泛型编程和STL>笔记及思考. 线性查找可能是最为简单的一类查找算法了.他所作用的数据结构为一维线性的空间.这篇文章主要介绍使用 C++ 实现泛型算法 ...

  8. C# 遍历控件 示例

    foreach(Control c in tabControl1.TabPages)//这个循环的意思是说,遍历tabControl1中所有的TabPages,TabPages是包含在tabContr ...

  9. 关于文档模式、DCOTYPE声明及严格模式

    1.文档模式 文档模式的概念是由IE5.5引入,通过使用文档类型(DOCTYPE)切换实现的.不同的文档模式主要影响CSS内容的呈现,尤其是浏览器对盒模型的解析,但在某些情况下也会影响到JavaScr ...

  10. BZOJ.1901.Dynamic Rankings(线段树套平衡树 Splay)

    题目链接or Here 题意:n个数,有两个操作:1.修改某个数为v:2.询问一段区间第k小的数 如果没有修改,则可以用线段树,每个节点P[a,b]存储大小为b-a+1的数组,代表其中的数 同时,这个 ...