mysql创建索引导致死锁,数据库崩溃,完美解决方案

news2024/11/29 10:40:00

文章目录

  • 写在前面
  • 一、短事务场景下,执行DDL语句场景分析
    • 1、短事务场景下,执行表字段添加操作
    • 2、短事务场景下,执行表字段修改操作
    • 3、短事务场景下,执行表字段删除操作
      • (1)往里添加一条数据试试
    • 4、短事务场景下,添加索引操作
    • 5、总结
  • 二、完美解决方案
  • 三、原因分析
  • 写在后面

写在前面

DDL语句,就是对数据库对象(数据库、表、列、索引等)进行创建、删除、修改等。

之前分享过一篇mysql创建索引导致死锁,数据库崩溃,mysql的表级锁之【元数据锁(meta data lock,MDL)】全解

通过上一篇文章我们了解到,MySQL有一种表锁叫做元数据锁(meta data lock,MDL)元数据锁,执行DDL时会检查元数据锁并尝试获取。

之前一直以为,只要保证MySQL数据库当前没有长事务,就可以安枕无忧地执行DDL语句,我们天真的认为短事务场景中,DDL语句总是会在上一个事务结束后,获取到元数据锁,并不会有死锁的危险。

但是最近发现!事情并没有想象中的那么简单!就算是没有长事务,MySQL8.0在创建索引的时候,仍然有可能会导致死锁的发生!
我们一起来分析一下。

注!本文操作都是基于mysql 8.0.21InnoDB引擎,可重复读事务隔离级别下来完成的。

一、短事务场景下,执行DDL语句场景分析

先创建一个表:

