面试官问你 MySQL 的线上执行 DDL 该怎么做?4 种方案多角度回答!

MySQL下使用Inplace和Online方式创建索引的教程 MySQL各版本,对于add Index的处理方式是不同的,主要有三种: (1)Copy Table方式 这是InnoDB最早支持的创建索引的方式。顾名思义,创建索引是通过临时表拷贝的方式实现的。 新建一个带有新索引的临时表,将原表数据全部拷贝到临时表,然后Rename,完成创建索引的操作。 这个方式创建索引,创建过程中,原表是可读的。但是会消耗一倍的存储空间。 (2)Inplace方式 这是原生MySQL 5.5,以及innodb_plugin中提供的创建索引的方式。所谓Inplace,也就是索引创建在原表上直接进行,不会拷贝临时表。相对于Copy Table方式,这是一个进步。 Inpla 立即下载

摘要

在 MySQL 的面试中有一类经典的面试题。比如《如何给正在线上运行的表执行 DDL 语句?》

回答这个问题,首先我们需要明确,执行 DDL 语句的时候,MySQL 会干什么

在 MySQL 5.6 之前,执行 DDL 语句的时候,会给表添加写锁,会阻塞该表其他所有的读写操作。这对生产来说,这个写锁占用的时间越久,对整个数据库带来的风险就越大。所以我们回答的核心就是如何避免这种影响,或者说如何将这种影响降低到最小


在 MySQL 中,DDL 算法有两种

  1. copy 算法
  2. inPlace 算法(Online DDL)

copy 算法

在 MySQL 5.6 之前,只有 copy 算法。当执行 DDL 语句或者重建表语句时,算法的流程如下图:首先会创建一个 tmp 临时表,然后将 A 表中的数据,向 tmp 表中移动;移动完成之后将 A 表改为 tmp 表,然后之前创建的 tmp 表就成为了新的 A 表。至此完成了 DDL 操作,或者重建表的操作

在 copy 算法中,不难发现。插入过程的 IO 操作是十分耗时的,如果这个时间有新的数据想写入 A 表的话,就可能造成数据的丢失。所以 copy 算法在整个 DDL 期间,或者重建表期间,A 表是不允许更新的,也就是说 copy 算法 state 4 之前都需要给表加写锁!

所以对应下面即将要讲的算法而言,copy 算法不是 Online 的


inPlace 算法

所以 MySQL 5.6 版本开始引入的 InPlace 算法,也就是 Online DDL 算法,主要解决的就是如何缩短写锁的时间

  1. 建立一个临时文件,扫描表 A 主键的所有数据页
  2. 用数据页中表 A 的记录生成 B+ 树,存储到临时文件中
  3. 生成临时文件的过程中,将所有对 A 的操作记录在一个**日志文件(row log)**中,对应的是下图 state2 的状态
  4. 临时文件生成后,将日志文件中的操作应用到临时文件,得到一个逻辑数据上与表 A 相同的数据文件,对应的就是图中 state3 的状态
  5. 用临时文件替换表 A 的数据文件

copy 算法中,我们讲的是 DDL 语句,那么 inPlace 算法我们用 alter 语句来讲

alter table A engine = innodb,ALGORITHM = inplace;

所以 inPlace 算法,由于日志文件记录和重放操作这个功能的存在。这个方案在重建表或者执行 DDL 语句的过程中,允许对表 A 做增删改操作,这也就是 Online DDL 名字的来源

回答这个算法最初的目的,他是为了缩短写锁的占用的时间

既然有一个 row log 记录操作,那么是不是就不需要获取写锁了?

实则不然,在上图的流程中,DDL 语句在启动的时候需要获取 MDL 写锁。但是这个写锁在正在拷贝数据之前就退化为读锁了,而不是像 copy 算法在 state 4 之前一直占用

那面试官问你为什么需要重建表的语句需要退化为读锁?

上面已经回答你了,肯定是为了 Online 啊,只有 MDL 读锁才不会阻塞增删改操作

那面试官继续问你为什么不干脆直接解锁呢?

