这事儿说起来挺逗的。前几天一个朋友半夜打电话给我,说他在公司写了个数据库,结果第二天要出差,想把 MySQL 搬到笔记本上继续搞。电话那头他急得不行,说“这数据库里几十张表,总不能手动重建吧”。我让他别慌,MySQL 迁移说白了就三个字:导出来,再导进去。但要是没摸过这路子,真的能卡你一整天。

先说说最笨的办法,也是很多人第一反应——把整个 MySQL 的 data 目录直接拷走。这种操作我见过不少人干过,结果要么是权限问题打不开,要么是版本不匹配报错。data 目录下存的是表的物理文件,比如 .ibd、.frm 等,但不同版本的文件格式可能有差异,而且拷贝时 MySQL 服务必须停掉,否则文件正在写,拷过去就会损坏。更坑的是,如果你用的 MySQL 版本不一样,比如从 5.7 拷到 8.0,基本就是自找麻烦。这招只适合同版本、同操作系统、并且记得停服务的情况,否则就是给自己挖坑。
靠谱的办法是用 mysqldump。它是 MySQL 自带的导出工具,能把整个库或指定表转成 SQL 脚本。操作很简单,命令行敲一句 ,然后输入密码,搞定。生成的 SQL 文件里全是建表和插入数据的语句,拿到新电脑上,用 导入就行。这个方法兼容性好,哪怕新电脑装的是不同小版本的 MySQL,只要主版本相近,基本都能跑。我有个朋友从 Windows 迁移到 Linux,也是这么干的,一路顺畅。
不过 mysqldump 也有坑。如果数据库很大,比如几十 GB,导出的 SQL 文件会很庞大,导入时可能卡半天。而且默认是一行一行插入,效率低。我见过有人导一个 10 GB 的库,等了两个小时还没完。这时可以加 参数,它会自动优化选项,比如合并插入语句,速度能快不少。但如果是上百 GB 的大库,mysqldump 就力不从心了,需要考虑别的方案。
大库怎么办?可以尝试物理备份。MySQL 有个工具叫 Percona XtraBackup,虽然是第三方开发的,但很多生产环境都在用。它直接拷贝物理文件,速度极快,而且不需要停服务。原理是先记录当前日志位置,然后拷贝数据文件,同时跟踪日志变化,最后应用日志保证一致性。操作比 mysqldump 复杂点,但效率高得多。比如 200 GB 的库,mysqldump 可能要导一天,用 XtraBackup 可能一两个小时就搞定。不过新手慎用,因为涉及不少命令行参数和权限设置,容易出错。建议先在小库上练手,再上大库。
还有一种情况是迁移到另一台电脑,但网络环境不同。比如公司内网是千兆,家里 Wi‑Fi 是百兆,迁移速度会受限于网络。这时可以压缩传输。用 mysqldump 导出时加管道,例如 ,文件可以压缩到原来的十分之一甚至更小。传到新电脑后再解压导入。我有个朋友从北京迁库到上海,走公网传输,压缩后原本 5 GB 的文件变成 500 MB,传输时间从半小时降到五分钟。但别忘了,压缩和解压都需要 CPU 算力,电脑配置低的话可能反而更慢。
迁移过程中最容易被忽略的是字符集问题。很多人导完数据后,发现中文变成乱码或问号。这大多是字符集不统一导致的。MySQL 早期默认字符集是 latin1,而大多数中文应用使用 utf8mb4。导出时要指定字符集,例如 ,导入时也要使用相同的字符集。新电脑上 MySQL 的配置文件(my.cnf 或 my.ini)里,最好把 和 也设成 utf8mb4,这样从根源上避免乱码。我见过一个案例,迁移后数据显示正常,但排序时中文顺序不对,原因是 collation 仍是 latin1swedishci,改成 utf8mb4unicodeci 就好了。
再说说迁移后的验证。很多人只看表结构和行数对得上就以为完事了,结果业务跑起来时发现存储过程报错或视图打不开。这往往是新旧环境细微差异导致的,比如 MySQL 版本不同导致某些函数行为变化,或者用户权限没有迁移。迁移完后要全面测试:连接数据库,跑几个关键查询,检查存储过程和触发器是否正常,再核对用户权限是否一致。如果有自动化测试脚本,跑一遍最稳妥。我一般会在旧库和新库上各执行一次相同的复杂查询,对比结果集是否完全一致,确保数据既没有丢失也没有错误。
提醒一句,别指望一次就搞定。数据库迁移理论上很简单,实际操作往往差着一个银河系。我见过最离谱的案例,有人把生产库迁到新服务器,忘了停旧库的写入,导致数据不一致,只能回滚。所以一定要先做好备份,再迁移,迁移后对比确认无误后再切换。如果在公司做迁移,最好选在凌晨业务量小的时段操作,留足缓冲时间。别像我那个朋友一样,半夜打电话求助,结果折腾到天亮。


