一、问题现象
登录服务器或宝塔面板,发现磁盘空间使用率持续攀升:
文件系统 容量 已用 可用 使用率 挂载点
/dev/sda1 200G 180G 20G 90% /排查后发现,/www/server/data/ 目录下塞满了 mysql-bin.000001 到 mysql-bin.099999 的文件,单个文件几十 MB 到几 GB 不等,几十个加起来轻松几十 GB。
这就是 MySQL 的 binlog(二进制日志) 在作怪。
二、什么是 MySQL binlog?
binlog 是 MySQL 的二进制日志,记录所有对数据库的修改操作(INSERT / UPDATE / DELETE / DDL),主要用于:
| 用途 | 说明 |
|---|---|
| 主从复制 | 从库根据 binlog 同步数据 |
| 数据恢复 | 按时间点精确恢复(PITR) |
| 审计追踪 | 知道谁在什么时候改了什么 |
| 问题来了:默认情况下,binlog 不会自动过期,会一直保留。一个高并发的站点,一天就能产生几百 MB 甚至几 GB 的 binlog,几个月下来磁盘就被撑爆。 |
三、binlog 文件位置
宝塔面板中,binlog 默认存放在:
/www/server/data/# 查看 binlog 文件大小
ls -lhS /www/server/data/mysql-bin.* | head -20
# 查看总占用空间
du -sh /www/server/data/mysql-bin.*
四、解决方案
4.1 紧急处理:手动清理旧 binlog
MySQL 命令清理(推荐)
-- 只保留最近 3 天的 binlog
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY);
-- 或者删除指定文件之前的所有 binlog
PURGE BINARY LOGS TO 'mysql-bin.000050';
这是最安全的方式,MySQL 会正确更新索引文件 mysql-bin.index,不会破坏主从复制。
4.2 一劳永逸:配置自动过期清理
编辑 MySQL 配置文件:
vi /etc/my.cnf在 [mysqld] 段落下添加:
[mysqld]
# 开启 binlog
log-bin = /www/server/data/mysql-bin
# 核心:自动清理 3 天前的 binlog(单位:秒)
expire_logs_days = 3
# 可选:限制单个 binlog 文件大小
max_binlog_size = 100M
# 可选:binlog 格式
binlog_format = MIXED
MySQL 8.0+ 注意:expire_logs_days 已被弃用,改用:Copybinlog_expire_logs_seconds = 259200
保存后重启 MySQL:
/etc/init.d/mysqld restart4.3 不需要 binlog?直接关闭
如果服务器没有主从复制、不需要时间点恢复:
[mysqld]
# 注释掉或删除这行
# log-bin = /www/server/data/mysql-bin重启后手动清理已有文件:
rm -f /www/server/data/mysql-bin.*删除前确认:不需要主从复制、不需要 binlog 做数据恢复。
五、binlog 保留天数建议
| 场景 | 建议 |
|---|---|
| 纯单机,无主从 | 关闭 binlog 或保留 1-2 天 |
| 有主从复制 | 保留 3-7 天 |
| 重要数据,需精确恢复 | 保留 7-30 天,定期备份 |
| 高写入量站点 | 1-3 天 + 定期备份 |
六、总结 & 操作清单
# 一键排查
cd /www/server/data/
ls -lhS mysql-bin.* | head -5
du -sh mysql-bin.*-- 清理旧 binlog
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY);
SHOW BINARY LOGS;# my.cnf 配置(MySQL 5.7)
expire_logs_days = 3
max_binlog_size = 100M
# my.cnf 配置(MySQL 8.0+)
binlog_expire_logs_seconds = 259200
max_binlog_size = 100M
核心原则:binlog 是双刃剑——能救命也能撑爆磁盘。用就管好,不用就关掉,别让它无限制膨胀。
