SHOW BINARY LOGS用于列出MySQL当前所有二进制日志文件名及字节大小,按生成时间升序排列,通过间隔执行对比最新文件size变化可估算平均生成速率,但不包含正在写入的活跃日志。

如何用 SHOW BINARY LOGS 快速查看当前 Binlog 文件大小和增长趋势
这是最直接、无需额外工具的方法,适合日常巡检。执行 SHOW BINARY LOGS; 会列出所有现存 binlog 文件名及其文件大小(单位字节),按生成时间升序排列。
关键点在于:连续两次执行该命令(间隔固定时间,比如 5 分钟),对比 mysql-bin.0000xx 最新文件的 size 变化量,就能粗略估算生成速度。例如:
mysql> SHOW BINARY LOGS; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000012 | 1048576 | | mysql-bin.000013 | 8325412 | +------------------+-----------+
若 5 分钟后 mysql-bin.000013 的 File_size 变为 12485760,说明这 5 分钟内新增约 4.1MB,即约 14KB/s。
- 注意:该命令只显示已刷盘完成的文件,正在写入的当前 active binlog 不计入统计(
SHOW MASTER STATUS才显示它) - 如果
File_size长期卡在很小值(如123),大概率是log_bin没真正启用,或配置未生效 - 该方式无法捕获瞬时尖峰,仅反映平均速率;高频率执行(如每秒)反而增加主库压力,不推荐
为什么 du -h 比 SQL 查询更准,但要注意文件句柄延迟
Binlog 是普通文件,Linux 下直接用 du -h /var/lib/mysql/mysql-bin.* 查看磁盘占用,结果比 SHOW BINARY LOGS 更真实——因为它包含尚未被 MySQL 刷新到索引中的临时写入、以及 fsync 延迟导致的“已写未同步”部分。
但必须注意一个坑:du 统计的是文件系统层面的大小,而 MySQL 进程可能仍持有旧 binlog 文件的打开句柄(尤其在 PURGE 后未重启服务时)。此时即使文件已被逻辑删除,du 仍会算入,造成误判。
- 验证是否残留句柄:运行
lsof -nP -p $(pgrep mysqld) | grep 'mysql-bin' - 若发现已 PURGE 的文件仍在输出中,说明 MySQL 还没释放,需等待或考虑重启 mysqld(生产环境慎用)
- 建议监控脚本中优先用
du,但加一层判断:只统计ls -t /var/lib/mysql/mysql-bin.* | head -n 20中最新的 20 个文件,避开极老文件干扰
binlog_cache_use 和 binlog_cache_disk_use 能暴露什么问题
这两个状态变量不直接反映日志体积,却能揭示 Binlog 生成效率瓶颈。执行 SHOW GLOBAL STATUS LIKE 'binlog_cache%'; 查看它们的累计值。
当 binlog_cache_disk_use 占 binlog_cache_use 比例持续高于 5%,说明大量事务因缓存不足被迫写临时磁盘文件,这不仅拖慢事务提交,还会让 Binlog 实际写入量远超预期(临时文件内容最终也要落盘进 binlog)。
- 典型诱因:
binlog_cache_size设置过小(默认仅 32K),而业务存在大批量单事务 DML(如一次插入 10 万行) - 解决方法:调大
binlog_cache_size(如设为512K),同时观察max_binlog_cache_size是否被触发(若频繁出现ER_TRANS_CACHE_FULL错误,则需同步调大后者) - 注意:
binlog_cache_size是每个事务独占内存,设置过大可能引发连接数多时的内存压力
自动清理失效时,expire_logs_days 为何不生效
设置了 expire_logs_days = 7 却发现 binlog 越积越多,常见原因不是参数错,而是 MySQL 实例从未触发过自动清理时机。
MySQL 只在两个时刻检查并删除过期 binlog:实例启动时 和 执行 FLUSH LOGS 或 mysqladmin flush-log 时。如果实例常年不重启、也无人手动刷新日志,那这个参数就形同虚设。
- 验证是否真失效:查
SHOW VARIABLES LIKE 'expire_logs_days';确认值已生效;再查SHOW BINARY LOGS;中最老文件的生成时间,对比当前时间是否超期 - 强制触发清理:执行
FLUSH LOGS;(会新建一个 binlog,同时触发过期扫描) - 长期方案:在 crontab 里定期执行
mysql -e "FLUSH LOGS;"(如每天凌晨),确保清理机制被激活 - 注意:
PURGE BINARY LOGS BEFORE是即时清理,但需人工计算时间点;expire_logs_days是懒清理,依赖触发点
监控 Binlog 生成速度本质是监控“数据变更压力”,文件大小只是表象。最容易被忽略的是:sync_binlog 设置(如设为 0)会让 File_size 显示严重滞后于实际磁盘写入量,此时仅靠 SHOW BINARY LOGS 会低估真实增长。











