mydumper 能显著缓解千万级表导出慢的问题,但必须显式启用分片和调优线程,否则默认仍是单线程全表扫描;常见错误是只加-j控制多表并发却漏-t,而-t才决定单表并行读取,且需配合--rows或--chunk-filesize及主键/唯一索引才能生效。

mydumper 能显著缓解千万级表导出慢的问题,但必须显式启用分片和调优线程,否则它默认仍是单线程全表扫描。
为什么加了 -t 还是慢?
常见错误是只加了 -j(控制并发导出多少张表),却漏掉真正决定单表速度的 -t 参数。不加 -t,哪怕表有千万行,mydumper 也只会用 1 个线程顺序读取整张表。
-
-t 4表示对当前大表按主键或唯一索引切分成 4 段,并行 SELECT —— 但前提是表必须有主键或唯一非空索引,否则-t直接被忽略 - 必须配合
--rows=500000或--chunk-filesize=256使用,否则-t不生效 - 若表无主键,可先建临时主键(
ALTER TABLE t ADD COLUMN id_tmp BIGINT AUTO_INCREMENT FIRST, ADD PRIMARY KEY(id_tmp)),导出完再删
导出中途失败,怎么补而不是重来?
mydumper 不支持断点续传,但输出结构清晰,适合手动补缺。关键看 db.table.00001.sql 这类命名规律:序号代表分片编号,缺失哪个就补哪个。
- 失败后查日志末尾的
Thread X failed,再进--outputdir目录执行ls db.table.*.sql | wc -l,对比预期分片数(如--rows=500000对应 20 片,却只生成 18 个文件) - 补单张表:加
--regex='^db\.table$' --overwrite-tables重跑 - 只缺某几个分片:用
--where="id > 5000000 AND id 手动切片导出,注意引号转义 - 千万别删整个目录重跑——mydumper 不校验已有文件,会生成
.00001.00001.sql这类冲突名
线程数和分片粒度怎么设才不翻车?
盲目拉高 --threads 或把 --rows 设太小,反而让 IO 拥塞、inode 耗尽、导入变卡。核心是匹配硬件能力,而非堆参数。
- SSD/NVMe 磁盘:从
--threads=8起步,上限一般不超过 12;机械盘别超--threads=4 - 分片优先用
--rows=100000~500000,比--chunk-filesize更稳定(后者受字段长度和字符集影响大) - 导出目录 inode 快爆了?立刻
df -i查,超 90% 时rm -f旧 dump 目录比调参更有效 - 加
--skip-tz-utc省掉每次连接都执行SET TIME_ZONE的开销,实测快 5%~10%
最容易被忽略的是权限和一致性配置:缺 LOCK TABLES 权限会导致静默跳过表;没加 --no-locks --no-binlog 就在 GTID 环境下跑,可能破坏主从同步。这些细节不提前检查,跑半天才发现导出不全,比慢更致命。


















