建新表、挂触发器、分批迁移、重命名——海量数据高并发下不锁表扩字段
《数据库内核原理》第 38 篇:pt-online-schema-change 在线扩展表结构。
一个海量数据高并发的业务场景,产品经理前期没想清楚,现在想要增加业务属性,MySQL要扩展表结构,有什么办法吗?
alter table add column,行不行?
不可行,海量数据高并发情况下会锁表。
通过增加表的方式扩展,通过外键join来查询,行不行?
不可行,外键影响性能,连表影响性能,海量数据高并发情况下不行。
通过增加表的方式扩展,通过视图来查询,行不行?
不可行,视图影响性能,海量数据高并发情况下不行。
揍产品经理,避免需求变更,行不行?
不可行,打赢坐牢,打输住院。
提前预留一些reserved字段,以备扩展,行不行?
可行。但如果预留过多,会造成空间浪费,预留过少,不一定能达到扩展效果。
MySQL的online-schema-change,在线扩展字段,行不行?
可行。且这是标配。
MySQL的online-schema-change的原理是怎么样的?
如何能在海量数据高并发的场景下,平滑扩展字段呢?
假设原表为:user(id, name)
希望扩展字段升级为:user(id, name, age)
创建新表
user_new(id, name, age),也就是扩展字段后的表;
创建触发器
对原表user进行的所有写操作insert/delete/update,对新表进行相同的操作;
逐步迁移数据
分批限速将user表中的数据,迁移到user_new表;
删掉触发器
移走原表;
将新表user_new重命名rename为原表user
字段扩展完成;
整个过程不需要加大锁,可以持续对外提供服务。
MySQL的online-schema-change有什么注意事项吗?
有三点要注意:
其一,被迁移的表要求有主键,这个条件一般都满足;
其二,扩展过程中要建立触发器,原表如果已经有很多触发器,方案就不行,但互联网海量数据高并发的场景下,一般都不允许业务触发器;
其三,由于触发器的建立,会影响原表性能,因此这个操作最好在流量低峰期进行;
pt-online-schema-change是互联网MySQL-DBA必备的利器,在互联网公司使用广泛。
检验一下
检索练习 · 为什么不能直接改
海量数据高并发场景下,为什么不能用 alter table add column 直接扩展表结构?
检索练习 · 五步原理
pt-online-schema-change 的五个步骤,正确的顺序是?
检索练习 · 触发器的作用
方案中「创建触发器」这一步,解决的是什么问题?
检索练习 · 注意事项
online-schema-change 的三点注意事项是?
想照着动手,读这份:《pt-online-schema-change 介绍》,Percona Toolkit 官方文档,含完整参数与使用示例。

本篇的五步流程(创建新表、创建触发器、逐步迁移、删触发器、rename),正是 pt-online-schema-change 的标准实现。
这是《数据库内核原理》的最后一篇。从索引与 InnoDB 架构的地基出发,穿过主键、锁与 MVCC、redo log 与崩溃恢复的深水区,最后落在 explain 与 SQL 优化实战——愿你下次遇到 MySQL 问题时,不只是解决它,还能讲清楚它:知其然,知其所以然。
知其然,知其所以然。思路比结论更重要。