inPlace 算法也需要保护自己,它需要先获取到 MDL 写锁,然后安全地操作表的物理和元数据文件。因为只有 MDL 写锁才能保证全局唯一、100%安全的操作。如果在执行 Alter 语句时有其他线程对这个表同时做 DDL,可能就会造成元数据损坏,死锁等问题

但是我想告诉的你,DDL 语句中,如果是在末尾增加列,那么 DDL 语句是完全不会阻塞的。只有在中间增加列,才有一个加锁的过程。因为只有修改中间,才会导致数据的排列变更,也就需要更改元数据。但是即使上面的 Online DDL 需要加锁,也只是一个元数据的更新,占用的时间很短。


copy 算法和 inPlace 算法创建的 tmp 都一样吗?

其实你仔细观察上面的两个图,你就发现了 copy 算法使用的是 tmp;inPlace 使用的是 tmp_file

  1. 如果在 tmp_table 中,这个临时表是在 server 层创建的。这就是 copy 算法
  2. 如果在 tmp_file 中,这个临时文件是 InnoDB 在内部创建出来的。这就是 inPlace 算法

tmp_file 整个 DDL 过程或者重建表的过程都在 InnoDB 内部完成。而对于 server 层来说,没有把数据挪动到 tmp_table 中。所以从 server 层看这就是一个“原地”操作,这就是“inplace”名称的来源

Online 和 inplace 两个逻辑之间的关系是什么?

  1. DDL 过程如果是 Online 的话,就一定是 inplace
  2. 反过来未必,也就是说 inplace 的 DDL,有可能不是 Online 的 截止到 MySQL 8.0,添加全文索引(FULLTEXT index)和空间索引 (SPATIAL index) 就属于是 inplace 操作,但不属于 Online(会阻塞增删改操作)

当然,也不是所有的 DDL 语句都支持 inPlace 操作,比如修改字段的类型就不支持 inPlace 算法

详细可以看官方文档

dev.mysql.com/doc/refman/…

Instant Add Column

Inplace 虽然不会阻塞 DML,也就是数据库的读写操作。但是如果表结构很大,持续的事件会比较久,也就是更新可能会在分钟级别的时间生效,这就产出了一个长事务(长事务的影响不是本章讨论的重点,不再过多赘述)。

而为了让这个生效的事件更加实时,MySQL 8 推出了新的功能:Instant Add Column

ALTER TABLE A ADD COLUMN new_column INT, ALGORITHM = INSTANT;

问题的来源是我们需要新建一个临时文件,那我们是不是不创建临时文件就解决了问题?

Instant Add Column 算法就是这么做的,具体的原理如下

  1. 只修改表的元数据,不重写一行数据,不产生临时表,也不拷贝表数据!
  2. 添加的字段,实际物理上不会在磁盘页里新增内容,只是在表的“数据字典”中记录“新加了一个字段,默认值为XXX,排在第几列”
  3. 读取老数据页时,遇到没有物理存储的字段,自动用默认值补齐(MySQL 8.0页格式的能力)
  4. 只有新插入/修改的数据,才会真正把新字段内容写进磁盘页(老行还是只有旧字段,新行是新字段格式)

Instant Add Column 算法速度极快:表再大,加字段都只需几毫秒到一秒钟,无论几十 G 还是几百 G 表

当然它的限制条件也很多,Instant Add Column 只能加在表的最后一列,不支持中间插入。

因为讲 inplace 算法的时候,就提及过在末尾增加列的事情。那这里我们在重点讨论一下为什么 Instant Add Column 算法不能在中间插入。因为如果新列只加在最后一列,原有的数据页中的所有行的字段顺序和偏移都不需要变。读取时,只需在“旧行”后面补上新列的默认值,不会出错,也不需要改数据页。如果你要求在中间插入一个字段,所有后面的每一列的偏移都要变,整个数据页里每一行的物理存储结构(列偏移信息)都要修改。所有旧数据行都要被重新解析、重写、移动,否则读取时会乱套,甚至解析出错。

