mysql 8.0 commit变快并非优化提交逻辑本身,而是默认启用更激进的group commit,协同binlog与innodb_log刷盘;其通过binlog_group_commit_sync_delay(微秒级,默认0但内核自动启等待窗口)、两阶段提交路径优化、performance_schema可观测性及合理binlog_cache_size(建议≥1mb)共同实现。

COMMIT 速度变快,不是因为 MySQL 8.0 “优化了提交逻辑”本身,而是它默认启用了更激进、更可靠的 Group Commit 实现,且与 binlog 和 innodb_log 的刷盘协同方式发生了实质性变化。旧版本(如 5.7)在高并发写入下容易卡在日志刷盘环节,而 8.0 把这个瓶颈大幅削弱了。
MySQL 8.0 默认启用 binlog_group_commit_sync_delay
MySQL 8.0 引入了两个关键参数来控制 binlog 的 group commit 行为:binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count。前者单位是微秒,默认值为 0,但注意:只要 sync_binlog=1(最安全模式),MySQL 8.0 内部会自动启用“等待窗口”机制——哪怕你没显式设 delay,内核也会在调用 fsync() 前短暂等待其他事务把 binlog event 推进 cache,从而凑成一批刷盘。
-
binlog_group_commit_sync_delay=0并不等于“不等待”,只是最小等待粒度为 0 微秒;实际是否等待,取决于当前是否有其他线程正排队进入binlog cache flush阶段 - 对比 5.7:即使
sync_binlog=1,5.7 的 binlog 刷盘基本是“单线程串行 fsync”,没有内置的等待合并逻辑,每个COMMIT都可能触发一次磁盘 I/O - 如果你手动把
binlog_group_commit_sync_delay设为1000(1ms),在中等并发下能明显观察到COMMIT耗时下降、吞吐上升,但要注意:延迟越高,单个事务的最坏延迟也越不可控
redo log 与 binlog 的两阶段提交(2PC)协同更紧
MySQL 的事务持久性依赖 InnoDB redo log 和 server 层 binlog 的一致。8.0 对内部 XA 的 prepare/commit 流程做了路径优化,尤其在 innodb_flush_log_at_trx_commit=1 + sync_binlog=1 组合下:
- 不再让 redo log 的
fsync和 binlog 的fsync完全独立调度;而是尽可能复用 I/O 请求队列,减少底层设备寻道次数 - 当多个事务同时到达 prepare 阶段时,8.0 更倾向于批量收集它们的 redo log LSN,并在一次
log_write_up_to()调用中完成刷盘,而不是逐个推进 - 这个行为在
information_schema.INNODB_METRICS中可通过log_os_log_written和log_pending_writes对比验证:8.0 的 pending writes 波动更平缓,说明写入更“聚堆”
performance_schema 暴露了真实的 group commit 效果
别只看 SHOW ENGINE INNODB STATUS,MySQL 8.0 把 group commit 的统计下沉到了 performance_schema,可以直接查:
SELECT * FROM performance_schema.events_statements_summary_by_digest WHERE DIGEST_TEXT LIKE '%COMMIT%' AND COUNT_STAR > 100;
更关键的是这张表:performance_schema.table_io_waits_summary_by_table,重点关注 mysql.binlog 这一行的 COUNT_WRITE 和 SUM_TIMER_WRITE —— 如果你发现 COUNT_WRITE 明显小于事务总数(比如 1000 次 COMMIT 只触发了 120 次 binlog 写入),就说明 group commit 正在生效。
- 5.7 中几乎不可能看到这种“写入次数远少于事务数”的现象,因为它的 binlog 写入粒度太细
- 8.0 下如果
binlog_cache_size设置过小(如仍沿用 5.7 的 32KB),会导致频繁 cache 溢出并强制刷盘,反而破坏 group commit 效果;建议至少设为1048576(1MB) - 使用
mysqlbinlog --verbose解析 binlog 文件,也能看到 events 是按“块”组织的,每块开头有Previous_gtids_log_event或Rotate_log_event,这就是 group commit 的物理痕迹
真正影响 COMMIT 速度的,从来不是“事务本身多大”,而是“有多少个事务能挤进同一个刷盘批次”。MySQL 8.0 把这个“挤”的机制从隐式经验逻辑,变成了可观察、可调节、默认就更积极的工程实现。最容易被忽略的一点是:它对 binlog_cache_size 和 max_allowed_packet 的敏感度更高了——这两个值一旦不合理,group commit 就会退化成 5.7 模式。











