千家信息网

MySQL死锁套路之唯一索引下批量插入顺序不一致

发表于:2024-10-19 作者:千家信息网编辑
千家信息网最后更新 2024年10月19日,前言死锁的本质是资源竞争,批量插入如果顺序不一致很容易导致死锁,我们来分析一下这个情况。为了方便演示,把批量插入改写为了多条 insert。先来做几个小实验,简化的表结构如下CREATE TABLE
千家信息网最后更新 2024年10月19日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 同时执行,第二个会进行锁等待状态

t1t2
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:

批量插入顺序不一致的导致的死锁

t1t2
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安全错误 数据库的锁怎样保障安全 安全合规软件开发管理 怎么把图片储存到数据库代码 软件开发criconse 大型数据库技术赵德玉 韩国服务器设置到国内路由器上 强化制度落实确保网络安全 数据库基础与应用在线 pes21球员数据库 交通银行软件开发中心好吗 河北护苗网络安全课程 农发行软件开发中心待遇30万 为什么机顶盒显示访问服务器失败 数据库有数据查不出来 网络安全叠加区块链链股票 完善境外渗透人员数据库 网络安全不好找工作吗 小学第五届网络安全宣传方案 郑州数据库招商 打印电子发票没有服务器啥意思 中国域名根服务器 千颐网络技术有限公司 瑞庭网络技术苏州 试论述网络安全的机遇及挑战 开展网络安全宣传周总结报告 山东网络安全知识竞赛答题网站 中国网络技术有限公司在哪里 魔兽世界潘达利亚数据库 有效保障国家网络安全 服务器安全考虑哪些问题吗 安卓软件开发魔镜实验报告
0