连载中 10/22

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

2026-05-06 · 2446 阅读 · 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)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10101 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9873 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9294 阅读 · 21 评论 · 287 赞