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 00: 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 00: 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 00: 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 320: 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 320: 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 00: 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语句就不会阻塞,所以也就不存在死锁。怎么复现这个死锁????

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python深度学习之路:TensorFlow与PyTorch对比【第140篇—Python实现】

👽发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Python深度学习之路:TensorFlow与PyTorch对比 在深度学习领域,Tens…

【数学建模】线性规划

针对未来可能的数学建模比赛内容,我对学习的内容做了一些调整,所以先跳过灰色关联分析和模糊综合评价的代码,今天先来了解一下运筹规划类——线性规划模型。 背景: 某数学建模游戏有三种题型,分别是A,B&am…

Cookie 信息泄露 Cookie未设置http only属性 原理以及修复方法

漏洞名称:Cookie信息泄露、Cookie安全性漏洞、Cookie未设置httponly属性 漏洞描述: cookie的属性设置不当可能会造成系统用户安全隐患,Cookie信息泄露是Cookiehttp only配置缺陷引起的,在设置Cookie时,可以设置的一个…

Java基于微信小程序的校园生活互助小助手

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

常用芯片学习——BME280芯片

BME280 温湿度气压传感器 芯片介绍 BME280是基于成熟传感原理的组合数字湿度、压力和温度传感器。该传感器块采用极为紧凑的金属盖LGA封装,占地面积仅为2.5x2.5mm2,高度为0.93mm。该传感器提供I2C以及SPI接口。它的小尺寸和低功耗允许在电池驱动的设备…

OpenCV-Java 开发简介

返回目录:OpenCV系列文章目录(持续更新中......) 上一篇:如何在“Microsoft Visual Studio”中使用OpenCV编译应用程序 下一篇:如何将OpenCV Java 与Eclipse结合使用 警告: 本教程可能包含过时的信息。 …

Prompt Engineering(提示工程)

Prompt 工程简介 在近年来,大模型(Large Model)如GPT、BERT等在自然语言处理领域取得了巨大的成功。这些模型通过海量数据的训练,具备了强大的语言理解和生成能力。然而,要想充分发挥这些大模型的潜力,仅仅…

口腔管理平台 |基于springboot框架+ Mysql+Java+B/S结构的口腔管理平台 设计与实现(可运行源码+数据库+lw文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 前台功能效果图 管理员功能登录前台功能效果图 会员功能 系统功能设计 数据库E-R图设计 lunwen参考…

【Flink SQL】Flink SQL 基础概念(四):SQL 的时间属性

《Flink SQL 基础概念》系列,共包含以下 5 篇文章: Flink SQL 基础概念(一):SQL & Table 运行环境、基本概念及常用 APIFlink SQL 基础概念(二):数据类型Flink SQL 基础概念&am…

操作系统(AndroidIOS)图像绘图的基本原理

屏幕显示图像的过程 我们知道,屏幕是由一个个物理显示单元组成,每一个单元我们可以称之为一个物理像素点,而每一个像素点可以发出多种颜色。 而图像,就是在不同的物理像素点上显示不同的颜色构成的。 像素点的颜色 像素的颜色是…

【PyTorch】成功解决TypeError: iteration over a 0-d tensor

【PyTorch】成功解决TypeError: iteration over a 0-d tensor 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程👈 希望得到您…

ssh 下连接Mysql 查看数据库数据表的内容的方法及步骤

要通过SSH连接到MySQL数据库,可以按照以下步骤进行操作: 在本地计算机上打开终端或命令提示符。 使用SSH命令连接到远程服务器。命令的格式如下: ssh usernameserver_ip其中,username是指在远程服务器上的用户名,serv…

Linux 块设备驱动

Linux 三大驱动分别是:字符设备驱动、块设备驱动、网络设备驱动。 块设备是针对存储设备的,比如 SD 卡、EMMC、NAND Flash、Nor Flash、SPI Flash、机械硬盘、固态硬盘等。因此块设备驱动其实就是这些存储设备驱动,块设备驱动相比字符设备驱…

jetson nano——编译一些包的网址导航,pyside2,qt(持续更新)

目录 1.PySide2下载地址2.tesserocr下载地址3.Qt下载地址4.OpenSSL官网5.latex编译器下载地址5.1MikTex5.2TeX Live 1.PySide2下载地址 https://download.qt.io/official_releases/QtForPython/pyside2/ 如下图: 2.tesserocr下载地址 https://github.com/simonflue…

ToolPlatform烧录HI3403实战

既然是嵌入式,烧录是逃不掉的。 连接串口!必须 主机有串口,或者用USB转接。 软件 01.software\pc\ToolPlatform 启动 其实只有这一个选项 BurnTool面板: 选择配置 选择烧写eMMC,再点击游览,选择xml…

NetSuite多脚本性能研究

在项目中,随着复杂度的提升,客制脚本以及各类SuiteAPP的应用,导致某个对象上挂载的脚本大量增加,最终导致了性能问题。表现在保存单据时时间过长,严重影响人机界面的用户感受。基于此问题,我们开展了NetSui…

大语言模型RAG-langchain models (二)

大语言模型RAG-langchain models (二) 往期文章:大语言模型RAG-技术概览 (一) 文章目录 大语言模型RAG-langchain models (二)**往期文章:[大语言模型RAG-技术概览 (一)](https://blog.csdn.net/tangbiubiu/article/details/136651625)**核心模块总览Mod…

《硬件历险》之Mac抢救出现问题的时间机器硬盘中的数据

本文虽然使用“抢救”一词,但是运气比较好,远没有达到访问和修改底层的信息来抢救的地步。如果你是需要通过访问和修改底层信息来抢救数据,建议阅读刘伟的《数据恢复技术深度揭秘(第二版)》或者寻找专业人士的帮助。 《…

关于 NXP PCA85073A 实时时钟读取数据时出现 IIC 传输失败的原因解析和解决方法

一、前言 对使用 I2C 传输的 RTC 外设 PCA85073,在 I2C 传输过程中若有复位信号输入,则有概率出现 I2C 死锁的状态,即 SCL为高,SDA一直为低的现象。 二、I2C 基本协议 在分析问题出现的原因之前,我…

es索引操作命令

索引操作 index 创建索引 put 方法创建索引 使用 put 创建索引时必须指明文档id,否则报错 # PUT 创建命令 # test1 索引名称 # type1 类型名称,默认为_doc,已经被废弃 # 1 文档id PUT /test1/type1/1 {"name":"zhangsan&…