mysql备份失败报“no space left on device”时,须优先检查/tmp、/var/tmp和/var/lib/mysql分区空间及inode使用率,确认tmpdir路径并清理残留文件,再通过--tmpdir指定大空间目录配合gzip流式压缩执行mysqldump。

别等 mysqldump 报 No space left on device 才反应——临时表空间(ibtmp1)或系统 /tmp 已满时,备份本身就会失败。必须先释放空间、绕过瓶颈、再执行带压缩的流式备份。
查清到底是哪个目录被临时文件撑爆
MySQL 临时文件可能落在三个地方:tmpdir(系统级)、innodb_temp_tablespaces(InnoDB 临时表空间)、或 /var/lib/mysql 下的 ibtmp1。它们互不干扰,但都可能导致磁盘写入失败。
- 执行
SHOW VARIABLES LIKE 'tmpdir';,确认 MySQL 进程实际使用的临时目录(常为/tmp或/var/tmp) - 执行
df -h /tmp /var/tmp /var/lib/mysql,对比各挂载点使用率;若/tmp>95%,优先清理它 - 执行
df -i /tmp,小文件极多时 inode 可能先耗尽,rm -f /tmp/#sql-*能快速清掉 mysqldump 中断残留的“幽灵文件” - 检查
ibtmp1大小:ls -lh /var/lib/mysql/ibtmp1;若 >10GB 且 MySQL ≥5.7.30,后续可在线收缩
紧急备份必须绕开默认 /tmp 和未压缩中间文件
默认 mysqldump 会在 tmpdir 写临时排序/JOIN 结果,再输出 SQL —— 两头吃空间。不指定 --tmpdir + 不压缩,等于把压力全压给已满的分区。
- 找一个剩余空间 > 预估备份大小 × 1.5 的路径(如
/data/backup_tmp),确认 MySQL 用户有读写权限 - 命令必须包含:
--single-transaction(InnoDB 免锁)、--tmpdir=/data/backup_tmp(避开系统/tmp)、| gzip(实时压缩,不落地大文件) - 示例:
mysqldump --single-transaction --tmpdir=/data/backup_tmp -u root -p mydb | gzip > /backup/mydb_$(date +%F).sql.gz - 若连
gzip都报错,说明管道缓冲区也溢出,改用pv限速:mysqldump ... | pv -L 10m | gzip > ...
清理 ibtmp1 不能删文件,得靠运行时收缩或重启
ibtmp1 是 InnoDB 自管理的临时表空间,文件体积不会随临时表删除而缩小。直接 rm ibtmp1 会导致 MySQL 启动失败。
- MySQL ≥5.7.30:执行
ALTER TABLESPACE innodb_temp_tablespaces ENCRYPTION='N';,强制重建临时表空间,立刻释放磁盘(需无活跃长事务) - MySQL SET GLOBAL innodb_fast_shutdown = 0;、确认
information_schema.INNODB_TRX无超 60 秒事务、执行FLUSH TABLES; - 无论是否重启,都要同步调大内存临时表阈值,避免反复落盘:
SET PERSIST tmp_table_size = 67108864;和SET PERSIST max_heap_table_size = 67108864;(两个值必须一致)
别漏掉日志类“静默杀手”
慢日志、通用日志、binlog 不是数据库运行必需项,但长期开启不轮转,单个文件可达数 GB,且它们往往和 datadir 或 tmpdir 在同一分区。
- 立刻关掉非必要日志:
SET GLOBAL slow_query_log = 'OFF';、SET GLOBAL general_log = 'OFF'; - 手动删日志文件前,先查路径:
SHOW VARIABLES LIKE 'slow_query_log_file';,然后rm -f /var/lib/mysql/slow.log - binlog 清理必须验证从库追平:
SELECT MASTER_POS_WAIT('mysql-bin.000100', 123456789);返回非 NULL 后,再执行PURGE BINARY LOGS TO 'mysql-bin.000101';
真正卡住人的不是技术动作本身,而是误判瓶颈位置——比如 df -h 显示 / 分区 92%,但真正爆掉的是挂载在内存上的 tmpfs /tmp;又或者以为 ibtmp1 能像普通文件一样删了就完事。每一步操作前,必须用 df -h 和 df -i 锁定真实满载点,再对应执行清理或绕行。











