最稳妥的方式是设置binlog自动过期删除而非关闭;先确认log_bin=on、查看show binary logs及磁盘占用,再在my.cnf中配置binlog_expire_logs_seconds=604800(兼容expire_logs_days=7),重启mysql后执行purge命令立即释放空间。

MySQL binlog 日志过大,最稳妥的关法不是“关”,而是“设过期自动删”——除非你确认不需要主从复制或增量恢复,否则直接关闭 log_bin 会破坏备份链路,且宝塔界面里那个开关只控制启停,不控制清理。
怎么确认 binlog 当前开着、占多大空间
先别急着改配置,得看现状:
- 执行
mysql -uroot -p -e "show variables like 'log_bin';",返回ON就说明开着 - 执行
mysql -uroot -p -e "SHOW BINARY LOGS;",看列表长度和最大文件大小,比如mysql-bin.000123已到 1.2G,说明积压严重 - 查磁盘:
du -sh /www/server/data/mysql-bin.*,加起来可能已占几十 GB
MySQL 5.7 / 8.0 兼容的过期设置写法
新版 MySQL(8.0.11+)已弃用 expire_logs_days,但宝塔默认安装的 MySQL 5.7 和部分 8.0 镜像仍依赖它;为兼顾兼容性,建议双参数并存:
编辑 /www/server/mysql/my.cnf,在 [mysqld] 段下添加:
binlog_expire_logs_seconds = 604800 expire_logs_days = 7
注意两点:
-
binlog_expire_logs_seconds优先级更高,单位是秒(604800 = 7 天),MySQL 8.0.11+ 必须用这个才真正生效 -
expire_logs_days是兜底,避免某些旧版客户端或脚本读不到新参数时失效 - 不要写
max_binlog_size来“限制单个文件大小”——它只影响轮转频率,不解决总量问题
为什么改完配置要立刻执行 PURGE,而不是等自动清理
MySQL 的自动清理不是定时扫描,而是靠「下次日志轮转时触发」。如果当前 mysql-bin.000123 已写入 3 天,但还没满、没轮转,那即使过了 7 天,它也不会被删——直到下一次 FLUSH LOGS 或达到 max_binlog_size 触发切换。
所以必须手动清一次旧账:
- 进 MySQL 命令行:
mysql -uroot -p - 执行:
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY); - 再查一遍:
SHOW BINARY LOGS;,确认最老的文件时间已落在 7 天内
这一步做完,磁盘空间才会立刻释放——因为 MySQL 调用 unlink(),内核马上回收 inode。
宝塔计划任务脚本比配置文件更可靠?不一定
有人图省事,在宝塔「计划任务」里加一条每天执行 PURGE BINARY LOGS BEFORE ... 的 Shell 脚本。这看似可控,但有硬伤:
- 脚本依赖
mysql客户端可用、密码可读(宝塔把 root 密码存在/www/server/panel/database/default.pl,但权限不对时会失败) - 如果某天 MySQL 正在重启或锁表,脚本执行失败,日志就继续涨
- 不如直接配
binlog_expire_logs_seconds——它是服务内置逻辑,不依赖外部调度,只要 mysqld 在跑就生效
真正该用计划任务的,是监控:比如每天检查 SHOW BINARY LOGS 行数是否 > 50,超了就发告警,而不是拿来替代配置项。
最后提醒一句:修改 my.cnf 后必须重启 MySQL(service mysqld restart 或宝塔面板里点重启),否则变量不会加载;而 SET GLOBAL 方式设的参数,MySQL 一重启就丢——所以只适合临时救急,不能当长期策略。











