mysql binlog占用空间过大时,应优先配置binlog_expire_logs_seconds(8.0+)或expire_logs_days(5.7)并写入my.cnf;手动purge仅作应急,flush logs可安全触发自动清理,严禁盲目reset master。

MySQL binlog 占用空间过大,优先改 binlog_expire_logs_seconds(MySQL 8.0+)或 expire_logs_days(5.7),并写入配置文件;手动 PURGE BINARY LOGS 只用于应急,不能替代自动策略。
MySQL 8.0+ 必须用 binlog_expire_logs_seconds
MySQL 8.0 开始,expire_logs_days 已被标记为 deprecated,虽然还能设,但实际不生效或行为不可靠。必须用秒级参数:binlog_expire_logs_seconds。
- 7 天 =
604800秒,执行:SET GLOBAL binlog_expire_logs_seconds = 604800; - 设完立刻生效,但重启后会丢失——必须同步写进
/www/server/mysql/my.cnf的[mysqld]段落里 - 如果之前设过
expire_logs_days,建议先清零:SET GLOBAL expire_logs_days = 0;,避免参数冲突 - 确认是否生效:运行
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';,值应为你设置的秒数
手动 PURGE BINARY LOGS 前必须核对主从状态
直接执行 PURGE BINARY LOGS BEFORE ... 或 TO ... 会永久删除文件,且不可回滚。一旦删掉从库还没读取的日志,主从就断了。
- 主库查当前日志:
SHOW MASTER STATUS;,记下File字段(如mysql-bin.000042) - 每台从库连上去执行:
SHOW SLAVE STATUS\G,重点看Relay_Master_Log_File和Exec_Master_Log_Pos - 所有从库中
Relay_Master_Log_File最旧的那个文件,就是你PURGE TO的安全下限——例如最旧是mysql-bin.000035,那至少保留000035及之后的 - 清理命令示例:
PURGE BINARY LOGS TO 'mysql-bin.000036';(删掉000036之前的)
宝塔面板里脚本清理要绕过密码明文风险
宝塔计划任务里常见写法是用 cat /www/server/panel/database/default.pl 读 root 密码,但该文件权限若非严格限制(如 600),容易被其他用户读取,存在泄露风险。
- 更稳妥的做法是创建专用 MySQL 用户,只赋
REPLICATION CLIENT和SUPER权限(PURGE所需),不用 root - 脚本中避免拼接密码字符串,改用配置文件方式:
mysql --defaults-extra-file=/path/to/my.cnf -e "PURGE ...",其中my.cnf内容为:
[client] user=cleaner password=xxx
- 记得给该配置文件设权限:
chmod 600 /path/to/my.cnf - 脚本里加时间校验,避免误删:比如加上
date -d "7 days ago" "+%Y-%m-%d %H:%M:%S"动态生成时间点
磁盘已满时,FLUSH LOGS 比 RESET MASTER 更安全
有人一着急就跑 RESET MASTER,它会清空所有 binlog 并重置序列号,导致从库彻底无法追平——除非你确定没有从库,且不需要任何恢复能力。
- 真正紧急释放空间,应该先执行:
FLUSH LOGS;,这会立即滚动出一个新 binlog 文件(如从000042切到000043),触发 MySQL 检查过期策略并清理旧文件 - 配合刚设好的
binlog_expire_logs_seconds,通常几秒内就能看到磁盘空间回落 - 如果
FLUSH LOGS后没反应,说明过期参数没生效或值设得太大,别硬删,先查SHOW VARIABLES确认 - 注意:
FLUSH LOGS是轻量操作,不影响连接和查询,可随时执行
真正容易被忽略的是主从延迟判断——很多线上事故不是因为参数没设,而是设了 7 天,但从库延迟超过 7 天却没人监控。清理策略生效的前提,是你清楚知道“最慢的那个从库”卡在哪。











