应选util.dumpInstance()备份整个实例,选util.dumpSchemas()备份指定库;前者导出系统库并默认排除information_schema等,后者仅处理显式传入的库数组,且二者均默认启用zstd压缩与分块并行导出。

util.dumpSchemas() 和 util.dumpInstance() 怎么选
备份整个 MySQL 实例用 util.dumpInstance(),只备份几个库就用 util.dumpSchemas()。两者都默认启用 zstd 压缩和分块并行导出,但 util.dumpInstance() 会额外导出 MySQL 系统库(如 mysql、sys),而 util.dumpSchemas() 只处理你显式指定的库名列表。
常见错误是误用 util.dumpSchemas("db1, db2") —— 这会被当作一个 schema 名,实际应传数组:util.dumpSchemas(["db1", "db2"])。参数传错会导致“Schema not found”或静默跳过。
- 大库全量备份 → 优先
util.dumpInstance() - 多租户环境按业务库隔离备份 → 用
util.dumpSchemas(["tenant_a", "tenant_b"]) - 想跳过
information_schema等只读库?util.dumpInstance()默认已排除,无需额外过滤
为什么禁用压缩会导致分块失效
MySQL Shell 的 chunk 分块机制(按主键或唯一索引列切分大表)和 zstd 压缩是强绑定的:一旦设置 {"compression": "none"},底层会自动关闭分块,退化为单线程全表扫描导出。这不是 bug,而是设计约束——分块依赖压缩流的边界对齐来保证并发安全。
实测中,20GB 表在启用 zstd + 4 线程时耗时约 90 秒;禁用压缩后即使设 {"threads": 4},仍为单线程,耗时升至 6 分钟以上。所以“不压缩更快”只适用于小表(
- 远程备份到对象存储(如 OCI、S3)→ 必须开 zstd,省带宽也提速
- 本地 SSD 备份且磁盘 I/O 是瓶颈 → 可试
{"compression": "zstd", "zstdCompressionLevel": 1}降低 CPU 占用 - 绝对不要设
{"compression": "none"}还指望多线程生效
util.dumpTables() 备份单表时的坑
util.dumpTables() 是 8.0.22+ 新增的接口,专为单表或少量表优化,但它不生成 SQL 文件,而是导出为 TSV + JSON 元数据组合。恢复时必须用 util.loadDump(),不能用 mysql 命令直接导入。
典型错误是把 util.dumpTables("test", ["sbtest1"], "/backup/") 导出的文件当成 SQL 脚本,然后执行 mysql test —— 这会报错 “Unknown command ‘#’”,因为首行是注释头,且内容是 TSV 格式。
- 确认导出目录下有
@.json和sbtest1.tsv,不是.sql - 恢复命令固定为:
util.loadDump("/backup/", {"schema": "test"}) - 如果目标库不存在,
util.loadDump()不会自动创建,需提前CREATE DATABASE test
权限和引擎限制容易被忽略
MySQL Shell 备份要求比 mysqldump 更严格:必须有 BACKUP_ADMIN 权限(5.7 需 RELOAD + LOCK TABLES),且只支持 InnoDB 表。MyISAM 表会跳过并报 warning,但不会中断流程——这容易导致备份遗漏。
另一个隐性限制是 socket 连接路径。若用 --socket=/var/lib/mysql/mysql.sock 连接,而 MySQL 实际监听在 /tmp/mysql.sock,util.dump* 会卡在 “Acquiring global read lock” 步骤超过 30 秒后超时,错误信息里却只显示 “Timeout waiting for lock”,不提示 socket 路径问题。
- 检查权限:
SELECT * FROM information_schema.role_table_privileges WHERE privilege_type = 'BACKUP_ADMIN'; - 查引擎:
SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'your_db'; - 连 socket 前先
ls -l /var/lib/mysql/mysql.sock /tmp/mysql.sock确认真实路径


















