MySQL磁盘满导致备份失败时,需先用df -h定位满载分区,再用du -sh和SHOW VARIABLES查binlog、ibtmp1、general_log等元凶;优先PURGE BINARY LOGS或关闭通用/慢查询日志释放空间,切忌误删ibdata1或关闭binlog。

备份失败不是备份工具的问题,而是MySQL在磁盘满时已拒绝写入 —— 此时PURGE BINARY LOGS、mysqldump、甚至SELECT都可能卡住或报错ERROR 1030 (HY000): Got error 28 from storage engine。必须先释放空间,再重试备份。
确认磁盘满的真正位置和元凶
别急着删文件。先定位是哪个挂载点满了,以及谁在疯狂写:
- 运行
df -h,重点看/var/lib/mysql所在分区(比如/dev/sda1)是否 100% —— 如果是,问题就在 MySQL 数据目录内 - 快速扫描大文件:
du -sh /var/lib/mysql/* | sort -hr | head -5,重点关注:mysql-bin.*(binlog)、ibtmp1(临时表空间)、general.log或slow.log(日志)、ibdata1(仅当innodb_file_per_table=OFF时才需警惕) - 检查日志开关:
SHOW VARIABLES LIKE 'general_log%'; SHOW VARIABLES LIKE 'slow_query_log%';—— 若值为ON且日志文件已达 GB 级,就是直接元凶
优先清理 binlog:最快见效的空间释放手段
binlog 是最常被忽略、却增长最快、又最安全可删的日志类型。它不随 MySQL 重启消失,必须主动 PURGE:
- 先确认从库同步位置(主从环境必做):
SHOW SLAVE STATUS\G,记下Relay_Master_Log_File值,比如mysql-bin.000120 - 安全清理命令(保留到该文件之前):
PURGE BINARY LOGS TO 'mysql-bin.000120'; - 或按时间删(推荐):
PURGE BINARY LOGS BEFORE '2026-06-09 00:00:00';(删掉 3 天前的所有 binlog) - 注意:
PURGE后空间立即释放;但如果某 binlog 被其他进程(如长连接的mysqldump --master-data)占用,rm会失败 —— 此时需先KILL对应线程
关闭并清理通用/慢查询日志
这两类日志开启后每条 SQL 都落盘,几十万行/天很常见,且不会自动轮转:
- 立刻停写:
SET GLOBAL general_log = 'OFF'; SET GLOBAL slow_query_log = 'OFF'; - 手动删除对应文件(路径查
SHOW VARIABLES LIKE 'general_log_file';):rm /var/lib/mysql/general.log(删完空间立刻释放) - 错误日志
log_error必须保留,但要用logrotate配置切割+压缩+保留 7 天,否则也会撑爆磁盘 - 别碰
log_bin = OFF—— 关闭 binlog 会导致主从中断、GTID 失效、无法 PITR,属于高危误操作
处理临时文件与 ibtmp1
如果 df -h 显示 /tmp 分区满,或 du 发现 /var/lib/mysql/ibtmp1 异常巨大(>10GB),说明有大事务未提交或复杂查询生成了巨型临时表:
- 清空系统临时目录:
sudo rm -rf /tmp/*(确保无正在运行的关键临时进程) - 若
ibtmp1过大,只能重启 MySQL 释放(需业务低峰期):service mysql stop && service mysql start—— 它会在启动时重建为初始大小(通常 12MB) - 长期方案:调小
tmp_table_size和max_heap_table_size(避免内存滥用),并优化含ORDER BY、GROUP BY、多表 JOIN 的慢 SQL
真正棘手的是 ibdata1 占满却无法收缩 —— 它只增不减,除非导出重建。而 data_free 高(用 SELECT SUM(data_free)/1024/1024 FROM information_schema.tables; 查)说明大量碎片,但表已被删就无法 OPTIMIZE TABLE。这种情况下,唯一安全路径是停服 + rsync 迁移 + 换盘,而不是盲目删 ibdata1 —— 那等于丢数据。


















