MySQL死锁套路之唯一索引下批量插入顺序不一致
发表于:2025-01-21 作者:千家信息网编辑
千家信息网最后更新 2025年01月21日,前言死锁的本质是资源竞争,批量插入如果顺序不一致很容易导致死锁,我们来分析一下这个情况。为了方便演示,把批量插入改写为了多条 insert。先来做几个小实验,简化的表结构如下CREATE TABLE
千家信息网最后更新 2025年01月21日MySQL死锁套路之唯一索引下批量插入顺序不一致
前言
死锁的本质是资源竞争,批量插入如果顺序不一致很容易导致死锁,我们来分析一下这个情况。为了方便演示,把批量插入改写为了多条 insert。
先来做几个小实验,简化的表结构如下
CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `a` varchar(5), `b` varchar(5), PRIMARY KEY (`id`), UNIQUE KEY `uk_name` (`a`,`b`));
实验1:
在记录不存在的情况下,两个同样顺序的批量 insert 同时执行,第二个会进行锁等待状态
t1 | t2 | |
---|---|---|
begin; | begin; | |
insert ignore into t1(a, b)values("1", "1"); | 成功 | |
insert ignore into t1(a, b)values("1", "1"); | 锁等待状态 |
可以看到目前锁的状态
mysql> select * from information_schema.innodb_locks;+-------------+-------------+-----------+-----------+------------+------------+------------+-----------+----------+-----------+| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |+-------------+-------------+-----------+-----------+------------+------------+------------+-----------+----------+-----------+| 31AE:54:4:2 | 31AE | S | RECORD | `d1`.`t1` | `uk_name` | 54 | 4 | 2 | '1', '1' || 31AD:54:4:2 | 31AD | X | RECORD | `d1`.`t1` | `uk_name` | 54 | 4 | 2 | '1', '1' |+-------------+-------------+-----------+-----------+------------+------------+------------+-----------+----------+-----------+
在我们执行事务t1的 insert 时,没有在任何锁的断点处出现,这跟 MySQL 插入的原理有关系
insert 加的是隐式锁。什么是隐式锁?隐式锁的意思就是没有锁
在 t1 插入记录时,是不加锁的。这个时候事务 t1 还未提交的情况下,事务 t2 尝试插入的时候,发现有这条记录,t2 尝试获取 S 锁,会判定记录上的事务 id 是否活跃,如果活跃的话,说明事务未结束,会帮 t1 把它的隐式锁提升为显式锁( X 锁)
源码如下
t2 获取S锁的结果:DB_LOCK_WAIT
实验2:
批量插入顺序不一致的导致的死锁
t1 | t2 | |
---|---|---|
begin | ||
insert into t1(a, b)values("1", "1"); | 成功 | |
insert into t1(a, b)values("2", "2"); | 成功 | |
insert into t1(a, b)values("2", "2"); | t1 尝试获取 S 锁,把 t2 的隐式锁提升为显式 X 锁,进入 DB_LOCK_WAIT | |
insert into t1(a, b)values("1", "1"); | t2 尝试获取 S 锁,把 t1 的隐式锁提升为显式 X 锁,产生死锁 |
------------------------LATEST DETECTED DEADLOCK------------------------181101 9:48:36*** (1) TRANSACTION:TRANSACTION 3309, ACTIVE 215 sec insertingmysql tables in use 1, locked 1LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s), undo log entries 2MySQL thread id 2, OS thread handle 0x70000a845000, query id 58 localhost root updateinsert into t1(a, b)values("2", "2")*** (1) WAITING FOR THIS LOCK TO BE GRANTED:RECORD LOCKS space id 55 page no 4 n bits 72 index `uk_name` of table `d1`.`t1` trx id 3309 lock mode S waitingRecord lock, heap no 3 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 1; hex 32; asc 2;; 1: len 1; hex 32; asc 2;; 2: len 4; hex 80000002; asc ;;*** (2) TRANSACTION:TRANSACTION 330A, ACTIVE 163 sec insertingmysql tables in use 1, locked 13 lock struct(s), heap size 376, 2 row lock(s), undo log entries 2MySQL thread id 3, OS thread handle 0x70000a888000, query id 59 localhost root updateinsert into t1(a, b)values("1", "1")*** (2) HOLDS THE LOCK(S):RECORD LOCKS space id 55 page no 4 n bits 72 index `uk_name` of table `d1`.`t1` trx id 330A lock_mode X locks rec but not gapRecord lock, heap no 3 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 1; hex 32; asc 2;; 1: len 1; hex 32; asc 2;; 2: len 4; hex 80000002; asc ;;*** (2) WAITING FOR THIS LOCK TO BE GRANTED:RECORD LOCKS space id 55 page no 4 n bits 72 index `uk_name` of table `d1`.`t1` trx id 330A lock mode S waitingRecord lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 1; hex 31; asc 1;; 1: len 1; hex 31; asc 1;; 2: len 4; hex 80000001; asc ;;*** WE ROLL BACK TRANSACTION (2)
怎么样解决这样的问题呢?
一个可行的办法是在应用层排序以后再插入
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
事务
死锁
尝试
顺序
成功
情况
状态
实验
一致
内容
就是
时候
学习
可行
两个
价值
前言
办法
原理
同时
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全警示教育新闻稿
传统关系型数据库优缺点
金丰汇网络技术有限公司
网络安全机构
教师网络安全宣传片
东莞数字软件开发源头好货
未来之役游戏内改服务器
服务器怎么多开传奇引擎
江西app软件开发流程
南京推荐无忧网络技术公司
铜川数据库修复
hzed网络安全管理
网络安全审查制度有哪些业务
淮南科艾网络技术
贵州区块链软件开发
如何导入sql数据库
足球即时球探比分数据库
数据库孟彩霞
计算机 网络技术考研
剪影软件开发
山东省金乡县网络安全
学数据库用win
数据库密码是数据库文件的密码吗
cg数据库
零售商品数据库
未安装数据库与服务器
有什么关于网络安全的书
数据库中序列
手机游戏卡顿无法连接服务器
银行网络安全工作落实情况报告