还有其他的限制如下,都很好理解,不再一一解释

  1. 字段必须允许NULL或者有默认值(NOT NULL 且无默认值肯定是不行的)
  2. 新字段也不能有 UNIQUE、PRIMARY KEY 等唯一约束,不能加自增
  3. 表必须是 InnoDB,且使用 MySQL 8.0.12+ 的新数据页格式

主从切换

在双 Master 的集群中。可以先在 Master B 中执行 DDL 语句,之后再将 client 接入到 Master B 中。然后再去修改 Master A


5. 总结

如何给正在线上运行的表执行 DDL 语句?

  1. DDL 我们需要结合业务场景和环境来看
  2. 如果新增列,并且 MySQL 使用的是MySQL 8,优先使用 instant 算法,这样既可以避免锁表,又能快速生效
  3. 如果是 5.6/5.7 版本,优先使用 Online DDL 功能,具体来说就是更新时指定算法是 inplace,可以避免重建表带来的锁表
  4. 如果上述方案都不能用,例如指定列更新或者更低版本,可以采用主从切换的方式来更新

YOLOv8改进 | Conv篇 | 轻量级下采样方法ContextGuided(大幅度涨点) ContextGuided通过创新的局部-全局协同机制,解决了传统下采样方法中细节丢失与上下文缺失的核心痛点。实验证明其在YOLOv8上可实现最高2.6%的mAP提升,且计算开销增加不足5%。这种即插即用的设计为实时目标检测系统提供了新的优化方向。创新启示:轻量化不代表简单裁剪,智能信息融合才是未来方向!下一步探索与Transformer结合构建混合架构多尺度上下文融合机制3D点云中的扩展应用资源获取完整训练代码:[GitHub链接]预训练模型:[Google Drive链接]讨论话题。 阅读详情

相关推荐

CESM2 实验笔记

文章目录1. 重新启动1.1 关于重启文件2. RUN_TYPE 初始化运行方式startupbranchhybrid3. branch 或者 hybrid运行的示例4. 其他声明5. 关于RESUBMIT 1. 重新启动 参考: https://bb.cgd.ucar.edu/cesm/threads/how-to-restart-cesm2-1-3-fhist-from-a-backup.5245/#post-36275 适用情况:模型运行因时间不足或其它原因中断,需要继续运行 方法1:将CONTIN

qq_38607066的博客 1万+

inplace mysql_MySQL下使用Inplace和Online方式创建索引的教程

MySQL各版本,对于add Index的处理方式是不同的,主要有三种:(1)Copy Table方式这是InnoDB最早支持的创建索引的方式。顾名思义,创建索引是通过临时表拷贝的方式实现的。新建一个带有新索引的临时表,将原表数据全部拷贝到临时表,然后Rename,完成创建索引的操作。这个方式创建索引,创建过程中,原表是可读的。但是会消耗一倍的存储空间。(2)Inplace方式这是原生MySQL ...

weixin_39889481的博客 612

EtherCAT简介

EtherCAT(EtherNet Control Automation Technology)是由德国公司BECKHOFF公司于2003年提出的实时工业以太网技术。其具有高速、高数据有效率的特点,支持多种设备的连接拓扑结构。从站节点使用专用的控制芯片,例如:microchip公司的Lan9252、BECKHOFF公司的ET1100等ESC(EtherCAT slave controller)芯片。主站的搭建方式有很多,例如:开源主站IGH、SOEM、商业化主站TwinCAT等。

m0_73482095的博客 1万+

MySQL DDL简析(1):inplace DDL 主要stage介绍

本文只是描述DDL中最慢的一个环节是在完成哪些工作,深入程度有限,如果有误请谅解。主要从DBA的角度来看这个问题,也是我一直比较迷惑的地方。基于代码8.0.23。本文术语:DML log:...

老叶茶馆 1764

TS808效果器制作教程

TS808效果器制作教程 可以在立创商城购买到大部分的电阻电容和IC,音频接口,踩钉,电位器和电源接口可以去某宝看看都买得到的。链接https//pan.baidu.com/s/1QId1eIE3fJ2u5NLBSISvGA。安装过程过于繁琐,把所有元器件按照图纸焊接完成就可以调试了,祝你们成功!这是TS808经典效果器制作过程的记录。IC是JRC4558。...

