MySQL里的数据迁移与同步,本质上是在不同实例或集群之间搬运已有数据,并让变更持续保持一致。迁移通常关注一次性把存量搬到目标端,同步则强调源端后续写入能实时或准实时反映到目标端。实际项目中两者经常组合使用:先用迁移把底色铺好,再用同步追平切换前的增量。

一、基于逻辑导出的迁移方案
逻辑导出是最直观的迁移方式,核心是把库表结构和高低层数据生成SQL文本,再到目标库回放。MySQL自带的mysqldump就能完成这件事,它通过查询系统表拿到建表语句,再逐行拼出INSERT。这种方式的优点是可读、可编辑、跨版本兼容好,缺点是在大表上会长时间持锁或占用缓冲池。
下面是一段典型的dump与导入命令,注意我们在导出时加了单事务参数,避免对InnoDB表加全局锁:
# 导出单个库,使用单事务保证一致性 mysqldump -h 127.0.0.1 -u root -p --single-transaction --routines --triggers mydb > mydb.sql # 在目标实例导入 mysql -h 192.168.0.1 -u root -p mydb < mydb.sql
如果数据量到了百GB级别,mysqldump单线程会成为瓶颈。此时可以换用mydumper与myloader,它们支持按表多线程导出,并且输出文件分片,方便并行恢复。需要注意的是,多线程导出虽快,但一致性快照仍依赖事务隔离,对MyISAM这类不支持事务的引擎要额外停写。
逻辑导出的另一个隐性成本是字符集与触发器。源端若使用utf8mb4而目标端是老utf8,导入后表情符会报错。建议在导入前用SHOW CREATE DATABASE核对,并在连接串显式指定字符集,避免依赖服务端默认。
二、基于binlog的同步机制
MySQL主从复制是同步能力的基石,它依赖二进制日志binlog记录所有数据变更。源端把binlog推给从库,从库重放事件达到一致。这种机制不关心表有多大,只追增量,因此非常适合割接前的长周期对齐。
配置主从时,源端要开启log_bin并设唯一server_id,从端通过CHANGE MASTER TO指向源端位点。下面是一段最小可用的从库配置示例:
-- 在从库执行,指向主库 CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='repl', MASTER_PASSWORD='repl_pass', MASTER_LOG_FILE='mysql-bin.000012', MASTER_LOG_POS=154; START SLAVE; -- 查看同步状态 SHOW SLAVE STATUSG
原生复制要求目标也是MySQL且版本兼容,若要把数据同步到异构系统,比如消息队列或另一个数据库,就需要解析binlog的客户端。Canal是常用开源方案,它伪装成从库向源端拉取binlog,再把行变更转成JSON投递。这样业务可以消费变更做缓存失效或搜索索引更新。
使用binlog同步要警惕环状复制与断点续传。一旦从库误写又回传主库,会造成数据回旋覆盖。生产环境应设read_only与super_read_only,并且监控Seconds_Behind_Master指标,延迟突增往往意味着大事务或网络抖动。
三、迁移与同步的组合实践
真实割接很少只用一种手段。常见做法是:白天用mydumper把存量导到新实例,同时部署Canal监听源端binlog;存量导入完成后,比对两边行数,再让Canal把导出期间的增量补录;最后在业务低峰停写源端,确认目标端追平后切换流量。
这种组合能实现分钟级停机,但对一致性校验要求高。可以借助pt-table-checksum定期比对新老表,发现差异再用pt-table-sync修复。下面给出校验调用示例:
# 在主库执行,对mydb下所有表做分块校验 pt-table-checksum --host=127.0.0.1 --user=root --password=xxx --databases=mydb # 发现不一致后,在修复节点执行同步 pt-table-sync --host=192.168.0.1 --user=root --password=xxx --databases=mydb --execute
如果业务允许短暂只读,也可以反向操作:先建主从,等延迟为零后把应用读流量切到从库,再断开复制提升从库为主。这种方案不需要额外同步组件,但要求应用层能区分读写数据源。
四、方案选型与避坑要点
选迁移同步方案时,先问三个问题:数据量多大、能接受多长停机、目标端是否同构。十GB内同构库,mysqldump加停写最省心;TB级跨城,必须binlog类方案;若目标不是MySQL,只能走CDC工具解析binlog写适配层。
容易踩的坑包括:忽略自增主键偏移导致切换后主键冲突,应在导入前用ALTER TABLE调整AUTO_INCREMENT;大事务让从库回放卡死,建议业务侧拆批;还有时区问题,源端用SYSTEM时区而容器目标端是UTC,时间字段会偏移,需在配置显式设time_zone。
最后提醒,无论哪种技术,割接前必须做回滚演练。把目标端数据反向同步回备用源,验证可还原,才能在生产按下切换键。技术本身成熟,真正决定平稳的是流程与校验是否到位。