mysqldump报“no space left on device”需先检查/tmp和备份路径所在分区空间及inode,再排查mysql日志、临时文件配置及innodb表空间未释放问题。

mysqldump 备份失败报 “No space left on device” 怎么快速定位
不是所有 “磁盘满” 都是 /var/lib/mysql 所在分区真满了——mysqldump 默认用系统 /tmp 做临时缓冲,大表导出会先写入磁盘再压缩,/tmp 和备份目标路径若在同一挂载点(比如都落在 /),就容易爆掉。
立刻执行:df -h /tmp 和 df -h /backup(把 /backup 换成你实际的备份路径);
再补一句:df -i /tmp,小文件极多时 inode 可能先耗尽。
常见误判点:
• information_schema.TABLES 里查出的 DATA_LENGTH + INDEX_LENGTH 是估算值,比真实 .ibd 文件小 20%–30%,别信它来判断空间余量
• du -sh /var/lib/mysql 总和远小于 df -h 显示已用,大概率是“幽灵文件”(已删但进程仍 open),用 lsof +L1 查
哪些 MySQL 日志可以安全关、立刻释放 GB 级空间
通用日志(general_log)和慢查询日志(slow_query_log)一旦开启,不设轮转就疯狂写,单个文件动辄几 GB。它们不是必须项,关了不伤主从、不丢数据,只影响 SQL 审计和排查能力。
操作前确认是否真在用:SHOW VARIABLES LIKE 'general_log%';SHOW VARIABLES LIKE 'slow_query_log%';
安全关闭方式:
• SET GLOBAL general_log = 'OFF';
• SET GLOBAL slow_query_log = 'OFF';
• 再手动删掉对应日志文件(如 /var/lib/mysql/general.log),rm 后空间立即释放
注意:
• 错误日志(log_error)必须留,但要用 logrotate 配置按天切割+压缩+保留 7 天
• log_bin = OFF 绝对不能随便关,否则主从、GTID、闪回全废
临时文件占满 /tmp 或 innodb_tmpdir 怎么救急
mysqldump、CREATE TABLE AS SELECT、大 ORDER BY 或 GROUP BY 都会生成巨型临时文件,默认走系统 /tmp。如果它挂载在内存(tmpfs),大小受限于 RAM,极易撑爆。
查当前设置:SELECT @@tmpdir, @@innodb_tmpdir;
临时救急方案:
• 加 --tmpdir=/path/to/larger/disk 参数重跑 mysqldump,例如:mysqldump --tmpdir=/data/tmp ...
• 若用 xtrabackup,它不认 --tmpdir,得改环境变量:export TMPDIR=/data/tmp && innobackupex ...
长期建议:
• 把 tmpdir 指向独立大分区,并确保 MySQL 用户有权限
• 调低 sort_buffer_size 和 join_buffer_size(别设成几百 MB 以上)
• 对大表加 ORDER BY 字段建索引,减少磁盘临时表生成
备份命令自己判断空间够不够,别等失败才报警
靠定时任务“准时跑”没用,备份失败后才发现空间不够,说明防御已经失效。真正靠谱的是让备份脚本启动前自检。
示例(shell):[ $(df --output=avail /backup | tail -1) -lt 5242880 ] && echo "NOT ENOUGH SPACE" && exit 1
这行检查 /backup 是否至少剩 5GB(单位 KB),不满足直接退出,不产生半截垃圾文件。
关键细节:
• xbbackup 自身无空间预检,必须在外层 shell 封装
• --parallel 越高,临时空间峰值越大,阈值要同步上浮
• 报警不能只发邮件:触发钉钉/企微机器人时,带上 df -h 和 ls -lh /backup/ 最新结果,省得运维再连一次机器
最常被忽略的一点:InnoDB 表删完数据,.ibd 文件不会自动缩,OPTIMIZE TABLE 或重建才能释放。但这个动作本身又需要额外空间——所以清理日志和临时文件,永远是第一步,也是见效最快的一步。











