mysqldump本身不直接消耗cpu,但其触发的大量select查询、buffer pool访问、mdl锁及查询缓存抖动导致mysqld进程cpu飙升;nice/ionice仅降低dump进程优先级,真正需限制的是mysqld资源行为。

直接结论:mysqldump 本身不直接吃 CPU,但默认单线程全表扫描 + 高频 Buffer Pool 访问 + 查询缓存抖动,会把 MySQL 进程拖进高 CPU;用 nice 和 ionice 只能压低备份进程自身调度权重,对 MySQL 主进程无效——真正要控的是 MySQL 的资源消耗,不是 dump 脚本。
为什么 mysqldump 执行时 MySQL CPU 会飙升
很多人误以为是 mysqldump 进程占了 CPU,其实 top 里看到的高 CPU 几乎都来自 mysqld。原因很实在:
-
mysqldump每次读一行、拼一条 INSERT,本质是一连串SELECT查询,触发大量逻辑读(Buffer Pool 查找 + 行格式解析) - 默认不加
--single-transaction时可能触发元数据锁(MDL),阻塞其他查询,加剧线程堆积 - 查询缓存(如果开启)在 dump 过程中频繁失效重建,引发内部 mutex 争抢
- 大表没索引或 WHERE 条件无法走索引时,
mysqldump就是全表扫描发起者,InnoDB 必须遍历所有 page
用 nice 和 ionice 能起什么作用
它们只影响 mysqldump 进程自身的 CPU/IO 调度优先级,对 mysqld 进程无感。但仍有实操价值:
-
nice -n 19 mysqldump ...:让 dump 进程在 CPU 竞争中“靠后站”,避免它抢走应用查询所需的 CPU 时间片 -
ionice -c 3 mysqldump ...:启用 idle I/O class,表示“只在磁盘空闲时才读”,大幅降低对主库写入、从库 relay log 应用的 IO 干扰 - 组合使用更稳妥:
nice -n 19 ionice -c 3 mysqldump -u root -p --single-transaction mydb > backup.sql - 注意:
ionice -c 2 -n 7(Best Effort 最低级)效果不如-c 3彻底,某些内核下甚至不生效
真正该限制的是 mysqld 的资源行为
与其调 dump,不如让 MySQL 在备份期间“自我约束”。几个关键动作:
- 临时调低并发线程压力:
SET GLOBAL innodb_thread_concurrency = 4;(默认 0 表示不限制,设为小值可抑制并发扫描争抢) - 禁用查询缓存(如果还在用):
SET GLOBAL query_cache_type = OFF;,避免 dump 引发 cache 大量失效 - 控制缓冲池污染:
SET SESSION innodb_buffer_pool_dump_pct = 0;,防止 dump 数据挤掉热数据 - 对超大表跳过或分批:
mysqldump --where="id BETWEEN 1 AND 1000000" db table,避免单次扫描太长 - 从库备份?务必加
--skip-lock-tables,并确认slave_parallel_workers = 0或已停 SQL Thread,否则 MDL 会卡住并行回放
比 mysqldump 更稳的替代方案
当数据库超过 20GB,mysqldump 就不该是首选。真实线上环境更依赖:
-
Percona XtraBackup:物理备份,不走 SQL 层,CPU 开销极低;热备只加毫秒级全局读锁;支持流式压缩传输 -
mydumper:多线程逻辑备份,可按表/按 chunk 并行导出,自带--trx-consistency-only优化一致性 - 云厂商 RDS 自带快照:底层基于存储层快照,完全不经过 MySQL 实例,零 CPU 影响
- 注意:
XtraBackup 8.0不兼容 MySQL 5.7,版本错配会导致apply-log报Unsupported redo log format
最常被忽略的一点:备份窗口期的监控必须包含 SHOW PROCESSLIST 的实时快照和 Performance Schema 中的 threads.THREAD_OS_ID 映射,否则你永远不知道是哪个内部线程在狂刷 CPU——光看 mysqldump PID 是没用的。











