连载中 19/22

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

2026-05-11 · 5755 阅读 · 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)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10100 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9872 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9293 阅读 · 21 评论 · 287 赞