MySQL添加索引时会锁表吗?

news2024/9/19 15:16:09

目录

  • 简介
  • Online DDL概念
  • Online DDL用法
  • 总结

简介

在MySQL5.5以及之前的版本,通常更改数据表结构操作(DDL)会阻塞对表数据的增删改操作(DML)。
MySQL5.6提供Online DDL之后可支持DDL与DML操作同时执行,降低了DDL期间对业务延迟带来的影响。

下面进行案例演示。我们准备了一个分数表,有600万的测试数据,接下来我们验证一下我们日常使用的ALTER语句(不提交),看看是否会全程锁表

#事务A 添加索引 不提交
begin;
ALTER TABLE scores ADD index idx_student_id (student_id);
# commit;
#事务B 查询数据与修改数据
begin;
select id from scores where id= 1;
commit;

begin;
update scores set course_name = '张三' where id = 1;
commit;

发现查询事务和修改事务都是可以正常返回的,发现这条DDL语句不会全程锁表,执行过程中真的不会锁表吗?我们再看一种情况,首先删除索引:

ALTER TABLE scores drop index idx_student_id;

然后开启添加索引事务(不提交),然后再开启查询事务,并且也不提交,这个时候通过show processlist命令查看mysql的执行信息,观察加索引时ddl语句的执行情况。

show processlist;

观察到ddl语句正在执行中:

在这里插入图片描述

再show一下,发现ddl语句变成了等待我们的元数据锁释放中,即查询语句持有了我们的一个元数据锁。这个时候我们提交查询事务,可以发现索引就添加成功了。说明我们这条sql本质上还是有个加锁的过程。

在这里插入图片描述

再看一种情况,也先删除索引,然后开启查询事务不提交,去持有元数据锁,然后再执行添加索引,然后show一下执行信息,发现DDL语句已经在等待元数据锁释放了。然后我们提交一下查询事务,再show一下,发现DDL语句正在往下执行,这个时候我们再开启一个事务进行修改(也不提交),多show几下直到DDL执行完毕,发现我们开启的修改事务阻塞了我们的DDL语句继续执行。提交修改事务,发现索引就添加成功了。那么也就是说我们这个DDL语句实际上有两个加锁的过程,并且在这个加锁的时候如果说我们的元数据锁被其他的事务给占有了,那么我们这个DDL语句就会被阻塞,第二次也是一样的。

MySQL 5.6或更高版本上进行表结构修改操作(如添加索引),MySQL默认情况下会尝试使用Online DDL来最小化操作对读写操作的影响,MySQL会选择默认的最佳方式进行操作。



Online DDL概念

概念:在不中断现有数据读写操作的情况下,自动执行 DDL语句(例如创建、修改、删除表等)的机制。Online DDL 可以在MySQL进行表空间或数据文件的变化时,自动执行 DDL语句,从而避免了传统方式中,执行 DDL 语句时对数据库读写操作的干扰和中断。

执行过程:Online ddl 执行大致可分为三个阶段:初始化阶段、执行阶段和提交表定义阶段:

  • 初始化阶段:
    • 评估存储引擎能力与DDL语句
    • 评估ALGORITHM 和 LOCK
    • 创建可升级的MDL读锁(元数据读锁)
  • 执行阶段:
    • 此阶段分为两个步骤准备和执行DDL语句
    • 此阶段是否需要MDL写锁取决于初始化阶段评估的因素。如果需要MDL写锁的话,仅在准备过程会短暂的使用MDL写锁,然后降级为MDL读锁
    • DDL执行过程(最耗时)
  • 提交表定义阶段:
    • 此阶段会将MDL读锁升级到MDL写锁,此阶段一般较快,因此独占锁的时间也较短
    • 用新的表定义替换旧的表定义,释放MDL锁

Online DDL用法

区别与我们日常使用的DLL语句,多了两个参数

