mysql数据库死锁原因分析
一、死锁模拟复现
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隔离级别来解决幻读的一种措施
mysql数据库死锁原因分析相关推荐
- mysql数据库死锁几种情况
mysql数据库死锁的产生原因及解决办法 数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会 ...
- 分布式MySQL数据库TDSQL架构分析
分布式MySQL数据库TDSQL架构分析 发表于11小时前| 次阅读| 来源程序员电子刊| 0 条评论| 作者雷海林 MySQLTDSQL腾讯架构 width="22" he ...
- WampServer + phpcms 开发中,浏览器 localhost 出现 Cannot to connect to mySQL server 的原因分析和解决办法?
首先,确定你phpcms的文件已经都已经放置在对应的文件目录下! 注意: 本文针对 Wampserver + phpcms 开发中出现的此类问题.其他情况仅供参考. 在安装软件**WampServer ...
- mysql unauthenticated user原因分析以及解决方法
mysql unauthenticated user原因分析以及解决方法 参考文章: (1)mysql unauthenticated user原因分析以及解决方法 (2)https://www.cn ...
- mysql数据库死锁的产生原因及解决办法
该文章为转载,如有侵权请及时联系 这篇文章主要介绍了mysql数据库锁的产生原因及解决办法,需要的朋友可以参考下 数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据 ...
- mysql 数据库 死锁_Mysql数据库出现死锁的情况(一)
在临近上线之前,我们系统做了一次压力测试,发现有一个接口在高并发情况下会出现一个死锁的情况..首先申明-不是我写的,我只是帮忙排查下. 随着对Mysql锁的深入了解,于是就准备写几篇文章来记录下Mys ...
- 记一次mysql数据库死锁实验
概述 之前接触到的数据库死锁,很多都是批量更新时加锁顺序不一致而导致的死锁,但是上周却遇到了一个很难理解的死锁.借着这个机会又重新学习了一下mysql的死锁知识以及常见的死锁场景.今天不介绍死锁的基本 ...
- Java多线程、高并发秒杀时MySQL出现死锁原因(Deadlock found when trying to get lock)及对应解决方案
1. 死锁背景 1.1 在做高并发秒杀中创建订单.减库存步骤时出现异常:MySQLTransactionRollbackException: Deadlock found when trying to ...
- mysql 没有mysql库_MySQL安装之后没有MySQL数据库的原因
mysql安装完之后,登陆后发现只有两个数据库:mysql> show databases; +--------------------+ | Database | +--- ...
最新文章
- BN和Dropout在训练和测试时有哪些差别?
- java在线问答系统_求一个基于JAVA的在线答疑系统程序
- [BJOI2015]树的同构
- fiddler抓取https请求
- python中Json、os、sys、hashlib等内置模块
- jQuery修改数组$.map
- 正确处理kafka多线程消费的姿势
- 复制控制---复制构造函数
- SAP Spartacus popover Component 的单元测试
- openlayer 图层上下_OpenLayers实现图层切换控件
- KMP算法----java实现
- ROS 教程之 network:多台计算机之间网络通信(2)
- 【Elasticsearch】es 5.3.0 bulk index 性能调优实践
- 【转】认识 C++ 中的 explicit 关键字
- 源码pub:C#实现IPv6地址的二进制输出
- android root su sticky bit
- java 获取本机ip地址吗_java 获取本机ip地址
- 用了40年,我们在元宇宙中打开了通往未来世界一道门
- RK系列开发板音频驱动适配指南(二)
- NOIP 2018 提高组初赛试题 题目+答案+简要解析
热门文章
- facetime使用普及
- python以表格形式打印出结果——PrettyTable
- java.lang.RuntimeException: Can't create handler inside thread that has not
- 实战 SQL Server 2008 数据库误删除数据的恢复
- 从Aavegotchi为例,看游戏公会现状和盈利情况
- ES5.6.4源码解析--聚合查询流程
- 【附源码】计算机毕业设计SSM无人值守台球厅智能管理监控系统
- 竞选计算机课代表演讲稿开头,竞选课代表的演讲稿模板集锦8篇
- Android对View进行截图
- API接口自动化测试框架搭建(三)-开发环境安装