myloader恢复慢的主因是默认仅4线程且不自动适配CPU核数,需手动设置--threads;同时须配合--queries-per-transaction调优、避免大表分片锁冲突,并确保目标库schema预先建好。

myloader 默认只用4个线程,不显式指定 --threads 就没法真正发挥多核优势——这是恢复慢的最常见原因。
必须显式设置 --threads 参数
myloader 不会自动根据 CPU 核数调整并发数,--threads 必须手动传入,否则始终使用默认值 4:
- 低于 4 核机器:设为
--threads=2或--threads=4即可 - 8 核以上服务器:建议从
--threads=8起步,再观察 I/O 和 CPU 利用率 - SSD + 高配机器(如 16 核/64GB):可试
--threads=12~16,但超过 16 容易触发连接数或锁竞争瓶颈 - 不要盲目堆线程:线程数翻倍 ≠ 速度翻倍;实测在机械盘上超过 8 线程后吞吐常不升反降
--threads 和 --queries-per-transaction 要配合调
单个事务包太小,会导致 COMMIT 过于频繁,刷盘压力大;太大则内存占用高、回滚代价重。二者需协同:
-
--queries-per-transaction=10000是较稳妥的起点(对应约 1–5MB 数据量) - 线程数提高时,可同步把
--queries-per-transaction提到20000~50000,减少事务开销占比 - 若遇到
ERROR 1205 (HY000): Deadlock found when trying to get lock,说明事务粒度太大,要回调该值 - 注意:该参数只影响数据导入阶段,schema 文件(
*-schema.sql)仍按单文件单事务执行
避免线程争抢同一张表或索引资源
myloader 按文件粒度分发任务,但若备份中某张大表被拆成多个 *.sql 分片(比如用了 mydumper -r 1000000),这些分片可能被不同线程并发写入同一张表,引发行锁或自增锁冲突:
- 恢复前确认备份是否含分片:
ls -l /backup/dbname/*.sql | head -10,看是否有tbname.00001.sql类命名 - 若有分片,建议加
--enable-binlog(即-e)并确保innodb_autoinc_lock_mode=2(交错模式),否则自增主键易卡住 - 更彻底的解法:对超大表单独导出(
mydumper -T big_table),再用单线程mysql导入,避开 myloader 的并发调度逻辑 - 别忽略
innodb_buffer_pool_size:线程数上去后,若 buffer pool 不足,会大量读磁盘,反而拖垮整体速度
目标库未预建 schema 会强制串行化
myloader 只有在目标库已存在、且表结构已建好时,才能真正并行导入数据。否则它会先串行执行所有 *-schema.sql,再启动 worker 线程:
- 执行前务必手动创建空库:
mysql -e "CREATE DATABASE IF NOT EXISTS target_db CHARACTER SET utf8mb4" - 如果用
-s db_name指定源库名,但目标库名不同(如-B new_db),myloader 不会自动建库,必须提前建好 - 若误删过目标库又重跑 myloader,它不会报错,而是静默跳过建表步骤——此时你看到的是“成功”,但实际只有部分表被重建
- 验证方式:
mysql -D target_db -e "SHOW TABLES" | wc -l对比备份目录里*-schema.sql文件数
真正卡住并发度的,往往不是线程数本身,而是 schema 是否就位、事务粒度是否匹配硬件、以及大表分片是否引发锁冲突——这些细节不处理,开再多线程也只是在排队等锁。


















