myloader --resume 是跨云离线迁移唯一可落地的断点方案,依赖 mydumper 表级 sql 文件与 metadata 快照位点实现续传,但需人工校验位点、行数及文件完整性,不自动感知网络中断或文件损坏。

myloader --resume 是跨云离线迁移唯一能落地的断点方案
跨云厂商(如从阿里云 RDS 迁到 AWS RDS)做离线迁移时,网络中断不是问题根源——真正崩掉的是 SSH 会话、跳转机磁盘满、或目标云服务器临时限流。只有 mydumper + myloader --resume 能靠表级文件切分和 metadata 位点实现可验证续传;mysqldump 管道导入失败就得重来,没有中间态。
关键前提必须满足:
-
mydumper导出时加--snapshot(默认开启)和--trx-consistency-only,确保所有表文件基于同一 binlog 位点 - 导出目录里必须存在
metadata文件,内容含mysql-bin.000042\t123456789这类快照锚点 - 目标库提前建库,但**严禁手动建表**——
myloader需要自己判断建表+跳过逻辑 - 目标库字符集、排序规则、SQL mode 必须与源库一致,否则
myloader解析 SQL 文件时直接报错退出,不写日志
中断后怎么准确定位哪张表卡住了
别靠日志猜,也别查 myloader 最后输出的表名——它可能刚打印完“Importing t1”,实际只执行了前 3 行 INSERT 就挂了。真实断点只能靠行数比对。
中断发生后,立刻在源库执行:
SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema = 'db1' ORDER BY table_name;
再在目标库执行(假设备份文件在 /backup/db1/):
ls /backup/db1/*.sql | sed 's/\.sql$//' | xargs -I{} mysql -h dst -Nse "SELECT COUNT(*) FROM db1.{}"
两列对比,出现以下情况即为断点:
- 目标库某表
COUNT(*)为 0 →myloader还没开始导入,下次加--resume会正常执行 - 目标库该表非空但行数远少于源库,且
myloader日志里有Skipping table t1 (non-empty)→ 危险!说明文件截断但表已建好,必须DROP TABLE t1后重试 - 目标库该表
COUNT(*) > 0但SELECT * FROM t1 LIMIT 1报ERROR 2013→ SQL 文件末尾损坏(如缺右括号),--resume会跳过,数据永久残缺
跨云场景下 metadata 位点必须人工校验
myloader --resume 只检查表是否存在且非空,**完全不读 metadata 里的 binlog 位点**。这意味着:如果源库在导出后又写了新 binlog,而你用旧备份续传,目标库就少了这部分变更——但 myloader 不报错、不警告。
所以每次重试前,必须人工核对:
- 打开
/backup/db1/metadata,记下mysql-bin.000042\t123456789 - 登录源库(或原 RDS 控制台),查历史 binlog 位置:
SHOW BINLOG EVENTS IN 'mysql-bin.000042' FROM 123456789 LIMIT 1 - 确认该位点之后的事务是否已通过其他方式同步(比如你在导出后开了 DTS 增量)
云厂商 RDS 通常禁用 SHOW MASTER STATUS,得用控制台「日志管理」页查 binlog 文件列表和起始位置,再换算偏移量。
文件损坏时 --resume 会静默跳过残缺数据
这是最隐蔽的坑:myloader --resume 对 SQL 文件损坏毫无感知。只要目标表非空,它就跳过——哪怕 db1/t1.sql 因云对象存储下载中断,最后一条 INSERT 缺少逗号或右括号,myloader 仍会跳过,导致目标数据永远少一行或多字段 NULL。
预防手段只有两个:
- 导出时加
--chunk-filesize=32(单位 MB),避免单文件过大增加损坏概率 - 传输后、导入前,用
sha256sum校验每个.sql文件的哈希值,比对源端备份目录的 checksum 列表
跨云迁移没有“绝对可靠”的断点机制,--resume 的本质是“跳过已建且非空的表”,不是“恢复到中断那一刻”。真正的数据完整性,得靠人工比对行数 + checksum + 关键业务记录抽样。











