MySQL:死锁模拟

news/2024/5/20 12:48:12 标签: mysql, 数据库, sql, 死锁

这个问题的关键在于sup伪列上的S锁放大,线上肯定是无序的因此block不一定是最后一个,这里就用顺序来模拟

建表:
CREATE TABLE `test3` (
`id1` int NOT NULL AUTO_INCREMENT,
`id2` int DEFAULT NULL,
 `a` int DEFAULT NULL,
 PRIMARY KEY (`id1`),
  UNIQUE KEY `a` (`a`,`id1`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
Query OK, 0 rows affected, 1 warning (0.05 sec)

sql>mysql> set auto_increment_increment=10;
Query OK, 0 rows affected (0.00 sec)

sql>mysql> insert into test3(id2,a) values(1,1);
Query OK, 1 row affected (0.01 sec)

sql>mysql> insert into test3(id2,a) select id2,a from test3;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

sql>mysql> insert into test3(id2,a) select id2,a from test3;
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

sql>mysql> insert into test3(id2,a) select id2,a from test3;
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0

sql>mysql> insert into test3(id2,a) select id2,a from test3;
Query OK, 8 rows affected (0.01 sec)
Records: 8  Duplicates: 0  Warnings: 0

sql>mysql> insert into test3(id2,a) select id2,a from test3;
Query OK, 16 rows affected (0.01 sec)
Records: 16  Duplicates: 0  Warnings: 0

sql>mysql> insert into test3(id2,a) select id2,a from test3;
Query OK, 32 rows affected (0.01 sec)
Records: 32  Duplicates: 0  Warnings: 0

sql>mysql> insert into test3(id2,a) select id2,a from test3;
Query OK, 64 rows affected (0.02 sec)
Records: 64  Duplicates: 0  Warnings: 0

sql>mysql> insert into test3(id2,a) select id2,a from test3;
Query OK, 128 rows affected (0.03 sec)
Records: 128  Duplicates: 0  Warnings: 0

sql>mysql> insert into test3(id2,a) select id2,a from test3;
Query OK, 256 rows affected (0.05 sec)
Records: 256  Duplicates: 0  Warnings: 0

sql>mysql> insert into test3(id2,a) select id2,a from test3;
Query OK, 512 rows affected (0.11 sec)
Records: 512  Duplicates: 0  Warnings: 0

sql>mysql> insert into test3(id2,a) select id2,a from test3;
Query OK, 1024 rows affected (0.22 sec)
Records: 1024  Duplicates: 0  Warnings: 0

sql>mysql> alter table test3 change id1 id1 int NOT NULL ;
Query OK, 2048 rows affected (0.51 sec)
Records: 2048  Duplicates: 0  Warnings: 0

sql>mysql> alter table test3 drop primary key;
Query OK, 2048 rows affected (0.58 sec)
Records: 2048  Duplicates: 0  Warnings: 0

sql>mysql> alter table test3 add primary key(id1,id2);
Query OK, 0 rows affected (0.15 sec)
Records: 0  Duplicates: 0  Warnings: 0

sql>mysql> alter table test3 add key(a);
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

sql>mysql> update test3 set id2=id1 ,a=id1;
Query OK, 2047 rows affected (1.41 sec)
Rows matched: 2048  Changed: 2047  Warnings: 0

表建立好以后,总共3列,其中id1,id2为主键,a,id1为唯一键,数据处理好以后主键唯一键都是有序的,而线上可能是乱序的。而自增的步长改为了10,记录从1,11,21开始,那么最后几条记录如下:

+-------+-------+-------+
| 30511 | 30511 | 30511 |
| 30521 | 30521 | 30521 |
| 30531 | 30531 | 30531 |
| 30541 | 30541 | 30541 |
| 30551 | 30551 | 30551 |
| 30561 | 30561 | 30561 |
| 30571 | 30571 | 30571 |
| 30581 | 30581 | 30581 |
| 30591 | 30591 | 30591 |
| 30601 | 30601 | 30601 |
+-------+-------+-------+

时序如下:

session1session2session3
begin;
insert into test3 values(119,119,30610);
这一步的目的主要是在唯一键a,id1最后插入一行数据
begin;
insert into test3 values(119,219,30610),(6059,6059,6059);(堵塞)
这一步完成后虽然有两个insert的值,但是第二个数据并没有进行唯一性检查和插入,而是堵塞在第一行数据,第一行数据,主键和session1是没有冲突的,但是唯一键有冲突,因此实际等待点为第一行数据(119,219,30610)对唯一键冲突检测上
begin;
insert into test3 values(6059,6071,6059);(不堵塞完成)
完成这一步我们插入了一行数据,目的在于后面堵塞session2语句的第二行数据在唯一键索引上的数据插入,这里我们可以看到主键是不冲突的,但是唯一键都是6059,6059,因此后面会冲突
rollback;
完成这一步的目的在于让session2的lock s 扩展到唯一键的最后一个block的sup伪列上,为next key lock
注意:这个时候session2的第一行数据插入实际上已经完成,并且有一个lock S到sup伪列上,这个时候堵塞在第二行数据的6059,6059这个唯一键上,而这个锁的持有者为session3
insert into test3 values(119,319,30620);
完成这一步的目的在于让session3也堵被session2堵塞,这个时候插入的唯一键只要落到最后一行记录到sup伪列之间则会被堵塞,这里插入的是唯一键30620,119

模拟中session3,没有使用insert values(),()的方式,是因为如果这样2行记录都会插入成功,因为线上是并发的,因此即便insert values(),()也可能出现问题这是其一。

其二,如果insert的值过多则持有锁的时间就更长,触发这个问题的机会就更大。因为insert values(),(),()....实际上还是每个行数据分别进行唯一性检查,插入操作,但是节省了语法解析和优化的部分。得到的死锁记录如下:

*** (1) TRANSACTION:
TRANSACTION 2752736, ACTIVE 111 sec inserting
sql>mysql tables in use 1, locked 1
LOCK WAIT 7 lock struct(s), heap size 1200, 5 row lock(s), undo log entries 2
MySQL thread id 26237, OS thread handle 140736551307008, query id 2964 localhost root update
insert into test106 values(119,219,30610),(6059,6059,6059)

*** (1) HOLDS THE LOCK(S):
RECORD LOCKS space id 1639 page no 15 n bits 800 index a of table `t10`.`test106` trx id 2752736 lock mode S
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;


*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1639 page no 10 n bits 952 index a of table `t10`.`test106` trx id 2752736 lock mode S waiting
Record lock, heap no 441 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 4; hex 800017ab; asc     ;;
 1: len 4; hex 800017ab; asc     ;;
 2: len 4; hex 800017b7; asc     ;;


*** (2) TRANSACTION:
TRANSACTION 2752739, ACTIVE 39 sec inserting
sql>mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1200, 3 row lock(s), undo log entries 2
MySQL thread id 26239, OS thread handle 140736283956992, query id 2970 localhost root update
insert into test106 values(119,319,30620)

*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 1639 page no 10 n bits 952 index a of table `t10`.`test106` trx id 2752739 lock_mode X locks rec but not gap
Record lock, heap no 441 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 4; hex 800017ab; asc     ;;
 1: len 4; hex 800017ab; asc     ;;
 2: len 4; hex 800017b7; asc     ;;


*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1639 page no 15 n bits 800 index a of table `t10`.`test106` trx id 2752739 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

死锁模型来看和线上一致。


http://www.niftyadmin.cn/n/346699.html

相关文章

人工智能专栏第九讲——目标检测

目标检测,就是指在图像或视频中自动地检测出感兴趣的目标区域,并识别出这个目标的类别。在人工智能的应用领域中,目标检测具有广泛的应用价值。例如,自动驾驶需要识别出道路标志和行驶的车辆、行人等障碍物;智能监控需要识别出异常行为和非法入侵等;医学影像处理需要识别…

第三十七章 弹灵守则第三十七条

“要不要一起玩?”那个跳来跳去的小男孩冲巴哥奔嘻嘻一笑。 “唔~” “很简单,这叫做玛丽的房间。”小男孩突然从她头顶跃过,脚尖点到她身后一块灰色方格。 “亮灰。” “D3D3D3。” “哈哈,你错了!”头顶扎着一根小辫…

【华为OD机试c++/java/python】称砝码【 2023 Q1 A卷 |100分】

题目描述 现有n种砝码,重量互不相等,分别为 m1,m2,m3…mn ; 每种砝码对应的数量为 x1,x2,x3...xn 。 现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。 注: 称重重量包括 0 数据范围:每组输入数据满足 1≤n≤10 , 1≤mi≤2000 , 1≤xi≤10 …

Flink有状态计算的状态容错

状态容错 State Fault Tolerance 首先来说一说状态容错。Flink 支持有状态的计算,可以把数据流的结果一直维持在内存(或 disk)中,比如累加一个点击数,如果某一时刻计算程序挂掉了,如何保证下次重启的时候&…

iTOP-RK3568开发板编译瑞芯微原厂源码

1 输入以下命令设置 java 版本为 1.8 版本,确认 java 版本是 1.8 版本之后,才可以进行下一步编译,如下图所示: source javaenv.sh java -version 2 输入命令配置 Android 分支 source build/envsetup.sh lunch rk3568_r-user…

计算机网络:计网体系结构

计网体系结构 1. 基本概念1.0 计算机网络的发展1.0.1 第一阶段1.0.2 第二阶段1.0.3 第三阶段 1.1 计算机网络的概念1.2 计算机网络的功能1.3 计算机网络的组成1.4 计算机网络的分类1.5 标准化工作及相关组织1.6 相关性能指标1.6.1 速率1.6.2 带宽1.6.3 吞吐量1.6.4 时延1.6.5 时…

栈与C++中的std::stack详解(多图超详细)

文章目录 栈(stack)什么是栈?栈的基本操作和应用入栈(push)出栈(pop)入栈和出栈的复杂度和应用场景 类模板std::satck形参T和Container成员函数元素访问栈的容量栈的修改 用法示例 栈(stack) 什么是栈? 栈是一种线性的数据结构&…

[CTF/网络安全] 攻防世界 php_rce 解题详析

[CTF/网络安全] 攻防世界 php_rce 解题详析 PHP RECThinkPHP V5漏洞Payload姿势总结 PHP REC PHP RCE 指的是通过远程代码执行漏洞(Remote Code Execution)来攻击 PHP 程序的一种方式。简单来说,由于PHP应用程序没有正确处理外部输入数据&am…