MySQL添加索引时会锁表吗?
目录
- 简介
- 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%';
相关文章:

MySQL添加索引时会锁表吗?
目录 简介Online DDL概念Online DDL用法总结 简介 在MySQL5.5以及之前的版本,通常更改数据表结构操作(DDL)会阻塞对表数据的增删改操作(DML)。 MySQL5.6提供Online DDL之后可支持DDL与DML操作同时执行,降低…...

算法日记day 16(二叉树的广度优先遍历|反转、对称二叉树)
一、二叉树的层序遍历 题目: 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:[[3]…...

PolarisMesh源码系列--Polaris-Go注册发现流程
导语 北极星是腾讯开源的一款服务治理平台,用来解决分布式和微服务架构中的服务管理、流量管理、配置管理、故障容错和可观测性问题。在分布式和微服务架构的治理领域,目前国内比较流行的还包括 Spring Cloud,Apache Dubbo 等。在 Kubernete…...

vue3 vxe-grid修改currentPage,查询数据的时候,从第一页开始查询
1、当我们设置好VxeGrid.Options进行数据查询的时候,下面是可能的设置: const gridOptions reactive<BasicTableProps>({id: UserTable,showHeaderOverflow: false,showOverflow: true,keepSource: true,columns: userColumns,size: small,pagerConfig: {cur…...

电商数据集成之电商商品信息采集系统架构设计||电商API接口
一、引言 本架构设计文档旨在阐述基于 Selenium 的电商商品信息采集系统的整体架构,包括系统视图、逻辑视图、物理视图、开发视图和进程视图,并提供一个简单的采集电商商品信息的 demo。该系统通过模拟浏览器行为,实现对电商商品信息的自…...
Spring Cloud Stream 实现统一消息通信平台
1. 概述 Spring Cloud Stream:是Spring提供的消息通信框架,旨在构建跨不同消息中间件的统一通信平台。目的:通过消息通信机制降低分布式系统中服务间的耦合度,实现异步服务交互。 2. 消息通信与RPC RPC:远程过程调用…...

uniapp安卓plus原生选择系统文件
uniapp安卓plus原生选择系统文件 效果: 组件代码: <template xlang"wxml" minapp"mpvue"><view></view> </template> <script>export default {name: file-manager,props: {},data() {return {is…...

Go语言 Import导入
本文主要介绍Go语言import导入使用时注意事项和功能实现示例。 目录 Import 创建功能文件夹 加法 减法 主函数 优化导入的包名 .引入方法 总结 Import 创建功能文件夹 做一个计算器来演示,首先创建test文件夹。 加法 在test文件夹中创建add文件夹ÿ…...

一款异次元小清新风格的响应式wordpress个人博客主题
一款异次元小清新风格的响应式个人博客主题。这是一款专注于用户阅读体验的响应式 WordPress 主题,整体布局简洁大方,针对资源加载进行了优化。 Kratos主题基于Bootstrap和Font Awesome的WordPress一个干净,简单且响应迅速的博客主题&#x…...

【cocos creator】ts中export的模块管理
在 TypeScript(TS)中,export 和 import 的概念与 Java 中的 public 类、接口以及 import 语句有一些相似之处。可以用以下方式来类比理解: Export 在 TypeScript 中,export 用于将模块中的变量、函数、类等暴露给外部…...
QT JSON使用实例
下面是一个使用Qt框架的示例代码,展示如何获取仪器的状态,将其打包成JSON格式,保存到当前目录下的JSON文件中,然后通过FTP发送该文件。 1. 准备工作 确保你已经安装了Qt,并创建一个新的Qt Console项目或Qt Widgets项目…...

浅聊 Three.js 屏幕空间反射SSR-SSRShader
浅聊 Three.js 屏幕空间反射SSR(2)-SSRShader 前置基础 渲染管线中的相机和屏幕示意图 -Z (相机朝向的方向)||| -------------- <- 屏幕/投影平面| | || | || | (f) | <- 焦距| | ||…...
Windows图形界面(GUI)-DLG-C/C++ - 月历控件(MonthCalendar)
公开视频 -> 链接点击跳转公开课程博客首页 -> e链接点击跳转博客主页 目录 月历控件(MonthCalendar) 使用场景 控件操作 月历控件(MonthCalendar) 使用场景 日程安排:用户可以通过月历控件选择特定的日期来安排会议或活动。事件管理&#x…...

【Langchain大语言模型开发教程】基于文档问答
🔗 LangChain for LLM Application Development - DeepLearning.AI Embedding: https://huggingface.co/BAAI/bge-large-en-v1.5/tree/main 学习目标 1、Embedding and Vector Store 2、RetrievalQA 引包、加载环境变量 import osfrom dotenv import…...

大厂面试-基本功
大厂面试第4季 服务可用性多少个9是什么意思遍历集合add或remove操作bughashcode冲突案例BigdecimalList去重复IDEA Debugger测试框架ThreaLocal父子线程数据同步 InheritableThreadLocal完美解决线程数据同步方案 TransmittableThreadLocal 服务可用性多少个9是什么意思 遍历集…...

RV1103使用rtsp和opencv推流视频到网页端
参考: Luckfox-Pico/Luckfox-Pico-RV1103/Luckfox-Pico-pinout/CSI-Camera Luckfox-Pico/RKMPI-example Luckfox-Pico/RKMPI-example 下载源码 其中源码位置:https://github.com/luckfox-eng29/luckfox_pico_rtsp_opencv 使用git clone由于项目比较大&am…...

与Bug较量:Codigger之软件项目体检Software Project HealthCheck来帮忙
在软件工程师的世界里,与 Java 小程序中的 Bug 作战是一场永不停歇的战役。每一个隐藏在代码深处的 Bug 都像是一个狡猾的敌人,时刻准备着给我们的项目带来麻烦。 最近,我就陷入了这样一场与 Java 小程序 Bug 的激烈较量中。这个小程序原本应…...

Git --- Branch Diverged
Git --- Branch Diverged Branch Diverged是如何形成的如何解决RebaseMerge Branch Diverged是如何形成的 尝试提交并将更改推送到 master 分支时,是否看到这条烦人的消息 原因是: 直到更改 B 之前,我的分支和“origin/master”完全相同。从…...
go标准库---net/http服务端
1、http简单使用 go的http标准库非常强大,调用了两个函数就能够实现一个简单的http服务: func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) func ListenAndServe(addr string, handler Handler) error handleFunc注册一个路…...

Linux文件和目录常用命令
1.操作命令 查看目录内容 ls 切换目录 cd 创建和删除操作 touch rm mkdir 拷贝和移动文件 cp mv 查看文件内容 cat more grep 其他 echo 重定向 > 和 >> 管道 | 1.1 终端实用技巧 1>自动补全 在敲出 文件/目录/命令 的前几个字母之后,按下…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...