439 字
2 分钟
MySQL 为什么需要 Redo Log 与 Binlog 两阶段提交
同时启用 InnoDB 和 Binlog 时,一次事务提交需要让两份日志描述同一批变更。若先提交引擎事务再写 Binlog,二者之间宕机可能出现 InnoDB 事务已提交、Binlog 缺少该事务事件;注意“事务提交”不等于对应数据页已写入表空间。若先写 Binlog 再提交引擎,宕机则可能出现副本重放了主库实际未提交的数据。两阶段提交用于协调这两个日志。
简化时序是:InnoDB 写 Redo Log 的 prepare 状态;Server 写 Binlog 并按配置同步;InnoDB 再把事务标为 commit。若崩溃发生在 prepare 后,恢复时 InnoDB 检查对应 Binlog 是否完整:存在则提交 prepared 事务,不存在则回滚。真实内部实现包含事务协调细节,不要把这个简化模型误解为所有日志写入都只有单次磁盘操作。
可靠性还要看 sync_binlog 与 innodb_flush_log_at_trx_commit 等配置。sync_binlog=1 通常要求每次提交同步 Binlog;更宽松设置可提高吞吐,但崩溃时可能丢失近期 Binlog。两阶段提交解决日志一致性协议问题,不自动保证异地副本已应用,也不取代备份。
追问
- prepare 后崩溃,如何决定提交还是回滚? 恢复阶段查找对应 Binlog 事务是否完整记录;有则提交,无则回滚。
- 两阶段提交等于分布式 XA 吗? 此处指 MySQL 内部协调 InnoDB Redo 与 Binlog 的提交过程,不是应用层通用 XA 事务。
- 主库提交成功为何副本仍可能落后? 主库提交与副本读取、执行、持久化日志是不同阶段,复制默认存在延迟。
MySQL 为什么需要 Redo Log 与 Binlog 两阶段提交
https://blog.xqcherry.top/posts/interview/mysql/two-phase-commit/ 目录