mysql数据库死锁原因分析

article/2025/8/26 18:01:57

一、死锁模拟复现

1、当前自己电脑的mysql版本8.0.22

2、数据库的隔离级别--可重复读(默认隔离级别)

3、自动提交关闭

4、表结构,age为非唯一索引,对下面整个案例非常重要

5、

1、事务A执行更新操作,更新成功

2、事务B执行更新操作,更新成功

3、事务A执行插入操作,陷入阻塞

4、事务B执行插入操作,插入成功,同时事务A的插入由阻塞变为死锁error,事务A的插入操作变成报错

最终结果如下:

我们发现事务一被回滚,事务二执行成功

那既然是死锁,为什么回滚事务A,而不是事务B,是随机的还是有机制在里面?

我们可以理解死锁是数据库对事务的保护机制,一旦发生死锁,MySQL会选择相对小的事务(undo较少的)进行回滚

分析死锁日志

执行命令 :show engine innodb status

二、介绍mysql中的锁

1、mysql中的锁

记录锁

记录锁其实很好理解,对表中的记录加锁,叫做记录锁,简称行锁

例如:

select * from user where id = 1 for update;

UPDATE SET age = 50 WHERE id = 1;

需要注意的是:

  • id 列必须为唯一索引列或主键列,否则上述语句加的锁就会变成临键锁(有关临键锁下面会讲)。
  • 同时查询语句必须为精准匹配(=),不能为 >、<、like等,否则也会退化成临键锁

记录锁是锁住记录,锁住索引记录,而不是真正的数据记录. 如果要锁的列没有索引,进行全表记录加锁

间隙锁(Gap Locks)

幻读例子

间隙锁 是 Innodb 在 RR(可重复读) 隔离级别 下为了解决幻读问题时引入的锁机制。间隙锁是innodb中行锁的一种

请务必牢记:使用间隙锁锁住的是一个区间,而不仅仅是这个区间中的每一条数据

存在以下间隙

(-∞, 1] (1, 4] (4, 7] (7, +supernum]

临键锁(Next-Key Locks)

Next-key锁是记录锁和间隙锁的组合,它指的是加在某条记录以及这条记录前面间隙上的锁。也可以理解为一种特殊的间隙锁。通过临建锁可以解决幻读的问题。每个数据行上的非唯一索引列上都会存在一把临键锁,当某个事务持有该数据行的临键锁时,会锁住一段左开右闭区间的数据。

需要强调的一点是,InnoDB 中行级锁是基于索引实现的

锁总结:

1、当使用唯一索引来等值查询的语句时, 如果这行数据存在,不产生间隙锁,而是记录锁

2、当使用唯一索引来等值查询的语句时, 如果这行数据不存在,会产生间隙锁

3、当使用唯一索引来范围查询的语句时,对于满足查询条件但不存在的数据产生间隙(gap)锁,如果查询存在的记录就会产生记录锁,加在一起就是临键锁(next-key)锁

4、当使用普通索引不管是锁住单条,还是多条记录,都会产生间隙锁;

5、在没有索引上不管是锁住单条,还是多条记录,都会产生表锁

三、死锁的产生的原因

数据库中有两条数据 id主键,age是非唯一主键

补充:

通过事务A和事务B的update语句,我们可以发现其实它们都持有间隙锁(10,20)的这段范围,说明间隙锁范围是可以相互兼容的,意思就是只要你的10不在我(10,+∞)的间隙锁范围内,那就可以产生部分重合的间隙锁,也就是这里的(10,20)

四、实际开发中如何尽量避免死锁发生

1、不同的应用访问同一组表时,应尽量约定以相同的顺序访问各表。对一个表而言,应尽量以固定的顺序存取表中的行

2、在主键等值更新的时候,尽量先查询数据库中是否有没有满足的条件,如果没有就不用更新,存在才更新

3、尽量使用主键更新数据,因为主键是唯一索引,在等值查询能查看到数据的情况下,只会产生记录锁,不会产生间隙锁,这样产生的死锁概率就减少了,如果是范围查询一样产生间隙锁

4、避免长事务,小事务发生锁的冲突的概率较小

