连载中 16/20

在线 DDL:分片环境的表结构变更

2026-07-26 · 2231 阅读 · 0 评论 · 0 赞

从一张表到三十二张表

MySQL 系列第 19 篇讲过单表大 DDL 的标准打法:用 gh-ost 或 pt-online-schema-change 做在线改表——影子表拷数据、增量回放、原子改名,全程不停写。分库分表之后,这套打法没有失效,只是工作量乘以了物理表的数量:一次加字段,8 库 32 表要跑 32 轮影子拷贝。好消息藏在坏消息里——每张物理表只有几百万行,单表拷贝从八小时缩到十几分钟;真正的难点从「怎么改一张大表」变成了「怎么协调三十二次小改表,全程线上无感」。

执行纪律:小步、串行、可停

分片环境的 DDL 变更纪律三条。金丝雀先行——先只改一个库的一张表,观察十五分钟:主从延迟、锁等待、同步链路都无恙,再继续;库内串行、库间并行——同一个实例上的表逐张改(共享 IO,并发只会互相拖慢),不同实例可以并行推进,总时长约等于最慢一库的耗时;可暂停可回退——gh-ost 支持暂停与终止,批处理脚本要有断点水位,变更中断后能从断点继续而不是从头再来。整套流程走下来,32 张表的加字段通常一个低峰夜就能安全完成。

真正的深坑:新旧结构共存

比执行更难的,是变更期间新旧表结构共存的问题:32 张表要改几个小时甚至一整夜,期间新旧结构同时在线——老结构的表没有新字段,新结构的表刚加上。这一刻如果有代码写了新字段的值,落到老结构的表直接报错。所以分片环境的 DDL 有铁律:结构变更和代码变更必须分两步发布

第一步:先发「读写都不依赖新结构」的代码(兼容新旧两种结构)
第二步:全量完成 DDL(32 张表逐张改)
第三步:再发「开始使用新字段」的代码
// 顺序反了:新代码写新字段 → 落到未改的老结构表 → 直接报错

删字段反过来:先停用(代码不读写),再删除。改字段类型最凶险,走「加新列、双写、刷数据、切读、删旧列」的完整迁移小流程——本质上是一次微型数据迁移,第 14-15 篇的框架直接套用。

让 DDL 变成日常小事

治理做得好的团队,会把分片 DDL 从「应急项目」变成「日常流程」:变更脚本模板化(金丝雀、串行、断点、校验全内置),执行平台化(点按钮跑批、进度可视、异常自动暂停),评审规则化(字段评审在拆分设计期就把未来半年可能的扩展想清楚,减少变更次数本身)。最好的 DDL 是不需要 DDL——设计期多想一步,运营期少熬一夜。

结构变更的工程讲完,接下来是数据的日常代谢:历史数据堆积怎么办、归档怎么设计才安全——下一篇聊聊让主表保持轻盈的冷热分离。

503

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

#在线DDL#gh-ost#分片变更#新旧结构兼容#金丝雀

评论 (0)

相关推荐

连载中 12/20

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

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

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 5 阅读 · 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 赞