MySQL大表DDL锁表避坑指南:COPY、INPLACE、INSTANT三种算法全解析

简介: 很多人只知道“Online DDL不锁表”,却不清楚什么场景真的不锁、什么场景照样锁。本文从DDL的三种算法入手,拆解Online DDL的触发条件、锁表场景、以及大表DDL的实战避坑方案。

大家好,我是小耶,写功课只是为了我踩过的坑,你们别再踩了!

凌晨两点,业务低峰期。

你准备给一张8000万行的订单表加一个字段。按照计划,停机窗口30分钟,应该够了吧?

结果ALTER TABLE跑了47分钟还没结束。业务方电话打过来了:“系统怎么打不开了?”

——因为DDL锁表了。

MySQL 5.6之前,加字段、加索引这种操作,全程锁表,写操作全部阻塞。8000万行的表,DDL跑几个小时,业务就停几个小时。

MySQL 5.6引入了Online DDL,5.7和8.0持续增强。但很多人只知道“Online DDL不锁表”,却不清楚什么场景真的不锁、什么场景照样锁。

今天把Online DDL彻底拆开讲清楚。

一、Online DDL的三种算法

MySQL执行DDL时,会根据操作类型和参数选择不同的算法。理解这三种算法,是理解Online DDL的基础。

算法一:COPY

最原始的方式。MySQL创建一个新的临时表,把原表数据逐行复制到新表,复制完成后删除原表、重命名新表。

全程锁写——复制期间,原表的写操作全部阻塞。8000万行的表,COPY算法可能要跑几个小时。

算法二:INPLACE

MySQL 5.6引入。不需要复制整张表的数据,直接在原表上修改。但不一定完全不锁表——某些INPLACE操作仍然需要短暂的锁(比如修改表结构时)。

INPLACE的核心是:尽量在原有数据文件上直接操作,减少数据复制。

算法三:INSTANT

MySQL 8.0.12引入。只修改数据字典中的元数据,不触碰实际数据文件。加字段这种操作,INSTANT算法几乎瞬间完成——因为只是在表的元数据里加了一条记录,已有的数据行根本不需要动。

INSTANT是Online DDL的终极形态:真正的零锁表、秒级完成。

二、不同DDL操作,分别用什么算法?

加字段(ADD COLUMN)

  • MySQL 5.6:INPLACE,但需要重建表(实际上类似COPY)

  • MySQL 5.7:INPLACE,支持在线操作

  • MySQL 8.0.12+:INSTANT,秒级完成(仅限在表末尾加字段)

  • MySQL 8.0.29+:支持在任意位置加字段,但可能降级为INPLACE

加索引(ADD INDEX)

  • MySQL 5.6+:INPLACE,支持在线操作

  • 加索引期间,读操作不阻塞,写操作可以并发进行

  • 但加索引的耗时与数据量成正比——8000万行的表,加索引可能需要几十分钟

修改字段类型(MODIFY COLUMN)

  • 大部分情况:COPY,需要重建表

  • 修改VARCHAR长度(增大):INPLACE可能支持

  • 修改INT到BIGINT:COPY,需要重建表

删除字段(DROP COLUMN)

  • MySQL 8.0.29+:INSTANT

  • 更早版本:INPLACE或COPY

修改字符集(CONVERT TO CHARACTER SET)

  • COPY,全程锁写,大表慎用

三、怎么判断DDL会不会锁表?

方法一:看ALGORITHM和LOCK参数

执行DDL时可以显式指定算法和锁级别:

-- 指定使用INPLACE算法,允许并发读写
ALTER TABLE orders ADD COLUMN remark VARCHAR(200), 
ALGORITHM=INPLACE, LOCK=NONE;

如果MySQL不支持指定的算法或锁级别,会直接报错——这是好事,至少你知道这个操作不安全。

方法二:查看INFORMATION_SCHEMA.INNODB_TABLES

MySQL 8.0可以查询表的DDL执行历史,了解之前的操作使用了什么算法。

方法三:看官方文档的Online DDL支持矩阵

MySQL官方文档有一张详细的表格,列出了每种DDL操作支持的算法和锁级别。做DDL之前先查一下,比盲目执行靠谱得多。

四、大表DDL实战避坑方案

避坑1:别在业务高峰期做DDL

即使是Online DDL,加索引、修改字段类型等操作仍然会消耗大量I/O和CPU。业务高峰期做DDL,可能拖慢整个数据库的响应时间。

避坑2:优先用INSTANT算法

MySQL 8.0.12+加字段(末尾)用INSTANT,秒级完成。升级到8.0是解决大表DDL最直接的办法。

避坑3:用pt-online-schema-change或gh-ost

如果MySQL版本不支持INSTANT,或者DDL操作必须用COPY算法,可以用Percona的pt-online-schema-change或GitHub的gh-ost。原理是:创建新表 → 复制数据 → 增量同步 → 原子切换。整个过程对业务透明,但需要额外的磁盘空间和更长的执行时间。

避坑4:DDL前先备份

不管用什么方案,DDL之前先备份。DDL失败可能导致数据不一致,有备份才有退路。

避坑5:控制单次DDL的规模

一次DDL只做一个操作。加字段和加索引分开做,避免一个DDL语句同时触发多种算法。

五、小结

Online DDL不是“所有DDL都不锁表”,而是“在特定条件下不锁表”。COPY算法全程锁写,INPLACE算法大部分场景不锁写但可能短暂锁,INSTANT算法才是真正的秒级零锁表。做DDL之前,先确认三件事:MySQL版本支持什么算法?你的DDL操作属于哪种类型?业务能不能接受短暂的锁?搞清楚这些,比盲目执行安全得多。