CREATE TABLE `lock_test` (
  `id` int NOT NULL,
  `name` varchar(20) DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

1、短事务场景下,执行表字段添加操作

在这里插入图片描述
我们发现,当事务A尚未提交时,事务B、事务C都会处于等待状态。

当事务A一经发起commit命令,事务B紧跟着会进行执行,并执行成功,事务C在事务B之后也会执行成功。

整个过程只有正常的事务等待,并不会发生死锁。

2、短事务场景下,执行表字段修改操作

在这里插入图片描述
我们发现,修改字段的场景下和添加字段场景下的结果是一样的。

3、短事务场景下,执行表字段删除操作

在这里插入图片描述
当该表无数据时,我们会发现,当事务A执行提交之后,事务B和事务C进入死锁,此时该表的任何SQL语句都无法执行!

此时导致数据库表死锁,数据库SQL堆积越来越多,导致数据库崩溃!

(1)往里添加一条数据试试

INSERT INTO `ourea`.`lock_test`(`id`, `name`, `age`, `column_name`) VALUES (1, '1', 1, '1');

在这里插入图片描述
有数据的情况和没有数据的情况,是不一样的!

有数据时,当事务A提交之后,事务C会执行成功,当事务C提交之后,事务B才是最终执行成功。

4、短事务场景下,添加索引操作

还是保持数据库中有数据。

INSERT INTO `ourea`.`lock_test`(`id`, `name`, `age`, `column_name`) VALUES (1, '1', 1, '1');

在这里插入图片描述
我们发现,当事务A执行提交之后,事务B和事务C进入死锁,此时该表的任何SQL语句都无法执行!

此时导致数据库表死锁,数据库SQL堆积越来越多,导致数据库崩溃!

5、总结

用事实说话。

通过实例,我们可以看出,即使没有长事务,执行DDL语句仍会导致表死锁。
尤其是对索引的操作,非常危险!

二、完美解决方案

在执行DDL语句之前,通过以下SQL,首先要确保没有长事务:

SELECT * FROM information_schema.INNODB_TRX;

然后,再执行DDL语句之前,先将整表锁住,然后执行DDL语句:
在这里插入图片描述
使用如下操作,完美解决死锁问题!

-- 锁整表,加上写锁
lock table lock_test write;
-- 添加索引
CREATE INDEX index_tb ON lock_test(column_name);
-- 解锁
unlock table;

三、原因分析

当对非主键字段更改索引时,其实并不是一个原子操作,会先更新非主键字段索引,然后再更新主键索引。

当我们把主键删掉之后:

在这里插入图片描述
这种情况,和当表中有数据,执行表字段删除操作的场景一模一样。

原因是MySQL5.6引入的OnLine-DDL,一个DDL语句其实包含着两个等待操作:

  • prepare阶段:尝试获取MDL排他锁,禁止其他线程读写;
  • ddl执行阶段:降级成MDL共享锁,允许其他线程读取;
  • commit阶段:升级成MDL排他锁,禁止其他线程读写;
  • finish阶段:释放MDL锁;
    1、3、4如果没有锁冲突,执行时间非常短。第2步占用了DDL绝大部分时间,这期间这个表可以正常读写数据,是因此称为“online ”。
    如果第3步升级为MDL写锁的时候,这个表的MDL锁有其他事务占着,那么这个事务会阻塞,等到可以拿到MDL写锁,而且如果不幸一直拿不到,最后锁超时了,就只好回滚这个DDL操作。
    所以,DDL语句只有才开始和结束的时候,才会禁止读和写,在语句执行的时候是可以进行读的。

写在后面

如果本文对你有帮助,请点赞收藏关注一下吧 ~
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

操作系统内核与安全分析课程笔记【2】进程管理与调度

文章目录基本概念与关键数据结构进程管理进程生命周期进程的关系进程家族树线程组进程组与会话进程的创建与终止Linux中的线程基本概念与关键数据结构 进程:静态的,存储在磁盘上的代码与数据。 程序:动态的,执行程序的动态过程&am…

线程调度的基本过程

进程的基本调度过程 文章目录进程的基本调度过程一.什么是进程我们先用官方的话语去解释一下,大家先看我们对这个定义的一个结果如下:二.进程的特征三.进程的三种基本状态四.进程的管理4.1 什么是PCB4.2 PCB中的信息4.2.1 pid4.2.2 内存指针4.2.3文件描述符4.2.4 进程调度信息一…

【Android】aliyun云构建自动化打包

先贴出 阿里云移动研发平台EMAS-云构建的文档地址 一切以文档为主 简介 云构建服务支持通过流水线进行多端应用的编译构建任务,支持包签名、平台托管证书等能力,提升研发效率,规范研发流程。 提升研发效能,缩短交付周期 提升研发…

【专项训练】布隆过滤器和LRU缓存

布隆过滤器:与哈希表类似 哈希表是一个没有误差的数据结构! 有哈希函数得到index,会把要存的整个元素放在哈希表里面 有多少元素,每个元素有多大,所有的这些元素需要占的内存空间,在哈希表中都要找相应的内存大小给存起来 事实上,我们并不需要存所有的元素本身,而是只…

C++模拟实现红黑树

目录 介绍----什么是红黑树 甲鱼的臀部----规定 分析思考 绘图解析代码实现 节点部分 插入部分分步解析 ●父亲在祖父的左,叔叔在祖父的右: ●父亲在祖父的右,叔叔在祖父的左: 测试部分 整体代码 介绍----什么是红黑树 红…

5.2 对射式红外传感器旋转编码器计次

对射式红外传感器1.1 接线图VCC GND分别接电源的正负极DO数字输出端,随意选择一个GPIO口1.2 硬件原理当挡光片或者编码盘在对射式红外传感器中间经过时,DO就会输出电平变化信号,电平跳变信号触发STM32 PB14号口中断,在中断函数中执…

01: 新手学SpringCloud前需知道的5点

目录 第一点: 什么是微服务架构 第二点:为什么需要学习Spring Cloud 第三点: Spring Cloud 是什么 第四点: SpringCloud的优缺点 1、SpringCloud优点 2、SpringCloud缺点 第五点: SpringCloud由什么组成 1&…

数据结构——链表OJ题目讲解(2)

作者:几冬雪来 时间:2023年3月10日 内容:数据结构链表OJ题目讲解 来源:牛客网和力扣 目录 前言: 刷题: 1.反转链表: 1.改变指向的解法: 2.取头结点插入到新链表: …

参考 | 辨别真假笔记本三星内存条 (ddr4)

参考 | 辨别真假笔记本三星内存条 (ddr4) 文章目录参考 | 辨别真假笔记本三星内存条 (ddr4)1. 三星内存条标签纸上编码的含义2. 三星内存颗粒上编码的含义3. 辨别内容参考1. 三星内存条标签纸上编码的含义 内存条贴张上面有两串值得注意的编码, 其中编码的具体意义参考三星官方…

docker-compress 配置

文章目录docker-compress下载安装常用命令Docker Compose配置常用字段docker compose案例yml 配置指令参考versionbuildcap_add,cap_dropcgroup_parentcommandcontainer_namedepends_ondeploydevicesdnsdns_searchentrypointenv_fileenvironmentexposeextra_hostshe…

【3.10】操作系统进程管理、KMP算法

多线程冲突了怎么办? 由于多线程执行操作共享变量可能会导致竞争状态,因此我们将此段代码称为临界区(*critical section*),它是访问共享资源的代码片段,一定不能给多线程同时执行。 我们希望这段代码是互斥…

cadence skill 记录FPM不能保存问题

;FPM skill by Richard L. version0.08 fpmontrealgmail.com;Tree:杂项(Chinese)/简单范例;Desc:范例如何建立一个简单的二极管封装;Vendor:Richard L.;Count:1;CVG64:示意图字段(测试中);Datasheet:pL12.7 ;引脚间距pA7.6 pB3.5 pH3.5 ;长宽高pPad2.0 pHole1.2 ;焊盘直径和孔径…

论文阅读《Block-NeRF: Scalable Large Scene Neural View Synthesis》

论文地址:https://arxiv.org/pdf/2202.05263.pdf 复现源码:https://github.com/dvlab-research/BlockNeRFPytorch 概述 Block-NeRF是一种能够表示大规模环境的神经辐射场(Neural Radiance Fields)的变体,将 NeRF 扩展到…

渗透测试——信息收集(详细)

信息收集:前言:信息收集是渗透测试除了授权之外的第一步,也是关键的一步,尽量多的收集目标的信息会给后续的渗透事半功倍。收集信息的思路有很多,例如:页面信息收集、域名信息收集、敏感信息收集、子域名收…

Redis学习【12】之Redis 缓存

文章目录前言一 Jedis 简介二 使用 Jedis2.1 测试代码2.2 使用 JedisPool2.3 使用 JedisPooled2.4 连接 Sentinel 高可用集群2.5 连接分布式系统2.6 操作事务三 Spring Boot整合Redis3.1 创建工程3.2 定义 pom 文件3.3 完整代码3.4 总结四 高并发问题4.1 缓存穿透4.2 缓存击穿4…

全方位解读智能中控屏发展趋势!亚马逊Alexa语音+Matter能力成必备

随着智能家居行业逐步从碎片化的智能单品阶段,迈向体验更完整的全屋互联阶段,智能中控屏作为智能家居最佳的入口之一,在年轻人青睐全屋智能装修的风潮下,市场潜力彻底被引爆。 一、为什么是智能中控屏? 在智能音箱增…

诗一样的代码命名规范

有文化:落霞与孤鹜齐飞,秋水共长天一色;没文化:太阳落山的时候,看见一只鸟在水上飞;日常编码中,代码的命名是个大的学问。能快速的看懂开源软件的代码结构和意图,也是一项必备的能力…

Docker入门建议收藏 第二部分

二、Docker 容器技术与虚拟机的区别 Docker 到底是个什么东西呢?我们在理解 Docker 之前,首先得先区分清楚两个概念,容器和虚拟机。 虚拟机 虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在…

单链表的头插,尾插,头删,尾删等操作

前言顺序表要求是具有连续的物理空间,并且数据的话是在这些空间当中是连续的存储。但这样会带来很多问题,比如说在头部或者说中间插入的话,效率不是很高;并且申请空间可能需要扩容,并且越往后一般来说都是异地扩容&…

优思学院|精益生产中的“单件流”真的能够做到吗?

精益生产中提到的“一个流”(One Piece Flow)是一种生产方式,它的核心理念是通过合理配置作业场地、人员和设备,使产品从投入到成品产出的整个制造加工过程中始终处于不停滞、不堆积、不超越,按节拍一个一个地流动。 …