5、在允许幻读和不可重复度的情况下,尽量使用RC的隔离级别,避免gap lock造成的死锁,因为产生死锁经常都跟间隙锁有关,间隙锁的存在本身也是在RR隔离级别来解决幻读的一种措施


http://chatgpt.dhexx.cn/article/xj8ExdvP.shtml

相关文章

处理数据库死锁问题

在实际的项目环境中碰到了如下的问题 Microsoft.Data.SqlClient.SqlException (0x80131904): 事务(进程 ID 98)与另一个进程被死锁在 锁 资源上&#xff0c;并且已被选作死锁牺牲品。请重新运行该事务。 怀疑是因为数据库查询和修改中产生的死锁问题&#xff0c;造成的上述原因…

数据库死锁:原因和解决办法

理解数据库中的死锁 在数据库的上下文中&#xff0c;死锁是指两个或多个事务无法进行的情况&#xff0c;因为每个事务都在等待另一个事务释放资源。这可以类比为事务的循环链&#xff0c;每个事务都在等待链中的下一个事务释放资源。以下是一个死锁场景的视觉表示&#xff1a;…

Java面试必问:死锁(多线程死锁+数据库死锁)

死锁 接下来从几个方面介绍&#xff1a; 多线程死锁多线程死锁解决办法数据库死锁数据库死锁解决办法 多线程死锁是怎么造成的&#xff1f; 多线程锁定同一资源会造成死锁线程池中的任务使用当前线程池也可能出现死锁 参考连接&#xff1a; https://blog.csdn.net/qq_3506…

MySQL数据库死锁了,该怎么办?一文全解最新教程

文章目录 正文死锁的发生为什么会产生死锁&#xff1f;Insert 语句是怎么加行级锁的&#xff1f;1、记录之间加有间隙锁2、遇到唯一键冲突 如何避免死锁&#xff1f; 之前分享过 MySQL 死锁的文章&#xff0c;然后很多读者对「插入意向锁」认识很迷糊。 大家误以为「插入意向锁…

5 分钟理解数据库死锁

图片来源&#xff1a;网络 文章目录 死锁是如何产生的&#xff1f;如何解决并避免死锁总结 &#x1f37a;知人者智&#xff0c;自知者明。胜人者有力&#xff0c;胜己者强。知足者富&#xff0c;强行者有志。不失其所者久&#xff0c;死而不亡者寿。——老子 大家好&#xff01…

数据库死锁场景

场景一&#xff1a; 单一线程多次进入子事务发生死锁 问题&#xff1a; 线上问题发生了死锁&#xff0c;但通过死锁日志发现一直在等待查询结果。我们使用的数据库是PGsql&#xff0c;默认的隔离级别是“读已提交”&#xff0c;按理来说查询不会加锁&#xff0c;导致一度被带偏…

数据库常见死锁原因及处理

目录 前言什么是死锁死锁产生的四个必要条件 1. 表锁死锁死锁场景解决方案建议 2. 行锁死锁2.1 两个事务分别想拿到对方持有的锁&#xff0c;互相等待&#xff0c;于是产生死锁死锁场景解决方案 2.2 共享锁转换为排他锁死锁场景解决方案 3. INSERT ... ON DUPLICATE KEY UPDATE…

数据库死锁分析与解决

一、死锁的表现 1、错误信息是:事务(进程 ID)与另一个进程被死锁在 锁 资源上&#xff0c;并且已被选作死锁牺牲品。请重新运行该事务。 2、错误信息是:事务(进程 ID )与另一个进程被死锁在 锁 | 通信缓冲区 资源上&#xff0c;并且已被选作死锁牺牲品。请重新运行该事务。 二、…

数字 IC 技能拓展(1)Xilinx_Vivado_SDK_2019.1 安装详细教程

引言 工欲善其事必先利其器&#xff0c;而君之“器”尚无&#xff0c;就更别谈“事”了。赶紧&#xff01;我们需要下载并安装一个 Xilinx Vivado 软件&#xff01;&#xff01;接下来就飞速地开始我们的 Xilinx_Vivado_SDK_2019.1 详细安装教程&#xff01;&#xff01;&#…

win10安装vivado + vitis 2019.2 教程

win10安装vivado vitis 2019.2 教程 安装包&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1fPlNDzpC0EPXMhOloDyzfA 提取码&#xff1a;1234 网上其他博主的安装教程&#xff0c;比如&#xff1a;vivado2019.2的安装&#xff0c;最后是没有安装上vitis PS端开发软件…

