MySQL Shell的util.loadDump()开启32线程可将导入速度从几MB/s提升至200MB/s+,但需前置执行SET sql_log_bin=OFF和ALTER INSTANCE DISABLE INNODB REDO_LOG(仅8.0.21+支持),否则redo与binlog刷盘成为硬瓶颈。

MySQL Shell 的 util.loadDump() 默认是单线程导入,但只要满足条件,开 32 个线程完全可行,实际吞吐能从几 MB/s 提升到 200MB/s+ —— 关键不在“能不能开多线程”,而在是否关掉了 InnoDB Redo Log 和二进制日志。
为什么开多线程后速度没变?
常见现象:加了 { threads: 32 } 参数,但导入速率和单线程几乎一样,CPU/IO 利用率也不高。
根本原因不是线程没起作用,而是 InnoDB Redo Log 和 binary log 成了硬瓶颈。每条 INSERT 都要写 redo、刷盘、再写 binlog,线程再多也得排队等落盘。
- MySQL Shell
loadDump()默认不关 redo log,也不会自动关 binlog(即使设置了skipBinlog: true,它只跳过 binlog 记录,不关写入逻辑) - Redo Log 在 MySQL 8.0.21+ 才支持运行时禁用,低版本无法生效
- 如果目标实例是 5.7 或未启用
innodb_redo_log_capacity相关配置,ALTER INSTANCE DISABLE INNODB REDO_LOG会直接报错
必须手动执行的两步前置操作
在调用 util.loadDump() 前,需在目标 MySQL 实例中依次执行:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 关闭二进制日志:
SET sql_log_bin = OFF;(注意:该语句需在目标库连接下执行,且用户要有SUPER或SYSTEM_VARIABLES_ADMIN权限) - 禁用 InnoDB Redo Log(仅限 MySQL 8.0.21+):
ALTER INSTANCE DISABLE INNODB REDO_LOG;(执行后需确认状态:SELECT * FROM performance_schema.innodb_redo_log_files;中state应为DISABLED)
这两步缺一不可。只关 binlog,redo 仍强制刷盘;只关 redo,binlog 的 fsync 也会拖慢整体写入节奏。
util.loadDump() 的关键参数取舍
线程数不是越多越好,需结合磁盘随机写能力与表结构复杂度权衡:
-
threads:建议设为磁盘并发写能力的 2–4 倍。例如 NVMe SSD 随机写 1GB/s,可设threads: 16~32;如果是 SATA SSD(~200MB/s),threads: 8更稳 -
deferTableIndexes:设为'all'能跳过二级索引构建,导入后再建,提速明显;但主键和唯一约束仍会在导入时校验,无法跳过 -
showProgress和resetProgress:开启后会额外增加元数据查询开销,压测时可关掉以榨干 IO -
loadUsers:若 dump 包含用户,且目标实例权限体系一致,才设为true;否则可能因 host 不匹配或密码插件差异失败
容易被忽略的兼容性陷阱
即便参数全对、Redo 也关了,仍可能卡在中间不动或报错:
- dump 文件由 MySQL 8.0+ 生成,但目标实例是 5.7:
loadDump()会拒绝加载,因为 5.7 不识别 8.0 新增的元数据字段(如collation_version) - dump 含有 JSON 列或隐藏索引,而目标实例版本不支持:报错信息类似
Unknown column 'xxx' in 'field list',实际是语法解析失败 - 路径权限问题:
/data/mysql_dump_dir必须是 MySQL Server 进程可读(不是当前 shell 用户可读),尤其在容器或 systemd 环境下,常因ProtectHome=yes导致读不到
真正耗时的从来不是“怎么写命令”,而是确认目标实例的 MySQL 版本、Redo 支持状态、文件系统权限这三项是否全部就绪 —— 少一个,多线程就等于空转。

















