大家好,我是数据库小学妹 👋
上个月帮一个客户做服务器迁移,数据库大概两百万条数据。当时觉得 mysqldump 一把梭就完事了。结果导出的 SQL 文件 1.2G,导入新库跑了一整晚还没跑完。CPU 直接拉满,业务方第二天一早就来催了。
后来换了金仓 KES 的迁移工具,同样的数据量,几分钟就搞定了。当时还挺意外的。迁移过程中存储过程和触发器也一并带过去了,没有额外处理。踩完这个坑之后,我把主流的 MySQL 数据库迁移方案都研究了一遍。每种方案都有自己的适用场景,也有各自的坑。选错了方案,轻则浪费时间,重则数据出问题。今天把 4 种方案的优劣和踩坑经验整理出来,帮朋友们少走弯路。
一、mysqldump:基础但有天花板
mysqldump 是 MySQL 自带的导出工具。把表结构和数据导出成 SQL 文件,再到目标库执行导入。操作简单,几乎零门槛,大部分 DBA 学的第一个迁移工具就是它。
bash
# 导出单库
mysqldump -uroot -p --databases mydb > mydb.sql
# 导入
mysql -uroot -p < mydb.sql
数据量在百万以下、停机窗口充裕的场景下,mysqldump 足够用了。
问题出在数据量大的时候。 数据量超过百万后,导入速度断崖式下降。我那次两百万条数据,导出 5 分钟就跑完了,导入跑了一整晚。原因是 mysqldump 导出的 SQL 全是 INSERT 语句。一条一条往目标库写,效率很低。数据量越大,这个问题越明显。
想优化的话,导出时加 --single-transaction 保证一致性,加 --quick 减少内存占用。数据量大的话,可以用 mydumper/myloader 做并行导入,速度能提升好几倍。KES 的迁移工具 KDTS,底层采用 并行导出导入机制(类似 mydumper)比 mysqldump 快很多。
二、物理文件迁移:快但限制多
直接把 MySQL 的 datadir 数据目录打包复制到新服务器。速度确实快,但前提条件非常苛刻。
同版本 MySQL、同操作系统、同存储引擎,追求迁移速度的场景下可以用。
但限制也很明显。源和目标的 MySQL 版本、操作系统、文件系统必须高度兼容。跨版本基本不能用,InnoDB 数据文件格式可能不兼容。迁移期间必须停库,业务要完全停下来。而且操作风险高,复制过程中文件损坏就会丢数据。
这个方案用得不多。除非是同机房换服务器,或者开发环境克隆这种场景。
三、主从复制:不停机但只能同库
利用 MySQL 自带的主从复制,让新库作为从库同步数据。追平后再切换主从角色。
bash
# 目标库配置为从库
CHANGE MASTER TO
MASTER_HOST='源库IP',
MASTER_USER='repl',
MASTER_PASSWORD='密码',
MASTER_AUTO_POSITION=1;
START SLAVE;
SHOW SLAVE STATUS\G
不允许长时间停机、数据量大、同版本迁移。满足这几个条件,主从复制是个不错的选择。
优势是不停机,短板是只能同库同版本。 触发器和存储过程不会自动同步,需要手动迁移。如果源库有大量触发器,迁移后很容易漏掉。如果目标是国产数据库,主从复制这条路就走不通了。
这就引出了第四种方案。
四、专业迁移工具:跨库场景的解法
前面三种方案各有短板。mysqldump 大数据量慢,物理文件不能跨版本,主从复制只能同版本同类型。
实际项目里,真正难的是这几类场景:
- 跨版本迁移:MySQL 5.6 到 8.0,SQL 语法有差异,字段类型有变化
- 跨库迁移:MySQL 到国产数据库,存储引擎和数据类型不兼容
- 不停机迁移:业务不能停,但又要保证数据一致性
- 混合场景:既要跨版本又要不停机,组合起来难度翻倍
这种场景下,金仓 KES 提供了一套完整的迁移工具链。覆盖了从全量迁移到实时增量同步的全流程。
KDTS 负责全量迁移。 底层用 mydumper 做并行导出导入,比 mysqldump 快很多。我开头说的那个案例,两百万数据跑了一整晚。换 KDTS 几分钟就搞定了。KES的完整方案是:KDTS做全量,KFS(Kingbase FlySync)做实时增量同步,前后接力,整个过程不需要停库,业务不受影响。
KFS 负责实时增量同步。 直接读 MySQL 的 Binlog,不做全表扫描,不加锁,对生产库几乎无影响。同步延迟稳定在秒级以内,日均可处理 4.5TB 增量数据。还支持双轨并行方案,迁移期间出了问题可以秒级回切到原库。之前我参与过一个百万级数据的迁移项目。用 KFS 做增量同步,最终切换只用了十几分钟,业务全程没断过。
实际操作分两步。先用 KDTS 做全量迁移,再启动 KFS 做增量同步追平差异。等两边数据一致了,选个业务低峰期做最终切换。
KES 对 MySQL 的兼容度比较高。存储过程、触发器、视图迁过去基本能直接运行。KES 还内置了兼容性评估工具KDMS。迁移前自动分析 SQL 语法和数据类型的兼容问题,生成评估报告。哪些语句能直接跑、哪些需要改写,报告里标得清清楚楚。提前发现问题,比迁移到一半报错强多了。
五、4种方案对比表
| 对比维度 | mysqldump | 物理文件 | 主从复制 | KES迁移工具 |
|---|---|---|---|---|
| 数据量适用 | 百万以下 | 不限 | 不限 | 不限 |
| 停机时间 | 长 | 长 | 短 | 短 |
| 跨版本支持 | 支持 | 不支持 | 不支持 | 支持 |
| 跨库支持 | 不支持 | 不支持 | 不支持 | 支持 |
| 操作难度 | 低 | 中 | 中 | 低(可视化) |
| 数据一致性 | 依赖停库 | 依赖停库 | 实时同步 | 实时同步 |
| 触发器/存储过程 | 自动导出 | 自动 | 需手动 | 自动迁移 |
| 回退能力 | 无 | 无 | 手动 | 双轨秒级回切 |
选方案没那么复杂。数据量小、停得起就用 mysqldump。不能停但同版本就用主从复制。涉及到跨版本或跨库,KDTS 加 KFS 的组合能把复杂度兜住。
六、选型决策框架
问题1:数据量多大?
→ 100万以下 → mysqldump 够用
→ 100万以上 → 往下看
问题2:能接受停机吗?
→ 能,有4小时以上窗口 → mysqldump 优化版(mydumper并行导入)
→ 不能 → 往下看
问题3:源和目标版本/类型一样吗?
→ 一样 → 主从复制
→ 不一样(跨版本/跨库) → KES迁移工具(KDTS+KFS)
七、避坑清单
迁移前这几点一定要确认,都是我踩过的坑:
1. binlog 格式必须是 ROW。 我第一次做主从复制,源库 binlog 格式是 STATEMENT。同步直接报错,改完重启才发现。白白浪费了两个小时。如果用 KFS 做增量同步,同样要求 binlog 是 ROW 格式。迁移前先确认一下。
2. 触发器不会自动跟过去。 mysqldump 可以带触发器,但主从复制不行。迁完不检查的话,有些业务逻辑就断了。迁移完记得手动检查:
sql
SELECT TRIGGER_SCHEMA, COUNT(*)
FROM information_schema.TRIGGERS
WHERE TRIGGER_SCHEMA NOT IN ('sys','mysql','information_schema')
GROUP BY TRIGGER_SCHEMA;
3. 字符集要对齐。 源库 utf8、目标库 utf8mb4,看起来兼容。实际迁移时,排序规则不同会导致索引失效。
4. 先在测试环境跑一遍。 别直接上生产。我有一次在生产库做 mysqldump,锁表时间太长,业务方打了三个电话。如果是跨库迁移到 KES,建议先用兼容性评估工具跑一遍。提前发现 SQL 语法和数据类型的问题。
5. 迁完一定要做数据校验。 不能只看表数量一样就完事。行数、主键范围、随机抽样比对,这三步至少做一步。我有一次迁移完觉得没问题。上线后才发现,有个时间字段精度丢了。排查了半天,最后发现是 DATETIME 和 TIMESTAMP 的默认行为不一样。
MySQL 数据库迁移没有一种方案能搞定所有场景。选哪个要看数据量、停机窗口和迁移距离。
不过有一点我可以确定。如果你的迁移目标是国产数据库,KES 的工具链是比较完整的。KDTS 负责全量迁移,KFS 负责实时增量同步,还有双轨回切换保底。前期做好兼容性评估,剩下的就是个体力活。
说到底,迁移这件事不怕工具不好用,就怕选错方案。选对了方案,半夜都能睡个好觉。
朋友们还遇到过哪些迁移的坑?欢迎在评论区分享 👋
我是数据库小学妹,咱们下篇见 👋