在 MySQL 8.0 中,binlog_expire_logs_seconds 是用于控制 binlog 保留时长的秒级参数,已经正式取代了按天计算且被弃用的 expire_logs_days。它的优势非常明显:日志保留策略可以精确到小时甚至分钟,在跨时区部署时也更统一;同时,binlog 清理由事件触发,执行优先级更高,有助于避免二进制日志持续堆积、占满磁盘空间。

MySQL binlog_expire_logs_seconds 是什么,为什么它比 expire_logs_days 更重要
从 MySQL 8.0.28 起,控制二进制日志保留时间的首选配置项,已经由 expire_logs_days 切换为 binlog_expire_logs_seconds。原因也很清楚:后者按秒设置,控制粒度更细;前者只能按天配置,并且已被官方标记为 deprecated。特别要注意的是,在 8.0.28 及以上版本中,如果仍然继续使用 expire_logs_days,MySQL 虽然通常不会直接报错,但该参数实际上不会生效,最终可能导致 binlog 长期堆积,无法按预期自动清理。
实操建议:
- 先确认 MySQL 版本:
SELECT VERSION();,如果版本 ≥ 8.0.28,优先配置binlog_expire_logs_seconds - 该变量支持动态调整,无需重启数据库:
SET GLOBAL binlog_expire_logs_seconds = 259200;(即 3 天) - 写入配置文件时,必须放在
[mysqld]段下,例如:binlog_expire_logs_seconds = 604800
- 注意:如果同时设置了
expire_logs_days和binlog_expire_logs_seconds,以后者优先
手动清理 binlog 之前,先确认当前状态与依赖关系
直接执行 PURGE BINLOGS 的确很快,但也容易误删正在被主从复制或备份工具使用的二进制日志。正式操作前,务必先检查以下内容:
- 查看当前所有 binlog:
SHOW BINARY LOGS;,重点关注File_size列,体积较小的文件可能只是刚切换出来的空日志 - 查看复制位点(主从复制场景):
SHOW SLA VE STATUSG,关注Relay_Master_Log_File和Exec_Master_Log_Pos,确保不会删除从库尚未消费完成的日志 - 查看 GTID 集合(启用 GTID 时):
SELECT @@global.gtid_executed;,PURGE不能删除其中任何事务所对应的 binlog 文件 - 检查备份工具依赖:Percona XtraBackup、mydumper 等工具通常会在备份结束后记录
binlog filename + position,清理前需要核对备份元数据
PURGE BINLOGS 的两种安全用法:按时间删除 vs 按文件名删除
按时间清理 binlog 看起来更直观,但 MySQL 实际上是根据 binlog 文件头的时间戳来判断,而这个时间戳对应的是文件创建时间,并不是最后一次写入时间。在高负载场景下,可能会出现几分钟误差。相比之下,按文件名清理通常更稳妥:
- 按文件名清理(推荐):
PURGE BINLOGS TO 'mysql-bin.000123';—— 保留包括000123在内及之后的全部日志,删除它之前的日志文件 - 按时间清理(需谨慎):
PURGE BINLOGS BEFORE '2024-05-20 00:00:00';—— MySQL 会找到第一个文件头时间 ≥ 该时间点的日志文件,再删除它之前的所有文件;如果没有任何文件满足条件,则不会删除任何内容 - 执行后应立即验证:
SHOW BINARY LOGS;,确认结果是否符合预期,尤其要关注最旧文件的File名称和File_size - 不要在业务高峰期执行
PURGE,因为该操作会短暂加全局锁,可能阻塞 DDL 或大事务提交
监控 binlog 异常增长,避免磁盘空间被占满
即使已经设置了 binlog_expire_logs_seconds,二进制日志仍然可能因为以下原因快速增长:
- 主库长时间没有写入:binlog 不会自动轮转,旧日志也无法过期,因为没有新文件触发清理机制,此时需要手动执行
FLUSH LOGS强制切换日志 - 从库延迟严重:主库通常会保留从库尚未读取的 binlog,
SHOW SLA VE STATUS中Seconds_Behind_Master数值过大时需要重点关注 - 开启了
binlog_row_image = FULL且频繁更新大字段:每次行变更都会记录完整镜像,导致 binlog 体积迅速膨胀 - 监控建议:可以使用
du -sh /var/lib/mysql/mysql-bin.*定期统计日志占用,或查看information_schema.INNODB_METRICS中log_writes指标的变化趋势
真正棘手的往往不是“怎么删除 binlog”,而是“为什么 binlog 删不掉”——问题通常卡在复制延迟、GTID 范围限制,或备份工具尚未释放位点。每次清理前只需花两分钟检查一下 SHOW SLA VE STATUS 和 SELECT @@global.gtid_executed;,就能尽量避开大多数线上故障风险。
