1、前言
redo log + bin log 是现在 mysql 常用的一种配置,在 innerdb 没有成为 mysql 的默认引擎之前,mysql 已经又了 binlog 这种日志格式,它在 server 层。innerdb 有自己的 redo log 支持崩溃恢复,后面成为 mysql 的引擎过后,整个事务的过程变成一种两阶段提交的方式:
- 先写 redo log,redo log 处于 prepare 阶段
- 2.后写 binlog
- 3.binlog 写入之后,提交 redo log,整个事务 commit
2、问题讨论
现在设想两种情况:
A.如果已经写了 redo log,redo log 处于 prepare 阶段,写 binlog 之前崩溃了
答:此时 binlog 还没写,redo log 也没提交,所以崩溃恢复的时候,整个事务会回滚。这时 binlog 还没写,如果是主从复制的架构,binlog 的数据也不会传递到备库里。
B.如果是已经写了 binlog,但是 redo log 还没提交
答:mysql 目前的崩溃规则如下:
- 1.如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交
- 2.如果 redo log 里面的事务只有完整的 prepare,则判断对应的事务 binlog 是否存在并完整
* a.如果是,则提交事务
* b.否则,回滚事务
追问 B:处于 prepare 阶段的 redo log 加上完整的 binlog,重启就能恢复,mysql 为什么要这样设计
答:这个问题与数据与备份的一致性有关。如果写 binlog 后 mysql 崩溃,但是因为已经写入了,binlog 会被从库消费使用(或者使用 binlog 恢复库),所以主库上也要提交这个事务,保证主从一致性。
网友评论