两阶段提交的过程
当事务提交后,有一个两阶段提交策略。
在开启两阶段提交时,会开启一个 XA 事务(宏观上的事务),
Prepare 阶段:将 redo log 的状态设置为 prepare,然后将 事务XID 写入 redo log,然后提交 redo log
Commit 阶段:将事务 XID 写入bin log,然后对 bin log 刷盘,最后将 redo log 的状态设置为 commit
当断电后,进行崩溃恢复时,会按照顺序扫描 redo log 文件
-
会首先查看 redo log 的状态,如果 redo log 的状态为 commit,则说明事务的两阶段提交已经完成,可以放心进行数据恢复。
-
如果 redo log 状态为 prepare,则检查 redo log 中的 XID
-
再根据 XID 去 bin log 中进行查找,如果 bin log 中不存在 XID,则说明 虽然 redo log 刷盘了,但是 bin log 没有刷盘,此时会进行事务回滚(根据 undo log 回滚)
-
如果 bin log 存在 XID,则虽然 redo log 处于 prepare 状态,但 bin log 已经刷盘了,此时会对事务进行提交。同时也可以放心进行数据恢复。
为什么有两阶段提交
主要是为了保证主从数据库一致性。
若没有两阶段提交,可能发生 redo log 已经刷入磁盘但 bin log 没有刷入磁盘,或者 bin log 已经刷入磁盘而 redo log 没有刷入磁盘的情况。如果是前者,若断电,则崩溃恢复后主数据库的数据可以恢复,而从数据库从 bin log 中获取到的数据是有缺失的,从而导致主从不一致。如果是后者,若断电,则恢复后,主数据库的数据会丢失,而从数据库的数据可以恢复完整,也会导致主从不一致现象。