MySQL数据库迁移方案怎么选?4种方案对比+大数据量迁移避坑实战

大家好,我是数据库小学妹 👋

上个月帮一个客户做服务器迁移,数据库大概两百万条数据。当时觉得 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 负责实时增量同步,还有双轨回切换保底。前期做好兼容性评估,剩下的就是个体力活。

说到底,迁移这件事不怕工具不好用,就怕选错方案。选对了方案,半夜都能睡个好觉。

朋友们还遇到过哪些迁移的坑?欢迎在评论区分享 👋

我是数据库小学妹,咱们下篇见 👋