MySQL迁移从来不是简单的dump加restore,真正决定成败的是迁移前对风险的识别深度。不同版本、不同存储引擎以及周边中间件都会引入隐性兼容问题,只有按步骤量化评估,才能给出可执行的迁移窗口和兜底方案。

一、梳理现有实例拓扑与依赖
风险评估的第一步是画清当前数据库的真实拓扑。很多团队只记录了主库地址,却忽略了从库、延迟从库、binlog订阅服务以及报表只读实例。任何一个未被登记的消费者,都会在迁移后因为连接失效引发上游报警。
建议使用information_schema和performance_schema做一次全量元数据采集,列出所有非系统库、用户权限以及外部IP白名单。下面这段SQL可以辅助找出活跃连接来源:
SELECT SUBSTRING_INDEX(HOST, ':', 1) AS client_ip, COUNT(*) AS conn_count, MAX(DB) AS used_db FROM information_schema.PROCESSLIST WHERE USER <> 'system_user' GROUP BY client_ip ORDER BY conn_count DESC;
拿到清单后,要和业务方逐一确认每个IP对应的服务模块。曾经有团队漏掉一个老旧的定时报表脚本,迁移后该脚本持续重连失败,最终导致看门狗重启了应用容器。拓扑梳理的价值就是把“不知道有谁在用”变成“明确每一个调用方”。
二、兼容性扫描与对象差异分析
当目标实例版本高于或低于源端时,必须做兼容性扫描。MySQL 5.7到8.0的迁移中,废弃的ONLY_FULL_GROUP_BY默认值、新增的caching_sha2_password认证插件都会直接阻断应用连接。
可以借助mysqldump的--no-data参数导出结构,再在目标库执行dry run式导入,捕获报错。常见风险点包括:使用了目标版本不支持的语法、表定义中指定了不存在的字符集、以及视图里引用了已删除的系统函数。
-- 导出结构但不导出数据 mysqldump -h 127.0.0.1 -u root -p --no-data --routines --events source_db > struct.sql -- 在目标库模拟导入并观察错误 mysql -h 192.168.0.1 -u root -p target_db < struct.sql
对于存储过程和触发器,要额外检查主体内是否硬编码了绝对路径或特定主机名。某次迁移中,一个触发器调用了sys_exec向本地写日志,目标容器没有对应权限,导致所有写入事务回滚。把这类对象列为高风险项,要么改造要么弃用。
三、建立压测基准与容量评估
只验证功能不够,目标实例的吞吐能力必须提前摸底。利用sysbench或业务录制回放工具,在目标环境跑出QPS、TPS和P99延迟基线,再与源端生产指标对比。
如果目标端使用了云托管MySQL,要注意参数模板差异。比如innodb_buffer_pool_size默认只占实例内存的半数,而自建库往往调到百分之七十五以上,这种隐性配置会让压测结果虚低。
sysbench oltp_read_write --db-driver=mysql --mysql-host=192.168.0.1 --mysql-user=root --mysql-password=pass --tables=10 --table-size=100000 --threads=64 --time=300 run
压测时同步记录磁盘IO等待和复制线程延迟。若发现目标端在同等并发下IO利用率逼近百分百,说明底层云盘性能不匹配,需要升级规格或调整redo日志策略,否则迁移后高峰时段会出现雪崩。
四、增量同步与数据一致性校验
全量迁移完成后,通常通过Canal或MySQL原生复制搭建增量通道。风险评估的重点在于:增量延迟是否可控,以及全量加增量后的数据是否真正一致。
采用pt-table-checksum对核心表做分块校验,它能算出每块数据的CRC值并在两端比对。发现不一致时,用pt-table-sync生成修复语句,但修复前必须业务确认,避免覆盖新写入。
pt-table-checksum --host=127.0.0.1 --user=root --password=pass --databases=order_db --tables=orders,order_item --recursion-method=hosts
校验不能只做一次。建议在停写前每隔六小时跑一轮,观察差异块是否收敛。如果某张表持续出现新差异,往往意味着存在未被迁移工具捕获的旁路写入,例如直接连从库改数据的运维操作,这类隐患要在切流前彻底堵住。
五、回滚预案与切换演练
所有评估的终点是:出问题能不能回去。回滚不是简单把流量指回老库,因为新库可能已经写入了业务数据,直接切回会造成新数据丢失。
正确做法是保留老库为只读影子库,迁移期间双向同步。切换后若发现严重故障,先暂停新库写入,将新库增量回流老库,再切流量。演练时要真实模拟一次回流,验证工具在千万级数据下的耗时。
-- 切换前将老库设为只读,防止演练污染 SET GLOBAL read_only = ON; -- 确认无活跃写事务 SELECT COUNT(*) FROM information_schema.INNODB_TRX WHERE trx_state='RUNNING';
演练报告要写明预估回滚时间、数据丢失窗口和责任人矩阵。当这些数字都经过实测而非估算,MySQL迁移的风险才真正从“未知”变为“可管理”。