myloader --resume 是唯一可落地的离线断点续传方案,依赖 mydumper 的独立表文件与 metadata 快照位点,但仅判断表非空即跳过,不校验数据完整性,需人工比行数、验 checksum、查位点兜底。

myloader --resume 是唯一能落地的离线断点方案
MySQL 离线迁移本身不走网络连接,所谓“中断”其实是终端断开、SSH 挂掉或本地磁盘 I/O 故障,不是 MySQL 自身断连。只有 mydumper + myloader 这套组合支持真正可操作的断点续传,因为 mydumper 会为每张表生成独立的 .sql 文件,并附带 metadata 记录快照位点;myloader --resume 才有依据跳过已导入的非空表。
关键前提必须满足:
-
mydumper导出时加--snapshot(默认开启)和--trx-consistency-only,确保所有表基于同一事务快照 - 目标库必须提前建好同名数据库,但不能手动建表——否则
myloader无法判断是否该跳过 - 导出路径下必须保留完整的
metadata文件,里面含SHOW MASTER STATUS的File和Position - 中断后重试必须用
myloader --resume,不能换命令或删表重跑
中断后怎么准确定位卡在哪张表
别靠日志猜,直接比行数。中断发生后,先在源库执行 FLUSH TABLES WITH READ LOCK 冻结写入,再用两组命令对比:
查目标库各表当前行数:ls /backup/db1/*.sql | sed 's/\.sql$//' | xargs -I{} mysql -h dst -Nse "SELECT COUNT(*) FROM db1.{}"
查源库对应行数:SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema = 'db1' ORDER BY table_name
常见三种情况及应对:
- 某张表在目标库
COUNT(*)非零但SELECT * FROM t1 LIMIT 1报ERROR 2013:说明t1.sql截断,数据不完整,必须删表重导 - 目标库该表
COUNT(*)为 0:安全,--resume会正常执行 - 目标库该表存在且行数明显少于源库,但
myloader日志显示Skipping table t1 (non-empty):最危险,--resume误判了,必须删表重导
文件损坏时 --resume 完全无感知
myloader --resume 只检查表是否存在且 information_schema.tables.table_rows > 0,它不管 SQL 文件是否损坏。如果 db1/t1.sql 因磁盘坏道导出不全(比如最后一条 INSERT 缺少右括号),myloader 仍会跳过这张表,导致目标数据永久残缺。
人工补位必须做:
- 每次导出完成后,用
sha256sum /backup/db1/*.sql留存校验值 - 中断恢复前,先
head -n 100 /backup/db1/t1.sql和tail -n 100 /backup/db1/t1.sql看语法是否完整 - 对大表启用
--chunk-filesize=64,避免单文件过大增加损坏风险 - 别依赖
--resume做完整性保障,它只解决“是否执行过”,不解决“是否执行对”
跨库同步中断必须盯工具记录的位点,不是 SHOW MASTER STATUS
跨库迁移(如 RDS → 自建库、MySQL → Kafka → MySQL)中断后,SHOW MASTER STATUS 或 SHOW SLAVE STATUS 查到的位点根本不能用——那是源库或目标库自己的位置,和迁移任务无关。真正有效的断点是迁移工具自己记录的源库位点,比如 binlog_file 和 binlog_position,必须从 checkpoint 表、ZooKeeper 节点或 Kafka offset 里取。
容易被忽略的细节:
- 目标表必须有稳定、全覆盖的唯一键(不能只靠自增
id),否则INSERT ... ON DUPLICATE KEY UPDATE会漏更新 - 源库
binlog_format必须为ROW,binlog_row_image=FULL必须开,否则 UPDATE 缺少旧值,目标端无法做对比 - GTID 场景下,两边
gtid_mode、server_uuid、gtid_purged必须严格一致,否则CHANGE MASTER TO直接失败 - 每次批量写入后统一刷一次 checkpoint,别每条都写,否则吞吐暴跌
断点续传最难的不是技术实现,而是接受它本质上是个“有损机制”:--resume 不校验数据、不感知损坏、不保证幂等。所有可靠性都得靠人工兜底——比行数、验 checksum、查位点、留日志。指望自动续传不出错,等于把数据库当玩具。


