ALTER TABLE scores ADD index idx_student_id (student_id) , ALGORITHM=INPLACE, LOCK=NONE;

ALTER TABLE scores ADD index idx_student_id (student_id) , ALGORITHM=COPY, LOCK=EXCLUSIVE;

ALGORITHM有三个可选项

ALGORITHM=DEFAULT:默认算法,使用最高效的算法


ALGORITHM=INPLACE:解决全程锁表的一个方式,在原表上进行更改,不需要生成临时表,不需要进行数据copy的过程。
添加索引步骤:
1.创建索引(二级索引)数据字典
2.加共享表锁,禁止DML,允许查询
3.读取聚簇索引,构造新的索引项,排序并插入新索引
4.等待打开当前表的所有只读事务提交
5.创建索引结束


ALGORITHM=COPY:最原始的方式,通过临时表创建索引,需要多一倍存储,还有更多的I0(类似5.6版本之前的处理过程)添加索引步骤:
1.新建带索引(主键索引)的临时表心
2.锁原表,禁止DML,允许查询
3.将原表数据拷贝到临时表
4.禁止读写,进行rename,升级字典锁
5.完成创建索引操作

LOCK有四种

LOCK=DEFAULT:默认方式,MySQL自行判断使用哪种LOCK模式,尽量不锁表
LOCK=NONE:无锁:允许Online DDL期间进行并发读写操作。通常与INPLACE搭配使用。如果Online DDL操作不支持对表的继续写入,则DDL操作失败,对表修改无效
LOCK=SHARED:共享锁:Online DDL操作期间堵塞写入,不影响读取
LOCK=EXCLUSIVE:排它锁:Online DDL操作期间不允许对锁表进行任何操作

接下来我们使用这两种执行方式来看一下是不是会全程锁表。先是第一种的INPLACE:

ALTER TABLE scores ADD index idx_student_id (student_id) , ALGORITHM=INPLACE, LOCK=NONE;

先删除刚刚的索引,然后开启一个事务添加索引(不提交),执行一下查询事务(提交),是可以正常查询的。再开启一个修改事务(提交),是可以正常修改的。即,INPLACE方式是不会全程锁表的。那么它在执行的过程中会加锁吗?

还是删除索引,然后开启一个事务添加索引(不提交),执行一下查询事务(不提交),此时show一下执行信息,发现DDL语句正在执行ALTER语句,再show一下,发现DDL语句已经被阻塞了,因为它在等待元数据锁释放,也就是说,DDL语句实际上还是会有个加锁的过程。提交一下查询事务,发现索引就添加成功了。

然后我们再次验证一种场景,还是删除索引,然后先开启一个查询事务(不提交)先持有元数据锁,然后再开启事务添加索引(不提交),这个时候show一下执行信息,发现DDL语句正在等待元数据锁释放,提交一下查询事务,show一下发现ddl语句正在往下执行,这个时候再开启一个修改事务(不提交),多show几下直到DDL执行完毕,发现我们的DDL语句也被这个修改事务阻塞了,因为它正在等待元数据锁的释放,这个时候我们再开一个修改事务(提交)、查询事务(提交),show一下发现他们都被阻塞住。也就是说online ddl语句被阻塞后它就会进一步的将后续过来的DML事务全部阻塞住,将修改事务提交,索引就添加成功了。

所以日常使用的DDL语句的INPLACE方式执行过程有两次加锁,加锁过程中如果有其他事务持有了元数据锁,DDL语句就会被阻塞,后续来的DML操作都会被阻塞住。

再看一下COPY方式:

ALTER TABLE scores ADD index idx_student_id (student_id) , ALGORITHM=COPY, LOCK=EXCLUSIVE;

还是删除索引,然后开启一个事务添加索引(不提交),然后执行查询事务(提交),修改事务(提交),执行信息发现两个DML语句都被阻塞。即COPY方式是全程锁表的,它不允许DDL和DML的并发。

总结