qq_18948149的博客 3429

保姆级教程:用Comsol Multiphysics仿真你的第一个SAW滤波器(含压电材料参数设置)

本文提供了一份详细的COMSOL Multiphysics教程,指导读者完成表面声波滤波器(SAW)的压电仿真全流程。从压电材料参数设置、叉指换能器建模到多物理场耦合分析,特别强调了实际应用中容易出错的细节和解决方案,帮助工程师快速掌握SAW滤波器仿真技术。

weixin_42665255的博客 593

inplace mysql_MySQL实战45讲学习笔记:第十三讲

一、引子经常会有同学来问我,我的数据库占用空间太大,我把一个最大的表删掉了一半的数据,怎么表文件的大小还是没变?那么今天,我就和你聊聊数据库表的空间回收,看看如何解决这个问题。这里,我们还是针对 MySQL 中应用最广泛的 InnoDB 引擎展开讨论。一个 InnoDB 表包含两部分,即:表结构定义和数据。在 MySQL 8.0 版本以前,表结构是存在以.frm 为后缀的文件里。而 MySQL 8...

weixin_34776437的博客 904

YonSuite如何新增用户并分配角色角色授权图文教程

用友YonSuite产品基础教学

ct341688的博客 622

MYSQLDDL

重放 row_log 中的操作到 new_table 的索引上(not-rebuild 数据是在原表上更新)。MySQL 使用 inplace 算法时,会自动判断,能使用 not-rebuild-table 的情况下会尽量使用,不能的时候才会使用 rebuild-table。MySQL 会建立一个新的临时表,把源表的所有数据写入到临时表(将原表数据拷贝到临时表(无排序,一行一行操作),在此期间无法对源表进行数据写入,MySQL 在完成临时表的写入之后,用临时表替换掉源表,新建临时表存储空间会增加一倍。

云计算、数据库、大数据、容器、微服务、深度学习、NLP、Python 712

音视频从入门到精通——指数哥伦布码原理

在计算机中,一般数字的编码都为二进制,但是由于以相等长度来记录不同数字,因此会出现很多的。

mirana的专栏 1383

Python爬虫实战:基于Scrapy与Playwright的搜狐新闻高效爬取

在当今信息爆炸的时代,网络爬虫技术已成为数据获取和分析的重要工具。作为国内领先的新闻门户网站,搜狐新闻包含了大量有价值的新闻数据,这些数据对于舆情分析、市场研究等领域具有重要意义。本文将详细介绍如何使用Python最新的爬虫技术栈(Scrapy框架结合Playwright浏览器自动化工具)来高效爬取搜狐新闻数据。pythontitle = scrapy.Field() # 新闻标题url = scrapy.Field() # 新闻链接。

2201_76125261的博客 1553

字段长度扩容大冒险:MySQL的Inplace与Copy之辩

算法,也就是创建临时表,把数据copy过去,最后交换名字,删除旧表。如果要修改的表是张大表的话,肯定要花费很久的时间,虽然MDL加锁时间很短,并不会影响该表正常读写,但是如果涉及主从架构的话,产生主从延迟是不可避免的了。毕竟在这个数据决定一切的时代,一个小小的字段变更,都可能引发连锁反应,影响无垠。这时候,糟糕的开发同学又急匆匆地跑来了,说刚才字段长度说错了,其实计划修改为。,他们坚持现行的做法,就地修改字段长度,免去了数据挪移的麻烦。这条修行之路虽然漫长,但对于数据库从业者来说,一定是充满乐趣和挑战的。

qq_39430356的博客 2009

在 SAP BTP 中通过 MTA 自动创建 Service Broker 的原理与实战

本文探讨了如何在SAP BTP的Cloud Foundry环境中通过MTA部署自动创建和注册Service Broker。传统手动注册方式存在依赖管理员、环境一致性差等问题。通过MTA部署可实现自动化Broker注册,利用占位符生成安全凭证,并确保平台端与应用端认证一致。文章详细解析了关键配置参数,包括create-service-broker标志、Broker名称、认证凭据和访问URL的设置方法。这种基础设施即代码(IaC)方式能提升DevOps实践水平,使服务注册成为应用部署流水线的有机组成部分。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 201

inplace mysql_MySQL之Inplace Upgrade升级原理与实践

第一章 MySQL-INPLACE就地升级原理过程INPLACE就地升级MySQL过程原理:关闭原数据库(业务挂维护页)备份原数据库数据安装新版本软件使用新版本软件挂旧版本数据启动升级系统表正常重启数据库验证各项功能是否正常恢复业务MySQL官方升级指导注意:MySQL升级只是升级系统表,升级时间和数据量无关。另外需要说明一点,数据库升级尽量使用Mergeing迁移升级(主从迁移、备份迁移),就...

weixin_39726873的博客 645

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

mysql inplace_MySQL 'In Place' 升级实践,从5.1到5.7

1、环境准备数据库A版本:5.1字符集:latin1引擎:MyISAM数据库量:约220G表数据量:约600服务器:centos6.52、升级过程已经搭建好5.1版本数据的从库,等主从同步之后,开始升级从库在第一次升级时遇到问题,执行mysql_upgrade显示表损坏。我们在升级前,首先检查并修复表(MyISAM引擎)。./bin/mysqlcheck-uroot-h-P-p-r-...

weixin_42284052的博客 351

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

MYSQL 的老大难,instant ,inplace,copy, DDL 怎么弄, 我不想迷迷糊糊

DDL 操作一直是我们的 MYSQL 的一个软肋,从MYSQL 5.6 其实相关的alter 语句已经有了改变,也就是题目的的inplace 和 copy 。其实很多人都知道,但用的比较...

sql server的专栏 1974

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

数据库系列之InnoDB中在线DDL实现机制

DDL变更时应用版本部署过程中的常见操作,在核心业务系统中DDL操作不能保证在线完成,是会影响业务7x24小时的。MySQL 5.6开始支持在线DDL的操作,解决了执行ddl锁表的问题,保证了在进行表变更时,不会堵塞线上业务读写,保障在变更时,库依然能正常对外提供访问。本文简要介绍在线DDL的原理以及DDL原子性的实现,加深理解。

牧羊人的方向 2387

MySQL--Online DDL三种算法原理详解

online-DDL详细原理介绍及gh-ost讲解_online ddl-优快云博客。

数据库学习ing 3487

Mysql online DDL 线上无锁添加索引

只能通过ALTER TABLE不能create index ALTER TABLE tbl_name ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE; 参数说明: ALGORITHM=INPLACE 更优秀的解决方案,在当前表加索引,步骤: 1.创建索引(二级索引)数据字典 2.加共享表锁,禁止DML,允许查询 3.读取聚簇索引,构造新的索引项,排序并插 入新索引 4.等待打开当前表的所有只读事务提交 5.创建索引结束 ALGORIT

Crystalqy的博客 6996

【MYSQL数据库升级,从MYSQL5.7到MySQL8】MySQL in-place升级数据库 从5.7 到8.0.36

mysql数据升级,从5.7 到 mysql 8.0

gsforget321的博客 2568

MySQL在线DDL原理

MDL锁,读读不互斥,读写、写写互斥。3. 我们常说的 Online DDL,其实是从 DML 操作的角度描述的,如果 DDL 操作不阻塞 DML 操作,那么这个 DDL 就是 Online 的。,在 5.6 的基础上又增加了一些新的特性,比如:增加了重命名索引支持,支持了数值类型长度的增大和减小,支持了 VARCHAR 类型的在线增大等。默认情况下,MySQL就是支持online的DDL操作的,在online的DDL语句执行的过程中,MySQL会尽量少使用锁的限制,我们不需要特殊的操作来启用它。

meser88的博客 2282
上一篇: 看到同事设计的表结构我人麻了!聊聊怎么更好去设计数据库表
下一篇: 事务管理:ACID特性与隔离级别详解
程序员职业指南
博客等级 码龄4年 2138粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值