小耶在手,SQL 不愁

还有什么想了解的,欢迎留言!小耶一定知无不言言无不尽……我们下次见~

相关文章
|
1月前
|
SQL 人工智能 Oracle
VLDB 2026核心议题解读:当负载被AI改写,数据库的内核该往哪走?
国际数据库顶级会议VLDB 2026将“AI Agent时代的数据系统”列为核心议题,数据库研究正在转向“如何让数据被AI Agent理解和使用”。当负载被AI改写,数据库需要重新设计什么?DBA的技能储备需要往哪个方向延伸?
|
1月前
|
SQL Java 数据库连接
1万行插入13秒到0.9秒:ORM批量插入只差一个参数
从一次列表接口慢的排障讲起,发现2000多条一模一样的N+1查询。文章拆开ORM生成慢SQL的三类典型病:N+1懒加载、逐条批量插入(只差一个rewriteBatchedStatements参数)、隐式转换让索引白建。给出JOIN/批量IN/@BatchSize的取舍、MyBatis与JPA各自的修法,以及用performance_schema按SQL指纹抓N+1、测试环境打印真实SQL的协作办法。
|
26天前
|
缓存 人工智能 关系型数据库
大模型调用成本降62%?语义缓存的阈值与命中率实测
客服机器人上线两周,用户问题高度重复,每次都走完整套RAG,数据库读QPS翻三倍,大模型账单飞涨。文章讲清语义缓存怎么用"向量相似度"代替"字符串相等"去命中重复提问,落地时数据该存哪、相似度阈值怎么定,以及多租户隔离、知识库更新失效、别缓存低质量回答这几个真正的难点。附两周实测:命中率约57%,大模型成本降约62%,命中时首字延迟从3.2秒降到0.45秒。
|
1月前
|
人工智能 Cloud Native 数据库
向量数据库选型实战:从 Embedding、ANN 索引到三条落地路线
本文直击向量数据库本质:不堆概念,不列产品,专讲它“是什么”、三条选型路径(专用库/关系库扩展/云托管)如何取舍,以及开发者落地必须关注的召回率、延迟、更新一致性等真实问题。聚焦RAG实战,强调“先用pgvector跑通再升级”,拒绝盲目上马。
138 0
|
1月前
|
SQL 监控 关系型数据库
MySQL索引合并优化器陷阱:为什么复合索引比索引合并快一个数量级?
MySQL优化器有一个“自作聪明”的行为——当单列索引无法完全覆盖查询时,它可能选择索引合并(Index Merge) ,同时使用多个单列索引,把结果集合并起来。听起来很合理对吧?但索引合并有严格的适用条件,用错了比全表扫描还慢——尤其是UNION类型的索引合并,需要对多个结果集去重和排序,代价极高。本文拆解索引合并的3种类型、3个踩坑场景,以及什么时候该用复合索引替代。
|
1月前
|
存储 SQL 容灾
共享存储集群 vs 分布式多副本:同城双活两条技术路线怎么选?
同城双活正在成为金融、政务等核心系统的容灾标配——RPO=0、RTO<30秒。但真正的落地远不止“两个机房各放一套数据库”那么简单。网络延迟的容忍度、脑裂预防机制、同步复制的性能代价、以及故障切换后的数据回滚,每一个环节都可能成为“最后一公里”的绊脚石。本文从容灾架构演进入手,拆解同城双活的核心技术原理、关键挑战与应对方案,并结合同城双中心方案及实测数据进行深度解析。
|
1月前
|
SQL 运维 关系型数据库
2026年分布式数据库有哪些主流选择?先评估这5个维度再决定
分布式数据库选型,99%的文章在列表格比参数——但真正的决策关键不在厂商PPT里,在上线后的真实运维里。本文从网络延迟容忍度、SQL兼容性验证、在线扩容能力、全局索引代价、运维工具链成熟度5个维度出发,给出可落地的评估方法和决策建议,帮助你在选型阶段避开那些“只有上线后才会发现”的坑。
|
1月前
|
SQL 关系型数据库 MySQL
别再盯着EXPLAIN的rows列了,8.0.18之后有更好的选择
EXPLAIN是DBA最常用的工具之一,但大多数人还在看type、rows、Extra这些传统字段——然后靠经验猜。MySQL 8.0.18开始引入的EXPLAIN ANALYZE,直接把实际执行时间和行数输出给你看,不用猜了。本文对比传统EXPLAIN和EXPLAIN ANALYZE的差异,展示如何用新工具把执行计划分析这件事从“猜”变成“看”。
|
1月前
|
SQL 运维 算法
订单表上亿行,我按用户ID拆成128片之后怎么样了
从单表几千万行慢查询的痛点出发,讲清垂直拆分与水平拆分的区别、分片键怎么选、分片算法(hash取模/range/一致性hash)怎么权衡,以及分库分表带来的分布式ID、跨片查询、分布式事务等问题,给出避免过度拆分的避坑清单。
|
1月前
|
SQL 存储 关系型数据库
分区裁剪失效、DDL卡死、元数据爆炸:分区表的3个真实代价
很多人觉得分区表是“轻量级分库分表”——数据分开放、查询只扫一个区、过期数据直接DROP分区,听起来很完美。但分区表有严格的适用边界和隐藏代价:分区键选错导致所有查询都扫全部分区、分区数量过多导致DDL巨慢、跨分区查询比普通表还慢……本文从分区表的核心原理出发,拆解4种分区类型、3个真实踩坑场景,以及分区表与分库分表的本质区别,帮你一次性搞清楚到底该不该用。