从宏观上看,Online DDL的事务相当于会和其他事务并行执行,只不过Online DDL会在表空闲时进行执行,所以Online DDL不会阻塞其他操作,在Online DDL执行过程会两次获取MDL锁(1.申请MDL写锁 2. 降级成MDL读锁 3.执行DDL --耗时 4. 升级MDL写锁 5. 释放MDL锁),并且需要等待已经持有MDL锁的并发事务提交或回滚后才能继续执行,在实际执行时需注意以下几点:

  • 进行DDL操作时尽量在业务低峰期进行操作。尽量的降低我们online ddll的阻塞时间,进而减少整个表的死锁
  • 在操作之前最好确认对要操作的表没有任何进行中的操作、没有未提交事务、也没有显式事务中的报错语句。
  • 设置超时时间lock_wait_timeout,避免长时间的metedata锁等待。
set global lock_wait_timeout = 60;
# 单位是s 默认好像是一年

show variables like '%timeout%';

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

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

相关文章

CentOS 7 yum官方源失效

问题 2024年7月,官方对centos 7停止了维护,yum的源网址mirror.centos.org也已经无法访问。 在此情况下,无法正常使用yum进行安装和更新工具。 在尝试了更换阿里源之后,仍然有部分工具库无法访问。 通用解决方案 1. 打开/etc/y…

react页面指定dom转pdf导出

1. 使用jsPDFhtml2canvas将页面转成图片然后导出2. 自定义创建iframe调用iframe.print()进行页面打印转pdf导出3. 使用react-to-print插件打印pdf4. 利用media print样式打印页面局部元素 1. 使用jsPDFhtml2canvas将页面转成图片然后导出 缺点:页面过长可能会导出失…

SwarmBrain: 通过大模型玩实时战略游戏《星际争霸II》

人工智能咨询培训老师叶梓 转载标明出处 实时战略(RTS)游戏如《星际争霸II》一直被视为测试和提升AI能力的绝佳平台。尽管基于强化学习(RL)的AI代理在《星际争霸II》中取得了显著进展,但它们在处理复杂环境时仍面临挑战…

SpringBoot、SpringCloud、SpringCloud Alibaba版本对应关系

1. 概述 随着SpringBoot和SpringCloud的发展,有些服务进入停更运维状态,一些新的框架出现,在开发微服务的时候不同组件的版本对应关系也是不可忽视的问题,如果版本不对应,可能会出现很多莫名的错误,给开发…

5G mmWave PAAM 开发平台

Avnet-Fujikura-AMD 5G 毫米波相控阵天线模块开发平台 Avnet 和 Fujikura 为毫米波频段创建了一个领先的 5G FR2 相控阵天线开发平台。该平台使开发人员能够使用 AMD Xilinx 的 Zynq UltraScale™ RFSoC Gen3 和 Fujikura 的 FutureAcess™ 相控阵天线模块 (PAAM) 快速创建和制…

AI周报(7.14-7.20)

AI应用-本届欧洲杯的AI技术应用 卢卡库在两场比赛中共有三次庆祝进球的情况,但遗憾的是这三次庆祝均未能转化为有效的进球。这种“吐饼王”的表现也让他成为了本届欧洲杯的一个另类焦点人物。虽然稍显悲情,但有了AI的深度应用,即使这样极端的…

震惊,搜索二叉树告诉我们不要生二胎?本篇(带图)让你轻松拿下

