说到 MySQL 数据库迁移,我这些年没少踩坑。零停机迁移听起来挺高大上,其实就是个“边动手术边让病人活着”的活儿。但这事儿真不简单,尤其是当你面对几百 GB 甚至上 TB 的数据,用户还在线刷订单、发消息,稍有不慎就是几十分钟的停机,老板能把你拉去祭天。

先说说迁移前的准备工作。很多人一上来就想着“直接拷贝数据库文件”,那叫莽夫行为。你得先摸清家底:业务高峰期在哪段时间,数据量多大,表结构有没有外键依赖,主从复制是否已配置。我习惯在迁移前一周就开始监控慢查询、锁等待和连接数,看看有没有异常。顺便说一句,别信什么“全量导出再导入”的傻瓜式方案,那是给小型网站用的。真正的零停机迁移,核心思路是“数据同步 + 增量追赶 + 秒级切换”。你得先搭建一套目标数据库环境,版本尽量保持一致,字符集、存储引擎、时区这些细节都要对齐。我见过有人把 utf8mb4 导进 utf8mb3,结果 emoji 全变问号,用户骂了三天。
接下来就是数据全量同步。这里推荐用 MySQL 自带的 mysqldump 加上 --master-data 参数,或者用 Percona 的 XtraBackup 做热备份。前者适合数据量在几十 GB 以内的场景,后者适合几百 GB 甚至上 TB 的大库。XtraBackup 可以做到不锁表,但要注意,它拷贝的是物理文件,恢复时也需要目标库的硬件配置和 MySQL 版本一致。我踩过最大的坑是源库是 MySQL 5.7,目标库是 8.0,结果 XtraBackup 版本不匹配,恢复时直接报错。所以建议先在测试环境跑一遍,验证全量同步的耗时和正确性。全量同步完成后,别急着切换,这时候源库和目标库的数据还差着几十分钟甚至更久的变化呢。
增量同步才是零停机的关键。全量数据过去之后,你得让源库的 binlog 持续不断地同步到目标库。这里常用的工具是 MySQL 的主从复制,或者 Canal、Debezium 这类开源工具。我倾向于用原生主从,稳定、可控,但要注意几点:源库必须开启 binlog,格式设为 ROW,且保留天数要足够长;目标库的 server-id 不能和源库冲突;同步过程中要监控 SecondsBehindMaster,追不上就说明网络带宽或目标库性能有问题。有一次我迁移一个电商库,增量同步时目标库的磁盘 IO 跑满,延迟飙到十几分钟,只能临时扩容。记住,增量同步期间,源库的写入压力不能太大,否则追平时间会无限拉长。
等到增量同步的延迟基本归零,就到了切换前的最后一步——验证数据一致性。千万别直接切,翻车案例多得是。我习惯用 pt-table-checksum 对整个库做一次校验,找出哪些表的数据不一致。这个工具会计算每张表的 checksum,然后比对源库和目标库,结果一目了然。如果有不一致,大概率是表结构有差异(比如自增主键、唯一索引)、字符集转换问题,或者 truncate 表后 binlog 没正确同步。修复方法很简单:对不一致的表单独再做一次同步,或者直接重新做一次全量 + 增量。虽然麻烦,但能救你命。我见过有人跳过这一步,结果切过去发现用户订单状态全乱了,回滚花了半小时,直接背了 P0 事故。
切换操作本身要快准狠。选业务低峰期,比如凌晨两三点,先停掉源库的写操作(关闭应用层写入、设置数据库只读),然后等增量同步追上几秒的 binlog,确认延迟为 0 后,把应用层的连接池配置切到目标库。这里有个细节:如果用的是读写分离,记得把读库也一并切换,否则会出现数据不一致。切换完成后,先让一小部分流量(比如内部测试账号)走新库,观察几分钟,确认无异常再放全量。别一次性全切,万一目标库性能扛不住,你连回滚的机会都没有。我习惯在切换前写好回滚脚本,万一有问题,30 秒内切回源库。
切换完成后,别急着关掉老库。至少观察一周,确保目标库稳定运行。期间要重点监控:慢查询是否增多、连接池是否够用、IO 和 CPU 负载是否正常。有时候目标库硬件配置比源库好,但参数没调优,反而性能更差。比如 innodbbufferpoolsize 要设为物理内存的 70% 左右,maxconnections 要根据业务峰值调整。另外,别忘了修改 DNS 解析或负载均衡器的配置,把老的数据库连接彻底干掉。我见过有人切完一周才发现,有个定时任务还在连老库,数据写了两份,查了半天才定位到。
说个容易被忽略的点:迁移后的验证。很多人以为数据能查、业务能跑就完事了,但零停机的核心是“用户无感知”。你得检查:历史数据是否完整(比如三年前的订单)、定时报表是否正常生成、后台管理系统的统计数字是否准确。我有一个习惯,迁移完成后写个脚本对比源库和目标库的行数、主键最大值、最近一周的数据分布,确保万无一失。如果发现异常,立刻回滚,别犹豫。零停机迁移不是一锤子买卖,它考验的是你对系统细节的把控、对风险的预判以及快速响应的能力。说白了,就是用技术经验换业务稳定。


