MySQL 里边那个 Binlog 组提交到底是怎么搞的,原理和实现细节聊一聊
- 问答
- 2026-01-19 10:41:05
- 1
要理解组提交,得先知道为什么需要它,简单说,就是为了解决一个性能瓶颈,在早期版本的 MySQL 里,为了保证 Binlog(二进制日志,记录所有修改数据库的操作)和存储引擎(InnoDB)的 Redo Log(重做日志,保证事务持久性)在事务提交时都能安全地写入磁盘,并且两者的逻辑顺序一致,MySQL 采用了一种“两阶段提交”的方式。
这个两阶段提交本身没问题,问题是落盘的方式,最开始,MySQL 是这么干的:当一个事务要提交时,它先让 InnoDB 把 Redo Log 刷到磁盘(Prepare 阶段),然后马上把 Binlog 也刷到磁盘(Commit 阶段),最后再让 InnoDB 把事务标记为最终提交完成,这个过程里,每次事务提交都会引发至少两次磁盘写入(Redo Log 刷盘和 Binlog 刷盘),磁盘写入(尤其是机械硬盘的随机 I/O)是非常慢的操作,如果事务很频繁,系统就会卡在等待磁盘 I/O 上,吞吐量根本上不去,这就好比你去银行办业务,每个人办完都要柜员单独跑进金库存一次钱,效率极低。

组提交就是为了解决这个“每次提交都刷盘”的低效问题而生的,它的核心思想非常直观:把多个事务的刷盘操作合并成一次,让大家“组团”去刷盘,从而摊薄每次刷盘的成本。
具体是怎么“组团”的呢?我们一步步看 MySQL 是如何实现 Binlog 组提交的,这个过程可以看作一个“排队”和“搭便车”的游戏,根据 MySQL 官方手册和其内部的实现逻辑,主要分为三个阶段(对应三个队列):

-
Flush 阶段(刷 Binlog 到文件系统缓存):
- 第一个到达的事务(我们叫它“队长”)会主动创建一个队列,并开始收集一段时间内(非常短)所有准备提交的其他事务。
- 在这个阶段,“队长”和它的“队员们”一起,把各自的 Binlog 事件写入到 Binlog 文件的内存缓冲区中,注意,这里只是写到操作系统缓存,还没真正落到物理磁盘。
- 这个阶段结束时,“队长”会负责将这一整批 Binlog 数据从内存缓冲区同步(
fsync)到磁盘,这是第一次也是最重要的一次磁盘 I/O,关键是,这次刷盘是为整个小组服务的,几十个甚至几百个事务的 Binlog 通过一次 I/O 操作就全部持久化了,这大大减少了 I/O 次数。
-
Sync 阶段(等待 Binlog 落盘):

- 这个阶段其实和 Flush 阶段紧密相连,在 Flush 阶段,“队长”在执行
fsync的时候,其他新来的事务会进入一个等待队列,它们会等着这次组刷盘完成。 - 一旦“队长”带领的这批事务的 Binlog 成功落盘,Sync 阶段就结束了,队列里所有等待的事务的 Binlog 都已经被确认写入磁盘。
- 这个阶段其实和 Flush 阶段紧密相连,在 Flush 阶段,“队长”在执行
-
Commit 阶段(InnoDB 引擎提交):
- Binlog 已经安全了,接下来轮到存储引擎干活。
- 同样,这里也采用了组提交的思想,在 Binlog 同步完成后,这些事务会按顺序进入 InnoDB 的提交队列。
- InnoDB 引擎会按照顺序,批量地将这些事务在引擎层标记为提交状态(这里涉及 Redo Log 的清理等操作),虽然这个阶段可能也需要 I/O,但通过批量处理,效率也比单个提交高很多。
你可以把整个过程想象成:Flush 阶段的“队长”负责组织大家把信(Binlog)塞进同一个大邮包,然后一次性寄出(刷盘),寄出后,大家再一起去邮局(InnoDB)批量确认收货(引擎提交)。
这里有个关键点:Redo Log 的刷盘时机。 你可能注意到,在组提交模式下,Redo Log 是在 Binlog 之前刷盘的(在 Prepare 阶段),但 MySQL 做了一个很重要的优化:它设置了一个全局的锁,在 Flush 阶段收集事务时,这个锁会被持有,这意味着,在 Redo Log 准备(Prepare)完成之后、Binlog 刷盘之前,虽然 Redo Log 已经写入了文件系统缓存,但并不会立即刷盘,它会等待,直到 Flush 阶段的“队长”触发 Binlog 刷盘时,顺带将这个全局锁释放,而释放这个锁的动作,会触发一次 Redo Log 的刷盘,这样一来,多个事务的 Redo Log Prepare 刷盘操作,也有机会被合并成一次,这进一步提升了性能。
Binlog 组提交的精髓就是“化零为整”,通过将多个事务的 Binlog 写入和刷盘操作捆绑在一起,将原本每个事务都需要经历的昂贵磁盘 I/O,分摊到一组事务上,极大地提升了在高并发写场景下的数据库吞吐量,这个特性对于 MySQL 的复制性能和整体写入能力至关重要。
(参考资料:MySQL 5.7 参考手册 “Group Commit” 相关章节,以及基于 MySQL 源码相关逻辑(如 MYSQL_BIN_LOG::ordered_commit 函数)的通用实现原理分析。)
本文由黎家于2026-01-19发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/83616.html
