
MySQL 在三种明确场景下会创建新的 binlog 文件:当前文件达到 max_binlog_size 限制、执行 FLUSH LOGS 命令或 MySQL 服务重启;理解这些时机对实现可靠的 binlog 消费(如 CDC)至关重要,可据此设计安全的位点(position)持久化策略。
mysql 二进制日志(binlog)文件切换时机对构建高可靠的数据变更捕获(cdc)系统至关重要——尤其当你的 java 应用使用 mysql-binlog-connector-java 实时解析 binlog 时,若进程意外崩溃,能否精准续读取决于你是否在恰当位置保存了位点(file name + position)。而位点有效性直接依赖于 binlog 文件的生命周期管理规则。
MySQL 并非按时间或固定事务数切换 binlog,而是基于以下三个确定性触发条件生成新 binlog 文件:
✅ 1. 文件大小达到 max_binlog_size 阈值
这是最常见场景。默认值为 1GB(max_binlog_size = 1073741824),可通过 SHOW VARIABLES LIKE 'max_binlog_size'; 查看。注意:MySQL 允许单个事件跨文件写入,因此实际文件大小可能略超该值(通常不超过一个完整事件长度),但绝不会在事件中途截断。
✅ 2. 手动或自动执行 FLUSH LOGS
该命令强制关闭当前 binlog 并新建一个。典型触发方包括:
- 运维手动执行 FLUSH LOGS;
- mysqldump --flush-logs 备份时自动调用
- mysqladmin flush-logs
- 某些高可用工具(如 MHA)在主从切换时也可能触发
✅ 3. MySQL 服务重启
无论正常关闭(systemctl stop mysql)还是异常崩溃后恢复,只要 mysqld 重新启动,就会创建全新的 binlog 文件(如从 binlog.000012 切换至 binlog.000013)。
? 关键实践建议(针对你的 Java CDC 应用):
- ✅ 位点必须持久化到外部存储(如数据库/Redis/ZooKeeper),而非内存或本地文件;每次成功处理一批事件后,立即更新 filename 和 position(推荐原子写入)。
- ✅ 位点保存时机应选在「事件已成功处理且确认提交」之后,避免“处理完成但未存位点即崩溃”导致重复消费。
- ⚠️ 切勿假设 binlog 文件名单调递增即代表时间顺序:虽然通常如此,但 FLUSH LOGS 或手动 PURGE BINLOGS 可能造成编号空缺或重用(如开启 log_bin_index 异常时),始终以 SHOW BINARY LOGS 结果为准。
- ?️ 启用 binlog_checksum = CRC32(MySQL 5.6.2+ 默认),并在客户端校验 checksum,防止网络传输或磁盘损坏导致的事件解析错误。
? 示例:获取当前活跃 binlog 状态
-- 查看所有 binlog 文件及其大小 SHOW BINARY LOGS; -- 查看当前正在写入的 binlog 文件名和位置(即最新位点) SHOW MASTER STATUS;
? 代码片段(使用 mysql-binlog-connector-java 安全保存位点)
// 假设 event 是已成功处理的最后一个 BinlogEvent String fileName = event.getFileName(); // e.g., "binlog.000015" long position = event.getPosition(); // e.g., 123456789 // 同步写入外部存储(务必保证原子性与持久性) checkpointStore.saveCheckpoint(fileName, position);
? 总结:binlog 切换是事件驱动、非周期性的过程,其确定性源于上述三类可控操作。将位点保存逻辑与这三类边界对齐(尤其是 FLUSH LOGS 和重启前后的窗口),配合幂等消费设计,即可构建零丢失、高可用的变更数据捕获链路。