vivado入门教程

vivado入门教程 基本步骤例程实现 第一次写博客&#xff0c;也是第一次使用vivado&#xff0c;自己也在学习之中&#xff0c;欢迎大家的评论啊&#xff01; 基本步骤 一、新建工程 二、选择工程路径及命名 三、一路next到下图&#xff0c;确定芯片的型号 四、添加源文件 五…

手把手教你安装vivado2015.4开发环境

//vivado2015.4安装教程 //作者&#xff1a;紫菜蛋花汤 //时间&#xff1a;2018.7.8 //版本&#xff1a;V1 准备工作&#xff1a; 1.vivado2015.4安装包 官方下载压缩包文件名&#xff1a;Xilinx_Vivado_SDK_2015.4_1118_2.tar 个人百度云连接&#xff1a;https://pan.ba…

Vivado 2015.4 安装教程(含license)

首先先下载vivado2015.4的压缩文件&#xff0c;可以从网盘里下载&#xff1a; 百度网盘链接&#xff1a;点击链接 下载后解压&#xff1a; 点击xsetup.exe文件 点击Next 点击Next 一定要选择第一个Vivado HL WebPack&#xff0c;不要像图中那样选择第三个&#xff0c;因为第一…

vivado 2017.4安装步骤

目录&#xff1a;windows安装vivado2017.4&#xff1b;虚拟机ubuntu安装vivado 2017.4&#xff1b;ios安装vivado。 一&#xff0c;windows安装vivado2017.4 xilinx官网下载地址为&#xff1a;https://www.xilinx.com/support/download.html 下载完解压后&#xff0c;如图所示…

vivado2019.2安装+license添加教程

vivado2019.2安装license添加教程 注意&#xff1a; 1.电脑的账户名字一定是英文&#xff1b; 2.压缩文件夹有30个G&#xff0c;安装后会更大&#xff0c;需要预留足够的空间。 1.资源链接 百度网盘: https://pan.baidu.com/s/1xEuB-vzoXWpj40fd1wAEFg 密码&#xff1a;tkk1…

[Software]Vivado 2018.2 安装及激活教程

一、安装 1、 解压文件 注&#xff1a;要将压缩文件解压至无中文的路径中。 2、 双击“xsetup.exe”文件&#xff0c;开始安装 3、 不选择新版本&#xff0c;选择继续安装此版本 4、 点击“Next”出现协议&#xff0c;在“I Agree”前都打勾 5、 版本选择&#xff0c;用户可以…

Vivado的下载和安装

本文是自己在安装和使用vivado的一个简单记录。 在安装之前进入官网下载好自己需要版本的安装包&#xff0c;软件安装包比较大&#xff0c;需要花费比较长的一段时间。 vivado官网下载地址 &#xff1a;下载地址 安装好软件后需要使用到license文件&#xff0c;可以去官网申…

Vivado2021.2版本安装教程

Vivado2021.2版本安装教程 2021.2版本提取链接&#xff1a;https://pan.baidu.com/s/12P7twkEVErKmqTmkhTnvMg 提取码&#xff1a;2hyr。 第一步&#xff1a;首先打开解压好的软件&#xff0c;找到xsetup.exe,然后管理员模式运行&#xff0c;出现以下界面&#xff0c;点击Next。…

Vivado安装教程详细版

之前问过大佬&#xff0c;哪个版本的vivado更加稳定&#xff0c;大佬说2017.4&#xff0c;于是俺就安装了一个。 安装步骤&#xff1a; 关闭360等杀毒软件。 下载解压后&#xff0c;双击打开这个xsetup程序&#xff1a; 弹出 点击Continue 三个I Agree全部勾选&#xff0c;…

Vivado 2018.3 安装步骤及 license 获取

本文的主要内容是介绍 Vivado 2018.3 版本的安装步骤及其 license 的获取与加载。 首先下载安装包&#xff0c;将其在没有中文的路径下解压。注意在解压前最好关闭电脑的杀毒软件&#xff0c;防止某些文件被拦截或者删除&#xff01; 解压完成后打开文件夹&#xff0c;在最底部…