Mysql 死锁案例4-delete 相邻记录导致死锁

死锁复现 

CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `c` int(11) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `c` (`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
/*Data for the table `t` */
 
insert  into `t`(`id`,`c`,`d`) values (0,0,0),(5,5,5),(10,10,10),(15,15,15)
事务1事务2
T1

BEGIN;

DELETE FROM  t WHERE  id=4;

T2

BEGIN;

DELETE FROM  t WHERE  id=4;

T3INSERT INTO t VALUES(3, 3,3);(阻塞)
T4INSERT INTO t VALUES(3, 3,3);(死锁)

死锁分析
注意where条件的c是普通索引

  1. T1事务1加主键索引间隙锁(0,5)写锁成功,
  2. T2事务2加主键索引间隙锁(0,5)写锁成功
  3. T3事务1申请意向插入锁(0,5)与事务2间隙锁(0,5)冲突阻塞
  4. T3事务2申请意向插入锁(0,5)与事务1间隙锁(0,5)冲突阻塞,循环等待死锁

这里其实也是间隙锁和意向插入锁冲突死锁,delete与update加锁逻辑差不多。参考:

Mysql 死锁案例2-间隙锁与意向插入锁冲突

查看锁信息 SHOW ENGINE INNODB STATUS 

------------------------
LATEST DETECTED DEADLOCK
------------------------
2024-03-13 16:47:14 0x1ed8
*** (1) TRANSACTION:
TRANSACTION 488371, ACTIVE 63 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 6, OS thread handle 2368, query id 2676 localhost ::1 root update
INSERT INTO t VALUES(3, 3,3)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 638 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 488371 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 80000005; asc     ;;
 1: len 6; hex 000000076d2c; asc     m,;;
 2: len 7; hex 69000001ba0495; asc i      ;;
 3: len 4; hex 80000005; asc     ;;
 4: len 4; hex 80000000; asc     ;;

*** (2) TRANSACTION:
TRANSACTION 488372, ACTIVE 51 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 20, OS thread handle 7896, query id 2681 localhost ::1 root update
INSERT INTO t VALUES(3, 3,3)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 638 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 488372 lock_mode X locks gap before rec
Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 80000005; asc     ;;
 1: len 6; hex 000000076d2c; asc     m,;;
 2: len 7; hex 69000001ba0495; asc i      ;;
 3: len 4; hex 80000005; asc     ;;
 4: len 4; hex 80000000; asc     ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 638 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 488372 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 80000005; asc     ;;
 1: len 6; hex 000000076d2c; asc     m,;;
 2: len 7; hex 69000001ba0495; asc i      ;;
 3: len 4; hex 80000005; asc     ;;
 4: len 4; hex 80000000; asc     ;;

*** WE ROLL BACK TRANSACTION (2)
------------
TRANSACTIONS

where语句等值匹配的delete语句加锁逻辑分主键索引和唯一索引和普通索引,规则参考:

MySQL行锁加锁规则之等值查询

普通索引删除的加锁案例:

DELETE FROM  t WHERE  c=5;
---TRANSACTION 488378, ACTIVE 6 sec
4 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 6, OS thread handle 2368, query id 2744 localhost ::1 root
TABLE LOCK table `test`.`t` trx id 488378 lock mode IX
RECORD LOCKS space id 638 page no 4 n bits 80 index c of table `test`.`t` trx id 488378 lock_mode X
Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
 0: len 4; hex 80000005; asc     ;;
 1: len 4; hex 80000005; asc     ;;

RECORD LOCKS space id 638 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 488378 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 32
 0: len 4; hex 80000005; asc     ;;
 1: len 6; hex 0000000773ba; asc     s ;;
 2: len 7; hex 25000001392ce4; asc %   9, ;;
 3: len 4; hex 80000005; asc     ;;
 4: len 4; hex 80000000; asc     ;;

RECORD LOCKS space id 638 page no 4 n bits 80 index c of table `test`.`t` trx id 488378 lock_mode X locks gap before rec
Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 8000000a; asc     ;;
 1: len 4; hex 8000000a; asc     ;;

加了3把锁,索引c间隙锁(5,10),主键索引记录锁id=5,索引c临键锁(0,5]

有兴趣的可以看下这篇文章:MySQL delete 相邻记录导致死锁

 死锁日志

------------------------
LATEST DETECTED DEADLOCK
------------------------
2017-09-09 22:34:13 7f78eab82700
*** (1) TRANSACTION:
TRANSACTION 462308399, ACTIVE 33 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 3525577, OS thread handle 0x7f896cc4b700, query id 780039657 localhost root updating
delete from ty where a=5
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 219 page no 4 n bits 72 index `idxa` of table `test`.`ty` trx id 462308399 lock_mode X waiting
*** (2) TRANSACTION:
TRANSACTION 462308398, ACTIVE 61 sec inserting, thread declared inside InnoDB 5000
mysql tables in use 1, locked 1
5 lock struct(s), heap size 1184, 4 row lock(s), undo log entries 2
MySQL thread id 3525490, OS thread handle 0x7f78eab82700, query id 780039714 localhost root update
insert into ty(a,b) values(2,10)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 219 page no 4 n bits 72 index `idxa` of table `test`.`ty` trx id 462308398 lock_mode X
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 219 page no 4 n bits 72 index `idxa` of table `test`.`ty` trx id 462308398 lock_mode X locks gap before rec insert intention waiting
*** WE ROLL BACK TRANSACTION (1)

分析死锁日志 

首先要理解的是 对同一个字段申请加锁是需要排队.  其次表ty中索引idxa为非唯一普通索引,我们根据事务执行的时间顺序来解释,这样比较好理解(MySQL 5.6 事务隔离级别为RR)。

  •  a. 根据死锁日志显示 事务2 也即sess1执行的事务,根据 HOLDS THE LOCK(S)显示    sess1 先执行 delete from ty where a=5 ,该事务持有索引a=5 的行锁lock_mode X ,因为是RR隔离级别,所以sess1 还持有两个gap锁[1,2]-[2,5], [2,5]-[3,6] 。
  • b. 事务1的日志也即sess2执行的事务,申请对 a=5 加锁,一个rec lock 和两个gap锁,因为sess1中delete还没释放,故sess2的事务1等待sess1的事务2释放a=5的锁资源。
  • c. 然后根据WAITING FOR THIS LOCK TO BE GRANTED,提示事务2 insert语句正在等待 lock_mode X locks gap before rec insert intention waiting, 因为insert语句 [4,2] 介于gap锁[1,2]-[2,5]之间,所以有了提示 "lock_mode X locks gap",insert语句必须等待前面 sess2中delete 获取锁并且释放锁。于是,sess2(delete) 等待sess1(delete) ,sess1(insert)等待sess2(delete),循环等待,造成死锁。 问题 如果sess1 执行 insert into ty(a,b) values(5,10); sess2会遇到死锁吗?

因为作者没贴具体的表结构和表数据,所以没看懂这个死锁, 也没复现出来(Mysql 5.7.12 事务隔离级别为RR)。

按对锁的理解,事务1事务2执行的第一个delete语句都能成功,只有一种可能,就是数据库没a=5这条记录,间隙锁与间隙锁不冲突。按这个设定执行,那么事务2的第二个delete语句就不会阻塞,所以也就不存在死锁。怎么复现这个死锁????

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/463903.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言初学12:强制类型转换

一、强制数据类型转换举例 1.1 double赋值给int #include<stdio.h> int main() {double sum 18, count 5;int mean;mean sum / count;printf("Value of mean : %d\n", mean);} 执行结果&#xff1a; double赋值给int&#xff0c;小数部分会删除&#xff…

dp入门:从暴力dfs 到 dp

本篇为小金鱼大佬视频的学习笔记&#xff0c;原视频链接&#xff1a;https://www.bilibili.com/video/BV1r84y1379W?vd_source726e10ea5b787a300ceada715f64b4bf 基础概念 暴力dfs很多时候仅能过部分测试点&#xff0c;要想将其优化&#xff0c;一般以 dfs -> 记忆化搜索 …

汽车IVI中控开发入门及进阶(十三):语音识别

前言: IVI中控上的语音识别,在目前市场上也是非常显眼的一个创新,大幅改变了传统IVI的操作习惯。 语音识别Speech recognition,也称为自动语音识别(ASR)、计算机语音识别或语音到文本,是一种使程序能够将人类语音处理成书面格式的能力。 语音识别Speech recognition是计…

1.6w字数据库基础知识超详细解析~‍(进阶/复习版)

文章目录 前言一、数据库的操作1.登入数据库2.创建数据库3.显示当前数据库4.使用数据库5.删除数据库 二、常用数据类型三、数据库的约束1约束类型2NULL约束3UNIQUE:唯一约束4DEFAULT&#xff1a;默认值约束5 PRIMARY KEY&#xff1a;主键约束6 FOREIGN KEY&#xff1a;外键约束…

Calendar类 --java学习笔记

Calendar 代表的是系统此刻时间对应的日历通过它可以单独获取、修改时间中的年、月、日、时、分、秒等 常见方法&#xff1a; 创建Calendar对象&#xff1a; 用Calendar.getInStance&#xff08;&#xff09;方法&#xff0c;返回一个此时此刻的日历&#xff08;Calendar&am…

关于IP地址证书的申请

对于直接通过IP地址访问的服务器&#xff0c;为其配置SSL证书同样至关重要。以下是一份详尽的指南&#xff0c;教你如何为你的IP地址申请SSL证书。 IP地址证书目前有DV验证和OV验证两种主流的验证方式&#xff0c;DV验证只需验证IP的所有权&#xff0c;OV的在此基础上&#xff…

换根dp,LeetCode310. 最小高度树

一、题目 1、题目描述 树是一个无向图&#xff0c;其中任何两个顶点只通过一条路径连接。 换句话说&#xff0c;一个任何没有简单环路的连通图都是一棵树。 给你一棵包含 n 个节点的树&#xff0c;标记为 0 到 n - 1 。给定数字 n 和一个有 n - 1 条无向边的 edges 列表&#…

自媒体人的超级宝典

这个10块钱的小报童还有谁没买&#xff1f; 你可别等到它涨到19.9的时候来问我有没有优惠 昨天正式发售就已经2300人了&#xff0c;之前可是几个小时就涨了400多人&#xff0c;照这个速度下去&#xff0c;明天就要涨价了。 说实话&#xff0c;我看了里面的内容&#xff0c;觉…

Linux网络编程: 以太网帧Frame/ARP/RARP详解

一、TCP/IP五层模型 物理层&#xff08;Physical Layer&#xff09;&#xff1a;物理层是最底层&#xff0c;负责传输比特流&#xff08;bitstream&#xff09;以及物理介质的传输方式。它定义了如何在物理媒介上传输原始的比特流&#xff0c;例如通过电缆、光纤或无线传输等。…

SAP Activate项目管理方法论路线图

SAP Activate 是 SAP 推出的一种基于敏捷方法论的灵活、快速且引导式的实施方法论&#xff0c;专为加速SAP S/4HANA和其他SAP解决方案的部署而设计。这个方法论结合了最佳实践、引导配置和方法论本身的强大能力&#xff0c;以确保项目的快速实施和成功部署。SAP Activate的核心…

ffmpeg 滤镜实现不同采样率多音频混音

音频混音在音视频开发中是十分重要的一个环节,所谓音频混音就是将所有需要混音的数据相加得到混音数据,然后通过某个算法进行非法数据的处理;例如相加数值超过最大值,最小值等! 在实际的音频开发中,要实现混音的流程如下: 因此我们的编码实现就分为五部分:寻找…

22-分支和循环语句_while语句(下)(初阶)

该代码输出什么&#xff1f; int main() {char ch \0;while ((ch getchar()) ! EOF){if (ch < 0 || ch>9){continue;}putchar(ch);}return 0; } 结果&#xff1a;该代码只打印数字字符 附&#xff1a;ASCII码表

Python基础入门 --- 5.函数

文章目录 Python基础入门5.函数5.1 基本定义5.2 传入参数5.3 返回值5.3.1 None类型 5.4 说明文档5.5 嵌套调用 Python基础入门 5.函数 定义&#xff1a;可重复使用&#xff0c;用来实现特定功能的代码段。 # 不使用内置函数len&#xff0c;统计字符串的长度 str "Hell…

南卡罗来纳州历史和文化经济地理和自然政治和社会教育1. 加州大学公布2024年秋季入学新生和转学申请数据2. 2024考研国家线公布路德会信徒核心信仰礼拜和

目录 南卡罗来纳州 历史和文化 经济 地理和自然 政治和社会 教育 1. 加州大学公布2024年秋季入学新生和转学申请数据 2. 2024考研国家线公布 路德会信徒 核心信仰 礼拜和实践 分布 社会和文化影响 约翰塞巴斯蒂安巴赫 生平简介 音乐风格和作品 遗产和影响 …

AXI Lite协议详解

AXI Lite协议详解 axi&#xff08;Advanced eXtensible Interface&#xff09;是一种总线协议&#xff0c;该协议是ARM公司提出的amba&#xff08;Advanced Microcontroller Bus Architecture&#xff09;3.0协议中最重要的部分&#xff0c;是一种面向高性能、高带宽、低延迟的…

C++17之std::variant

1. std::variant操作 如下列出了为std:: variable <>提供的所有操作。

Docker 学习笔记一

一、什么是docker Docker 是一个基于轻量级虚拟化技术的容器&#xff0c;整个项目基于Go语言开发&#xff1b;Docker是一个C/S架构&#xff0c;后端众多模块各司其职&#xff0c;docker的daemon是运行在主机上通过client可以进行通信。 docker 由三部分组成&#xff1a;镜像(…

Rust 构建开源 Pingora 框架可以与nginx媲美

一、概述 Cloudflare 为何弃用 Nginx&#xff0c;选择使用 Rust 重新构建新的代理 Pingora 框架。Cloudflare 成立于2010年&#xff0c;是一家领先的云服务提供商&#xff0c;专注于内容分发网络&#xff08;CDN&#xff09;和分布式域名解析。它提供一系列安全和性能优化服务…

Figure 01掀起了具身智能的崭新篇章

在人工智能的发展历程中&#xff0c;OpenAI始终扮演着创新的先锋角色。最近&#xff0c;他们与Figure公司的合作成果尤为引人注目&#xff0c;这一合作将多模态大模型技术成功应用于Figure 01机器人的开发中&#xff0c;为人类与机器的互动开辟了全新的时代。该机器人不仅能够与…

innovus中path group 的策略和应用(上)

在所有的后端工具里边&#xff0c;有三个重要的引擎&#xff1a;auto-place&#xff0c;CTS&#xff0c;auto-route三个。这里边的auto-place是决断了整个设计时序的基点。由于&#xff0c;auto-place的动作是在设计的preCTS阶段&#xff0c;所以这里的设计时序就是广义上说的&…