连载中 10/22

binlog 与两阶段提交:crash-safe 的秘密

2026-05-06 · 2439 阅读 · 0 评论 · 0 赞

两本日志,两个主人

第 7 篇讲过 redo log,但 InnoDB 里还有另一本日志 binlog,两人分工不同:

维度redo logbinlog
所属层InnoDB 引擎层MySQL Server 层(所有引擎都有)
内容物理日志:某页做了什么修改逻辑日志:语句或行变更
写法固定大小循环写追加写,写满切换新文件
用途崩溃恢复主从复制、时间点恢复

binlog 的三种格式

格式记录什么优劣
statement原始 SQL 语句省空间;但 NOW()、UUID()、LIMIT 这类不确定执行的内容会让主从各算各的,数据不一致
row(默认)每行数据的变更前后镜像最可靠,从库回放结果确定;一条大 update 会产生海量事件
mixed多数用 statement,检测到不确定内容切 row折中;row 已是默认,mixed 存在感降低

第 13 篇讲读写分离和第 21 篇讲恢复时都会用到 binlog,row 格式是主从安全性的基石。

问题:两本日志能不能各写各的

假设提交时先写完 redo 再写 binlog,中间崩溃:重启后 redo 重放,主库数据是新的,但 binlog 没写——从库永远拿不到这条修改,主从不一致。反过来先 binlog 后 redo,崩溃后主库丢了这条数据,从库却有一条主库不存在的记录。只要顺序执行就可能断在中间,需要的是「要么都成、要么都不算」的原子协议——这就是两阶段提交。

两阶段提交的时序

  • 阶段一(prepare):redo log 写入并 fsync,标记为 prepare 状态;
  • 阶段二(commit):binlog 写入并 fsync,然后把 redo log 标记为 commit 状态。

崩溃恢复时的判定规则只有一条:redo 处于 prepare,就去查对应的 binlog——binlog 完整就提交,不完整就回滚。binlog 的事件有内部校验,写完整才算数。于是两个方向都对:redo 成 binlog 没成 → 回滚,主从都没有;binlog 成了 → 提交,主从都有。binlog 成了没提交的,恢复时由它来补票

顺带解开第 9 篇结尾的悬念:主从复制的本质就是从库按 binlog 重放,而两阶段提交保证的「binlog 与主库数据一致」,正是主从一致性的前提。

双 1 配置与组提交

# 事务安全的最高配置(默认值)
innodb_flush_log_at_trx_commit = 1   # redo 每次提交 fsync
sync_binlog = 1                      # binlog 每次提交 fsync

两个 1 同时在线,才算真正的 crash-safe:最多丢一个事务都不行。代价是每次提交两次 fsync——机械盘时代这是重负,如今 SSD 上配合组提交(group commit)(多个并发事务的 fsync 合并成一次)扛住高并发完全没问题。报表库、日志归档库等能容忍极端情况丢 1 秒的场景,可以放成 2 和 100 这类组合换性能,交易链路别动

本篇划重点

  • redo 物理循环写管崩溃恢复,binlog 逻辑追加写管复制与恢复;
  • 两阶段提交 = redo prepare → binlog → redo commit,恢复时以 binlog 完整性定生死;
  • 双 1 是交易链路的底线,组提交让双 1 不再是性能包袱。

日志的地基全部打完,从下一篇起进入高可用三部曲:先从零动手搭一主两从——my.cnf 参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO,一条不落。

咖啡凉了,记得趁热喝。

503

10 年全栈工程师 · 503咖啡馆主理人

#MySQL#binlog#两阶段提交#crash-safe#双1配置

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 5 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