MySQL的expire_logs_days在5.7.31+/8.0.11+已弃用且无效,应改用binlog_expire_logs_seconds;error/slow/general日志需外部脚本或logrotate清理,并注意主从复制延迟影响binlog安全删除。

MySQL 的 expire_logs_days 不会自动清理日志文件,它只控制二进制日志(binlog)的保留天数,且在 MySQL 5.7.31+ 和 8.0.11+ 中已被弃用——直接设了也无效。
为什么 expire_logs_days 设了没反应?
这个参数在旧版 MySQL 中确实能触发自动 purge,但有两个致命限制:
- 仅对
binlog生效,完全不处理error log、slow query log或general log - MySQL 5.7.31 及以后版本默认忽略该参数,必须显式启用
binlog_expire_logs_seconds才有效 - 即使生效,也只在服务器启动时或执行
PURGE BINARY LOGS时检查,不是实时定时任务
真正能定时清理 binlog 的方法:用 binlog_expire_logs_seconds
这是官方推荐的替代方案,单位是秒,比天数更精确,且强制启用后才起作用:
- 设置前先确认 binlog 已开启:
SHOW VARIABLES LIKE 'log_bin';返回ON才能用 - 修改配置文件
my.cnf,在[mysqld]下添加:binlog_expire_logs_seconds = 2592000 # 30 天
- 重启 MySQL 或动态设置(需 SUPER 权限):
SET GLOBAL binlog_expire_logs_seconds = 2592000; - 注意:动态设置后,下次重启仍会恢复为配置文件值,务必同步改配置文件
其他日志(error/slow/general)只能靠外部脚本 + cron
MySQL 自身不提供这些日志的自动轮转或清理机制,必须自己处理:
- 查当前日志路径:
SHOW VARIABLES LIKE '%log_error%';、SHOW VARIABLES LIKE '%slow_query_log_file%'; - Linux 下常用组合:
find /var/lib/mysql/ -name "mysqld.log.*" -mtime +30 -delete - 更稳妥的做法是配合
logrotate,避免进程还在写日志时被误删(需加copytruncate或发SIGUSR1通知 MySQL 重开日志) - 切记不要直接
rm -f正在使用的error.log,否则 MySQL 会停止写日志,错误信息就丢了
最常被忽略的一点:binlog 清理受 max_binlog_size 和主从复制状态影响——如果从库还没读完某段 binlog,即使过期了也不会被 purge。所以得定期看 SHOW SLAVE STATUS\G 里的 Relay_Master_Log_File,再决定能不能安全清理。


















