发生在数据库内部的两阶段提交
// 语句为update T set c = c + 1 where ID = 2

在最后提交事务时有三个步骤:
- 写入 redo log, 处于 prepare 状态
- 写 binlog
- 修改 redo log 状态为 commir
因为 redo log 的 提交分为 prepare 和 commit 两个阶段,所以称为两阶段提交
思考一下为何需要两阶段提交
- 假如 redo log 不分为 prepare 和 commit 怎么办,在写完 redo log 后 没有写 binlog 会发生的情况:
(1) 先写 redo log 再写 bin log,此时 c = c + 1的这个数据页的变化已经写入其中,恢复数据时,c = c + 1,但是 binlog 中没写,即不包含此语句,此时进行恢复会发现与原数据库的值不同。
(2)先写 binlog 再写 redo log, 此时 c = c + 1 的这个语句已经写入了其中,但是数据页的变更没有写入 redo log 中, redolog 中的 LNS 就会大于数据页中的 LNS,而此时并未提交 c = 0,但是 此时 bin log 中记录 c = c + 1, 恢复出来的时候就会发现完全不同。
崩溃恢复
包括一下两个情况,时刻 A 以及 时刻 B
- 时刻A 时, 写入 redo log,此时处于 prepare 阶段,然后崩溃,此时没有写 binlog
然后会出现一些问题:此事务处于 prepare 状态,但是没有写入 binlog 。在恢复时,此时此事务还未提交,此时根据 bin log ,恢复的数据为 c = c;
- 时刻 B 时,写入了 bin log 但是未提交事务为 commit 状态,此时 bin log 中存在对应的事务,此时则提交事务,恢复数据为 c = c + 1 ;
