
mydumper 为什么比 mysqldump 快得多
因为 mydumper 默认按表并行导出,还能拆分大表为多个 chunk(基于主键或唯一索引),每个 chunk 单独成文件、独立线程处理;而 mysqldump 是单线程全表扫描,锁表时间长、IO 和 CPU 都没法压满。
关键点在于:它不依赖 MySQL 的逻辑复制或 binlog,而是直接走 SELECT + 一致性快照(靠 FLUSH TABLES WITH READ LOCK 或 --no-locks + --use-savepoints 组合),所以对线上读写影响小得多。
- 导出时默认启用
--threads=4,可手动调到--threads=8或更高,但别超过数据库 CPU 核数的 1.5 倍,否则争抢严重 - 大表必须加
--chunk-filesize=64(单位 MB),否则单个 SQL 文件过大,myloader导入时容易 OOM 或卡住 - 跳过系统库要显式写
--regex='^(?!(mysql|sys|information_schema|performance_schema))',光靠--skip-triggers不管用
myloader 导入失败常见报错和对应解法
最常卡在 ERROR 1062 (23000) at line X: Duplicate entry '...' for key 'PRIMARY' —— 这不是数据重复,而是 myloader 并行导入时,多个线程同时 INSERT 同一张表的不同 chunk,触发了自增主键冲突或唯一约束竞争。
根本原因:目标库表结构里没关 AUTO_INCREMENT 或没清空自增计数器;或者源库导出时没带 --no-schemas,导致建表语句里的 AUTO_INCREMENT=xxx 被原样执行,覆盖了实际数据最大值。
- 导入前先清空目标库:用
myloader --drop-if-exists,别手写DROP DATABASE再CREATE,会丢掉字符集/排序规则 - 确保导出时加了
--no-create-info(如果只导数据)或--no-schemas(如果已有结构),避免建表语句干扰自增起点 - 导入时强制指定线程数:
myloader --threads=8 --database=testdb,别依赖默认值;线程数高于表数量时,空闲线程不干活,但不会报错
跨版本迁移时 mydumper/myloader 的兼容性雷区
mydumper 本身不校验 MySQL 版本,但它生成的 metadata 文件(metadata)里记录了 Started dump at: 和 Finished dump at: 时间戳,以及 SHOW MASTER STATUS 输出。如果源是 MySQL 8.0+,而目标是 5.7,myloader 会尝试还原 GTID 信息,直接报错 ERROR 1840 (HY000)。
更隐蔽的问题是:MySQL 8.0 默认用 caching_sha2_password 认证插件,而旧版 myloader(v0.9.5 之前)不支持该协议,连接目标库时静默失败,日志只显示 “Connected to MySQL server” 然后卡住。
- 导出端 MySQL 8.0+,务必加
--no-binlogs和--no-gtids,彻底绕过复制相关字段 - 确认
myloader版本 ≥ v0.10.0(GitHub release 页面查),低于此版本无法连 MySQL 8.0+ 的新认证方式 - 目标库若为 5.7,建库时显式指定
CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci会失败,得降级用utf8mb4_unicode_ci
如何验证搬迁后数据完全一致
别信“没报错就是成功”。mydumper 的 chunk 拆分基于查询,如果某张表没主键/唯一索引,它会退化成全表一个 chunk,且不警告;而 myloader 对空 chunk 文件静默跳过,不会报错也不会提示。
最轻量可靠的验证方式,是比对每张表的 CHECKSUM TABLE 结果 —— 但注意:MySQL 5.7 开始 CHECKSUM TABLE 默认用哈希算法,不同版本或不同页大小下结果可能不一致;所以必须统一在目标库上跑。
- 导出前,在源库执行:
SELECT CONCAT('CHECKSUM TABLE ', table_schema, '.', table_name, ';') FROM information_schema.tables WHERE table_schema NOT IN ('mysql','sys','information_schema','performance_schema');,生成所有校验语句 - 导入完成后,在目标库批量执行这些语句,把结果导出为 CSV,用
diff对比源库同一批结果(注意去掉时间戳和行号) - 如果表太多,可用
pt-table-checksum替代,但它要求主从环境或至少能连通两端,不如纯 SQL 方案直接
真正容易被忽略的是:mydumper 默认不导 event、function、procedure,除非加 --triggers --routines --events;这些对象缺失不会中断流程,但业务可能突然报错找不到存储过程。