引子: 二叉树作为一种常见的一种数据结构,我们也经常使用,有以下几种类型:满二叉树(Full Binary Tree):所有节点都恰好有两个子节点或没有子节点。完全二叉树(Complete Binary Tree&#xff09…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第三十六章 Linux驱动初探

i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

Python list comprehension (列表推导式 - 列表解析式 - 列表生成式)

Python list comprehension {列表推导式 - 列表解析式 - 列表生成式} 1. Python list comprehension (列表推导式 - 列表解析式 - 列表生成式)2. Example3. ExampleReferences Python 中的列表解析式并不是用来解决全新的问题,只是为解决已有问题提供新的语法。 列…

易我数据恢复怎么样?这款四款也很好用

虽然我已经很小心了,但是生活中总有一些意外情况导致数据丢失,这时,数据恢复软件便成为了我们的救命稻草。不知道大家用过易我数据恢复没。我用过,但是目前更喜欢下面的四款数据恢复工具,更符合我的使用习惯&#xff0…

【ai】学习笔记:电影推荐1:协同过滤 TF-DF 余弦相似性

2020年之前都是用协同过滤2020年以后用深度学习、人工智能视频收费的,不完整,里面是电影推荐 这里有个视频讲解2016年大神分析了电影推荐 :MovieRecommendation github地址 看起来是基于用户的相似性和物品的相似性,向用户推荐物品: 大神的介绍: 大神的介绍: 基于Pytho…

Windows tasklist命令详解,Windows查看进程

「作者简介」:冬奥会网络安全中国代表队,CSDN Top100,就职奇安信多年,以实战工作为基础著作 《网络安全自学教程》,适合基础薄弱的同学系统化的学习网络安全,用最短的时间掌握最核心的技术。 tasklist 可以…

Chapter14 非真实感渲染 NPR——Shader入门精要

Chapter14 非真实感渲染 NPR 一、卡通风格渲染1.渲染轮廓线2.添加高光3.ToonShadingMat 二、素描风格渲染 一、卡通风格渲染 特点:物体被黑色线条描边,分明的明暗变化等方法:其中之一就是 基于色调的着色技术 1.渲染轮廓线 方法 基于观察角…

零基础入门鸿蒙开发 HarmonyOS NEXT星河版开发学习

今天开始带大家零基础入门鸿蒙开发,也就是你没有任何编程基础的情况下就可以跟着石头哥零基础学习鸿蒙开发。 目录 一,为什么要学习鸿蒙 1-1,鸿蒙介绍 1-2,为什么要学习鸿蒙 1-3,鸿蒙各个版本介绍 1-4&#xff0…

MYSQL2

1.建库以及建表: mysql> create database mydb8_woker; mysql> use mydb8_woker; mysql> create table t_worker( -> department_id int(11) not null comment 部门号, -> worker_id int(11) primary key not null comment 职工号, -&…

Java中的Heap(堆)(如果想知道Java中有关堆的知识点,那么只看这一篇就足够了!)

前言:(Heap)是一种特殊的完全二叉树,它在诸多算法中有着广泛的应用,本文将详细介绍Java中的堆。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 先让我们看一下本文大…

《Milvus Cloud向量数据库指南》——开源许可证的开放度:塑造AI开发合作与创新的双刃剑

在人工智能(AI)技术日新月异的今天,开源软件作为推动技术创新的重要力量,其许可证的开放度成为了影响AI开发合作、创新模式乃至整个行业生态的关键因素。不同的开源许可证模型,以其各自独特的开放程度,不仅决定了软件项目的可访问性和可定制性,还深刻影响着AI领域内的合…

springboot 实体类加注解校验入参数据

导入的是springboot自身的依赖包 import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.validation.Valid;

R语言进行K折交叉验证问题

在使用R语言进行模型参数评估优化时候,会使用K折交叉验证,其中会遇到各种各样问题: 错误: C5.0 models require a factor outcome > (1-mean(E0));(1-mean(E1)) [1] 1 [1] 1 报错说明C5.0模型需要因子变量输出,源代码如下&am…

还在为电脑录屏困扰吗?试试这4个方法,瞬间解决

现在很多人用手机进行日常操作都知道录屏的功能怎么操作,但是电脑录屏怎么录呢?如果你需要使用电脑进行录屏操作的时候就可以看看这篇文章。 1.福晰录屏大师 这个工具是一个专业的录屏软件。可以控制录制的区域范围,也能控制音频来源&#…