最近刷到不少面试题和技术视频都在讨论:MySQL千万级大表如何添加字段?这题我可太会了,都是血泪教训换来的经验啊!
三种靠谱解决方案
方案一:原生Online DDL(MySQL 5.6+)
如果你的MySQL版本比较新,可以这样操作:
ALTER TABLE user
ADD COLUMN level INT DEFAULT 0 COMMENT '用户等级',
ALGORITHM=INPLACE,
LOCK=NONE;
重点参数:
ALGORITHM=INPLACE
:避免重建表LOCK=NONE
:允许并发读写
⚠️ 注意事项:
- 一定要在测试环境先试一遍
- 操作前检查是否有长事务
- 选择凌晨等业务低峰期操作
方案二:pt-online-schema-change(推荐)
这是Percona公司的工具,我们现在线上环境都在用:
pt-online-schema-change \
--alter="ADD COLUMN level INT DEFAULT 0" \
D=testdb,t=user \
--critical-load="Threads_running=100" \
--max-load="Threads_running=50" \
--execute
这个工具的工作原理很巧妙:
- 创建一张新表(已经加上新字段)
- 创建触发器同步增量数据
- 分批拷贝旧数据
- 最后瞬间切换表名
整个过程只在最后rename时锁表一瞬间,对业务影响很小。
方案三:gh-ost(新一代方案)
GitHub开源的工具,用binlog来同步数据:
gh-ost \
--allow-on-master \
--database="testdb" \
--table="user" \
--alter="ADD COLUMN level INT DEFAULT 0" \
--execute
优点是不用触发器,性能影响更小,还可以随时暂停、动态调节速度。
三种方案怎么选?
特点 | Online DDL | pt-osc | gh-ost |
---|---|---|---|
锁表时间 | 较短 | 毫秒级 | 毫秒级 |
性能影响 | 中等 | 较轻 | 最轻 |
使用难度 | 简单 | 中等 | 中等 |
适用版本 | MySQL 5.6+ | 所有版本 | 所有版本 |
- 求稳:用pt-online-schema-change,资料多社区成熟
- 性能要求高:用gh-ost,控制更灵活
- 版本新且量小:可以用原生Online DDL
重要经验总结
- 备份第一:操作前务必备份数据
- 测试必做:在测试环境完整演练一遍
- 低峰操作:选择业务量最少的时间段
- 监控到位:实时关注数据库负载和连接数
- 预案准备:准备好回滚方案和应急措施
千万级大表的DDL操作,真的不能掉以轻心。一次失误可能就会导致重大事故,希望我的经验能帮大家避开这个坑!
你在工作中有没有遇到过类似的踩坑经历?欢迎在评论区分享交流~