mysql 唯一索引 死锁_MySQL死锁案例_唯一索引
近期在MySQL数据库中产生了死锁的情况,与通常的死锁不同,由于表中有唯一索引,所以加锁方式也比较有趣,本文将对于该例进行阐述(本文将对数据进行脱敏操作):
问题描述:隔离级别:READ-COMMITTED
表结构:
show create table \G
CREATE TABLE `uniq` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`aa` int(11) DEFAULT NULL,
`bb` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_ab` (`aa`,`bb`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
注意其中存在唯一索引:UNIQUE KEY `uniq_ab` (`aa`,`bb`)
SQL执行顺序:
SQL执行顺序
问题解析:
对于唯一索引,insert成功后,会加上X lock;
对于唯一索引的插入,需要在插入前进行duplicate key的检查,所以需要申请加上S lock,由于S lock与X lock不兼容,所以产生锁等待;
由于GAP与INSERT_INTENTION不兼容,所以产生锁等待,至此死锁产生。
基本概念
MySQL Innodb中的锁:
S LOCK:共享锁,也称读锁
X LOCK:排它锁,也称写锁
IS LOCK:暗示一个事务需要加共享锁
IX LOCK:暗示一个事务需要加排它锁
对应的兼容关系:
锁兼容关系
此外,还有一套更为精准的判断逻辑,以符合更多场景,所以MySQL还具有以下几类的锁类型:Record lock(记录锁):加在索引行上的锁。
GAP lock(间隙锁):加在record两侧间隙上的锁,但是不包括数据本身。
Next-key lock:Record lock + GAP lock
INSERT_INTENTION lock(插入意向锁):在insert之前,需要申请INSERT_INTENTION lock
举例:
Session1: mysql> CREATE TABLE child (id int(11) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;
mysql> INSERT INTO child (id) values (90),(102); mysql> START TRANSACTION; mysql> SELECT * FROM child WHERE id > 100 FOR UPDATE; Session2:
mysql> START TRANSACTION; mysql> INSERT INTO child (id) VALUES (101);
则Session2会产生INSERT_INTENTION lock waiting
Insert对于唯一索引的加锁方式:
对于insert的行,加上X lock,在Insert之前,需要加上 INSERT_INTENTION lock。
问题解决:
方案一(调整后端):
由于事发的逻辑为:一个事务中进行多次insert。在数据库层面的展示即为多次申请锁资源,并且是并发的事务,所以当插入的数据出现资源抢占时,容易发生死锁。
所以建议:insert时插入多个值,一次性申请该sql的所有锁资源。这样,则可以避免多次申请锁资源,同时在性能上也能得以提升。
方案二(调整前端逻辑):
规避重复触发的情况,防止不同事务在唯一索引上插入相同数据。
mysql 唯一索引 死锁_MySQL死锁案例_唯一索引相关推荐
- mysql insert s锁_MySQL 死锁套路:唯一索引 S 锁与 X 锁的爱恨情仇
在初学者从源码理解MySQL死锁问题中介绍了使用调试 MySQL 源码的方式来查看死锁的过程,这篇文章来讲讲一个常见的案例. 毫不夸张的说,有一半以上的死锁问题由唯一索引贡献,后面介绍的很多死锁的问 ...
- mysql 唯一索引 死锁_MySQL 死锁套路:唯一索引 S 锁与 X 锁的爱恨情仇
毫不夸张的说,有一半以上的死锁问题由唯一索引贡献,后面介绍的很多死锁的问题都跟唯一索引有关.这次我们讲一段唯一索引 S 锁与 X 锁的爱恨情仇 我们来看一个简化过的例子 # 构造数据 CREATE T ...
- 如何判断mysql死锁_MySQL 死锁问题分析
线上某服务时不时报出如下异常(大约一天二十多次):"Deadlock found when trying to get lock;". Oh, My God! 是死锁问题.尽管报错 ...
- mysql数据库批量插数死锁_MySQL 死锁套路:一次诡异的批量插入死锁问题分析
线上最近出现了批量insert的死锁,百思不得姐.死锁记录如下 2018-10-26T11:04:41.759589Z 8530809 [Note] InnoDB: *** (1) TRANSACTI ...
- mysql锁问题排查_Mysql死锁问题如何排查和解决?
前言 发生死锁了,如何排查和解决呢?本文将跟你一起探讨这个问题 准备好数据环境 模拟死锁案发 分析死锁日志 分析死锁结果 环境准备 数据库隔离级别: mysql> select @@tx_iso ...
- mysql取消死锁_mysql 死锁可以自动解除吗
1. session1 执行 delete 会在唯一索引 c2 的 c2 = 15 这一记录上加 X lock(也就是在MySQL 内部观测到的:X Lock but not gap): 2. se ...
- mysql常见死锁_MySQL死锁系列-常见加锁场景分析
如下图所示,数据库的隔离等级,SQL 语句和当前数据库数据会共同影响该条 SQL 执行时数据库生成的锁模式,锁类型和锁数量. 下面,我们会首先讲解一下隔离等级.不同 SQL 语句 和 当前数据库数据对 ...
- 重启 mysql死锁_MySQL死锁导致无法查询的问题
之前从来没有遇到过mysql死锁的问题,今天第一次,查看了很多博客,问题终于解决啦,在此特意记录和分享. 1.第一种方式:重启MySQL 因为MySQL的事务产生了死锁,刚开始我是直接重启MySQL, ...
- MySQL之事务 索引 锁_MySql 知识点之事务、索引、锁原理与用法解析
本文实例讲述了MySql 知识点之事务.索引.锁原理与用法.分享给大家供大家参考,具体如下: 事务 事务概念 事务就是一组原子性的SQL查询,或者说一个独立的工作单元.如果数据库引擎执行一组操作语句, ...
- Mysql索引基本概念及案例总结(含索引的使用注意事项)
Mysql索引基本概念及案例总结 键(Key)与索引(Index)关键字的区别 索引是键的列表,当我们定义一个key(外键除外,一般是PRIMARY KEY或者KEY形式)时就会产生对应的索引.一般情 ...
最新文章
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu[转]
- android崩溃日志收集
- Oracle数据库用户角色、表空间创建、删除命令
- Secure CRT 自动记录日志和时间戳功能配置
- 实现输入一个字符串,分别将大写字母、小写字母、数字、其他字符存到列表里面并且输出列表
- html 调用c#dll中的控件,C#调用ActiveX控件的方法
- centos8下搭建gotk3(go语言gtk库) x86_64-w64-mingw32交叉编译环境
- linux vnc端口映射,linux服务器配置docker+vnc,随时访问远程桌面
- 1012 数字分类 (20 分)—PAT (Basic Level) Practice (中文)
- App性能测试以及测试方法技巧
- java 问题 无法解析类型 java.lang.CharSequence。从必需的 .class 文件间接引用了它
- Spark3.0新特性-AQE
- 保利威视自定义右键菜单设置
- 2021有效的电子邮箱号码大全,外贸企业邮箱地址大全
- 2022年全国大学生数学建模竞赛赛题B组解题参考+代码
- 学生用计算机app,学生方程计算器
- 通往古埃及文明的钥匙 ———— 罗塞塔石碑
- OTA法规及备案要求
- EtherCAT通讯简介
- 针对Arduino IDE 2.0安装后找不到端口的问题(USB转串口驱动)(Win11)