当前位置:首页 >  站长 >  数据库 >  正文

MySQL 写入失败与磁盘满:binlog 和 ibdata1 的膨胀处理

 2026-09-06 16:44  来源: 互联网   我来投稿 撤稿纠错

  一键部署OpenClaw

半夜网站报数据库写入失败,登上服务器一看,磁盘 100%。du 一层层剥进去,/var/lib/mysql 里有几十个 mysql-bin.0000XX 文件,加起来占了几十 G。这就是 binlog 膨胀——MySQL 8.0 起 binary log 默认开启,而清理周期默认 30 天,写入量大的库撑爆磁盘只是时间问题。

这个故障的完整因果链:8.0 起默认开 log_bin、30 天滚动清理、单文件 1GB 滚动,三者叠加,磁盘被吃光只是快慢问题。处理分两步走:先应急删 binlog 腾空间恢复写入,再改保留期治本。

先确认案发现场:官方文档给的关键数字是 binlog_expire_logs_seconds 默认 2592000 秒(即 30 天),单个 binlog 文件到 max_binlog_size(默认 1GB)就滚动新文件,而清理动作只发生在服务器启动和日志 flush 的时候。写入密集的库一天滚好几个 1GB,30 天攒下几十 G 毫不奇怪。注意 ibdata1 也要看一眼:InnoDB 的系统表空间只增不减,历史上存过大事务就瘦不回去,但它是数据文件,处理思路和 binlog 完全不同,别混为一谈。

# 确认 binlog 占用与清理配置

du -sh /var/lib/mysql/ | cat

mysql -e "SHOW BINARY LOGS;" | tail -5

mysql -e "SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';"

mysql -e "SHOW VARIABLES LIKE 'max_binlog_size';"

应急清理用 PURGE BINARY LOGS,不要手 rm——手工删除文件会让 MySQL 的索引文件和磁盘状态不一致,主从环境下还可能直接断复制。PURGE 支持按时间点或按文件名两种方式,留够主从同步所需的量再删。删之前必须确认:这台库有没有从库挂着、从库的落后量有多大,binlog 删早了从库追不上就麻烦了。

-- 应急:删掉 3 天前的 binlog(先确认从库不需要!)

PURGE BINARY LOGS BEFORE '2026-09-01 00:00:00';

-- 或者按文件名:保留到 mysql-bin.000150 为止

PURGE BINARY LOGS TO 'mysql-bin.000150';

-- 立刻触发一次滚动与清理,不用等启动

FLUSH BINARY LOGS;

应急之后要治本:把保留窗口从 30 天压到和你的备份周期匹配。官方文档和通行实践的建议是:binlog 保留期至少覆盖一个完整备份周期再加缓冲——每天全备,留 7 天就够;每周全备,留 14 天。改这个变量是在线可改的,不用重启。

-- 在线改为 7 天并立即生效

SET GLOBAL binlog_expire_logs_seconds = 604800;

-- 写进 my.cnf 持久化([mysqld] 段)

-- binlog_expire_logs_seconds = 604800

-- 验证:再次查看磁盘

df -h /var/lib/mysql

mysql -e "SHOW BINARY LOGS;" | wc -l

收尾说两句长期主义:一是给 /var/lib/mysql 单独分区或单独挂盘,让数据库膨胀炸不到系统盘;二是把 binlog 磁盘占用加进监控,超过阈值告警,别等写入失败才发现。至于 ibdata1 膨胀,那是另一个故事——它需要导出全库、删文件重建、再导入的完整迁移流程,风险等级完全不同,本篇先不展开,但记住一条:任何时候都别直接删 ibdata1。

相关阅读:写入失败十有八九病根在磁盘。《服务器故障排查总纲:按现象反查的五层定位法》把本篇和磁盘满、日志轮转排在相邻位,数据层故障从总纲入口进,处理顺序一目了然。

申请创业报道,分享创业好点子。点击此处,共同探讨创业新机遇!

相关标签
服务器故障排查

相关文章

热门排行

信息推荐