紧急备份mysql需三步:腾空间(查df -h/-i并清理/tmp残留)、换路径(--tmpdir指定大空间目录)、压输出(gzip实时压缩),避免默认/tmp瓶颈。

直接上结论:别硬扛着用默认配置跑 mysqldump,先腾空间、换路径、压输出,三步内完成可落地的紧急备份。
df -h 和 df -i 必须同时查,/tmp 满了比 /var/lib/mysql 满更致命
很多运维卡在第一步就误判——df -h 显示 / 分区 92%,但 /var/lib/mysql 所在目录其实只用了 60%。真正爆掉的是 /tmp(mysqldump 默认临时缓冲区),尤其当它挂载在 tmpfs(内存虚拟盘)上时,哪怕物理内存充足,df -h /tmp 也可能显示 100%。
- 立刻执行:
df -h /tmp和df -h对比;再补一句:df -i /tmp,小文件极多时 inode 可能先耗尽 - 若
/tmp已满,rm -f /tmp/#sql-*清理残留临时文件(mysqldump中断后留下的“幽灵文件”) - 别信
information_schema.TABLES里的DATA_LENGTH,它比真实.ibd小 20%–30%,按这个估算空间大概率翻车
mysqldump --tmpdir + 压缩输出,绕过系统/tmp瓶颈
mysqldump 大表导出会先写入磁盘再压缩,不指定 --tmpdir 就等于把压力全扔给 /tmp。紧急情况下必须显式指定一个有足够空间的目录,并强制压缩输出。
- 找一个剩余空间 > 预估备份大小 × 1.5 的路径,比如
/data/backup_tmp,确认 MySQL 用户有读写权限 - 命令示例:
mysqldump --single-transaction --tmpdir=/data/backup_tmp -u root -p mydb | gzip > /backup/mydb_$(date +%F).sql.gz - 关键点:
--single-transaction避免锁表(InnoDB 前提),gzip实时压缩,避免生成超大未压缩中间文件 - 如果连
gzip都报 “No space left on device”,说明管道缓冲区也撑不住,改用pv限速:mysqldump ... | pv -L 10m | gzip > ...
关通用日志和慢日志,释放 GB 级空间立竿见影
这两个日志不是数据库运行必需项,开启后不设轮转会持续追加,单个文件常达几 GB。关掉它们不会影响主从、事务或数据一致性,只影响后续 SQL 审计能力。
- 先确认是否启用:
SHOW VARIABLES LIKE 'general_log%';和SHOW VARIABLES LIKE 'slow_query_log%'; - 立即关闭:
SET GLOBAL general_log = 'OFF';和SET GLOBAL slow_query_log = 'OFF'; - 手动删日志文件:
rm -f /var/lib/mysql/general.log /var/lib/mysql/slow.log(路径以general_log_file和slow_query_log_file变量值为准) - 注意:
log_error(错误日志)必须保留;log_bin绝对不能关,否则主从和 GTID 全废
备份完立刻检查 ibtmp1 和残留 #sql-* 文件
备份过程本身会触发 InnoDB 临时表空间扩张和排序落盘,若备份中途失败,/var/lib/mysql/ibtmp1 或 /tmp/#sql-* 可能卡在数 GB 不释放,下次备份还会撞上。
- 查当前大小:
ls -lh /var/lib/mysql/ibtmp1,若 > 1GB 且 MySQL 近期重启过,可安全删除(重启后自动重建) - 清理残留:
lsof +L1查“已删但进程仍 open”的文件,重点看mysqld进程是否还 hold 着/tmp/#sql-* - 长期建议:在
my.cnf中固定tmpdir = /data/tmp,并确保该路径独立挂载、不与系统盘混用
真正危险的不是“只剩 10% 空间”,而是默认行为把所有临时压力都导向同一个窄通道——/tmp。只要把 --tmpdir、日志开关、压缩管道这三件事串起来,90% 的紧急备份都能在不扩容、不停服的前提下完成。











