核心机制两阶段提交的 5 大物理步骤为了压榨磁盘性能MySQL 将日志的“写入文件系统缓存write”与“物理持久化fsync”进行了精密拆解。以下是一个事务完整提交的物理历程1. redo log prepare: write物理动作每个事务各自将 redo log 从redo log buffer写入操作系统的Page Cache。状态此时日志已离开 MySQL 进程但仍处于系统内存中未真正落地 。2. binlog: write物理动作每个事务将自己的 binlog 从线程私有的binlog cache写入系统的Page Cache。目的为接下来的“组提交”积蓄力量。3. redo log prepare: fsync -- 【Redo Log 组提交发生在这里】物理动作MySQL 调用操作系统的fsync指令将Page Cache中处于prepare状态的 redo log 集中刷入磁盘 。黑科技组提交Group Commit由于多个并发事务生成的 LSN日志序列号是连续的第一个到达的事务会成为“组长”一次磁盘 IO 就能带走整组事务的日志 。这意味着并发越高IO 效率越高 。4. binlog: fsync -- 【Binlog 组提交发生在这里】物理动作将Page Cache中的 binlog 数据集体持久化到磁盘 。优化方案通过设置延迟参数如binlog_group_commit_sync_delay可以人为拉长等待时间让更多事务加入这一步的“刷盘班车”进一步降低 IOPS 。5. redo log commit: write物理动作在Page Cache中将事务状态从prepare标记为commit。为何不需要 fsync这是一个精妙的性能优化。由于前两步已经保证了 redo log 的prepare记录和完整的binlog都在磁盘上即使系统此时宕机重启后 MySQL 依然能根据这两者恢复事务 。因此最后的commit标记只需写到内存缓存即可无需再次昂贵的刷盘操作 。异常崩溃与自救指南为了方便理解我们假设在每一个物理步骤执行完的瞬间数据库服务器突然断电宕机。步骤 1 2写入 Page Cache 阶段未刷盘物理状态日志仅存在于操作系统的内存缓存Page Cache中 。崩溃后果由于数据没有落盘断电后这部分内存数据全部丢失 。重启恢复MySQL 重启后由于磁盘上完全没有该事务的痕迹该事务就像从未发生过一样。由于此时尚未给客户端返回“提交成功”这种丢失是符合一致性的 。步骤 3redo log prepare: fsync完成物理状态redo log 已持久化到磁盘状态为prepare但 binlog 还在内存或甚至还没写完 。崩溃后果磁盘上有prepare记录但没有对应的 binlog。重启恢复回滚Rollback。原因binlog 是主备复制的唯一依据。如果此时判定事务成功主库有数据但备库没有因为 binlog 丢了会造成严重的主备不一致。步骤 4binlog: fsync完成物理状态redo log 处于prepare状态binlog 已完整写入磁盘 。崩溃后果磁盘上同时具备了prepare记录和完整的 binlog但 redo log 里的commit标记还没写 。重启恢复自动提交Commit。原因既然 binlog 已经安全落盘意味着该事务一定会同步到从库。为了保证主从一致主库在重启后会扫描发现“prepare完整 binlog”的组合从而自动将该事务补全为提交状态 。步骤 5redo log commit: write完成物理状态事务在逻辑上已经彻底完成但在物理上redo log 里的commit标记可能还在 Page Cache 里没刷到磁盘 。崩溃后果虽然磁盘上可能还没看到commit标记但状态与步骤 4 完全一致。重启恢复自动提交Commit。原理同步骤 4。只要prepare记录和 binlog 都在即使commit标记没刷盘MySQL 也能确信这个事务是安全的从而完成恢复 。