连载中 19/22

大表 DDL:千万级表加字段的正确姿势

2026-05-11 · 5751 阅读 · 0 评论 · 0 赞

加个字段,全站报错

产品要在订单表加一个 remark 字段,老王看表才 4000 万行,随手一条 ALTER TABLE——三秒后接口全线超时报警。这一课学费贵,这篇把大表 DDL 的坑位和正规姿势一次讲透。

先懂堵车:MDL 元数据锁

DDL 动表结构,必须拿到这张表的 MDL 写锁;查询和 DML 拿 MDL 读锁,读写互斥。规则只有两条,但组合起来很要命:

  • MDL 写锁申请要排队等所有读锁释放;
  • 写锁等待期间,新来的读锁也排在它后面——后面所有查询全部堵死。

于是一个未提交的长事务(哪怕只是 SELECT)持着读锁不放,你的 ALTER 排队,全表的业务查询跟着一起排队——雪崩。排查方法第 15 篇的 metadata_locks 就是为此准备的。做 DDL 前先确认没有长事务,是第一军规。

Online DDL:数据库自带的温和方案

5.6 起 InnoDB 支持在线 DDL,DDL 期间读写大多不被阻塞(短暂的锁只在开始和结束的瞬间)。每种操作的支持度不同,用 ALGORITHM 显式声明并让数据库拒绝不支持的写法:

# INSTANT:只改元数据,秒级完成(8.0.12+ 加列的主力)
ALTER TABLE orders ADD COLUMN remark VARCHAR(255) DEFAULT NULL, ALGORITHM=INSTANT;

# INPLACE:引擎内重建,不复制整表到服务层,期间可读写(耗时但不断流)
ALTER TABLE orders ADD INDEX idx_amount (amount), ALGORITHM=INPLACE, LOCK=NONE;

等级:INSTANT(秒改元数据)> INPLACE(引擎内原地重建)> COPY(建影子表全量复制,锁写)。8.0 的加列默认 INSTANT,这是 8.0 值得升级的实在理由之一;但修改列类型、加全文索引等仍要走 INPLACE 甚至 COPY。INPLACE 重建大表依然要数小时、占双倍空间、产生大量 redo——不断流不等于没成本,主从延迟(第 12 篇)会被 DDL 结束时的大事务补课拉爆。

gh-ost:可控割接的外科手术

更大的表(亿级)、或对限速有要求时,用 gh-ost 这类工具,原理三步:

  • 建影子表:按目标结构建 orders_ghost,空表;
  • 拷数据 + 追增量:分批把原表数据拷进影子表,同时订阅 binlog 把期间的增删改持续回放到影子表(顺序、限速都可控);
  • 原子割接:数据追平后 RENAME TABLE 原子换名,业务无感。

对比 Online DDL,gh-ost 付出的是双倍存储与更长的总耗时,换来的是可暂停、可限速、可观测、随时中止——生产环境大表变更的安心丸。pt-online-schema-change 同理(用触发器追增量,gh-ost 用 binlog,后者对业务更无侵入)。

大表 DDL 作业清单

  • 先查长事务:information_schema.innodb_trx 清场;
  • 低峰期执行,明确 ALGORITHM,让不支持的语句直接报错而不是偷偷 COPY;
  • 亿级表或需限速:gh-ost,变更前演练与预估时长;
  • 主从架构下关注从库回放延迟,必要时逐台执行;
  • 能不加字段就不加:扩展表、JSON 字段(低频访问的附属信息)是缓兵之计,但别当万能药。

表结构动得了,数据量继续涨怎么办?分库分表的临界点判断和拆分姿势,下一篇讲。

咖啡凉了,记得趁热喝。

503

10 年全栈工程师 · 503咖啡馆主理人

#MySQL#大表DDL#MDL锁#Online DDL#gh-ost

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