二阶段提交

要讲清楚二阶段提交首先要有几点概念!
1.Mysql分为
会话层-> SQL服务层-> 存储引擎层(INNODB MYISAM?? MEMORY) -> 物理文件系统

MYsql主从模式是在SQL服务层同步 行记录变化(是逻辑变化)
那么就意味着主从模式下主从节点的存储引擎可以是不同的.(例如主节点INNODB,从节点是MEMORY 当Redis用哈哈哈)
Binlog 隶属于服务层
ReDoLog 隶属于存储引擎层
所以主从节点同步是同步Binlog
而MYSQL重启后是使用RedoLog进行恢复(原因是Binlog记录的是逻辑变化,而一个逻辑修改对应者N个物理修改,这些N个物理修改并不是原子性的)
Redo 是物理日志,记录的是页级别的修改(哪页、偏移、写了什么字节)
在 crash recovery 时,InnoDB 会 只以磁盘上的 Redo 日志为依据进行重放,内存中的 Redo buffer 丢失
所以RedoLog和Binlog的目的是不同的
但是RedoLog和Binlog想表达的东西又是一样的,即修改XXXX记录的XXX值
故需要同步两者之间的状态,否则会出现主从数据不一致的情况.

当一个事务执行的时候
首先写入UndoLog做一下旧版本备份(便于后续回档)
然后写RedoLogBuffer
修改内存页 / Buffer Pool
当事务提交的时候,存储引擎层RedoLog刷盘 并标记为Prepare状态
服务层提交Binlog 并通知存储引擎RedoLog改成Commit状态

崩溃阶段 Redo 是否已刷盘 / 标记 Prepare Binlog 是否写刷成功 恢复结果
在 PREPARE 之后、Binlog 之前 Binlog 没有记录 → 该事务被回滚,Undo 撤销其变更
Binlog 写成功但引擎未 Commit 标记 Binlog 有记录 → 补写引擎 commit 标记 → 事务提交
在 Commit 标记阶段或之后 事务已被 commit → 恢复为已提交状态
在 redo 未刷盘阶段 否(或未达 binlog 阶段) 修改未持久化 → 事务被回滚、不生效

如果不使用二阶段提交会发生什么?

RedoLog提交 ->binlog提交失败->恢复时,innodb根据RedoLog重做 –>导致服务层和存储引擎层数据不一致