两阶段提交¶
由于存在redo log 和 binlog ,而他们两是相互独立的。而事务提交必须确保两者同时有效。不然会出现不一致的情形。
- 阶段1:
redo log写盘,InnoDB 事务进入prepare状态 - 阶段2:
binlog写盘,InooDB 事务进入commit状态
时间1宕机:这个时候 redo log已经写入磁盘。bin log没有刷到磁盘所以会消失。服务器从故障中恢复时,读取磁盘中的redo log ,但是由于对应的redo log项还是prepare状态,就要判断binlog 是否完整,如果binlog完整则提交事务,如果binlog不完整则回滚事务。
时间2宕机:redo log 和 binlog都已经存磁盘,从redo log恢复即可

联系¶
共同的数据字段 : XID
- 崩溃恢复的时候,会按顺序扫描 redo log:如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;
- 如果碰到只有 parepare、而没有 commit 的 redo log,就根据 XID 去 bin log 找对应的事务。
语句执行流程¶
- 分配事务 ID ,开启事务,获取锁,没有获取到锁则等待。
- 执行器先通过存储引擎找到 id = 1 的数据页,如果缓冲池有则直接取出,没有则去主键索引上取出对应的数据页放入缓冲池。
- 在数据页内找到 id = 1 这行记录,取出,将 age 改为 30 然后写入内存
- 生成 redolog undolog 到内存,redolog 状态为 prepare
- 将 redolog undolog 写入文件并调用 fsync
- server 层生成 binlog 并写入文件调用 fsync
- 事务提交,将 redolog 的状态改为 commited 释放锁
三阶段提交¶
3PC相较于2PC而言,解决了协调者挂点后参与者无限阻塞和单点问题,但是仍然无法解决网络分区问题。
阶段一 : CanCommit 1、事务询问 2、各参与者节点向协调者反馈事务询问的响应 阶段二 : PreCommit 根据阶段一的反馈结果分为两种情况
- 执行事务预提交
- 发送预提交请求 协调者向所有参与者节点发送preCommit请求,进入prepared阶段
- 事务预提交 各参与者节点接受到preCommit请求后,执行事务操作
- 各参与者节点向协调者反馈事务执行
- 中断事务 任意一个参与者节点反馈给协调者响应No时,或者在等待超时(协调者等待参与者)后,协调者还未收到参与者的反 馈,就中断事务,中断事务分为两步: 1)协调者向各个参与者节点发送abort请求 2)参与者收到abort请求,或者等待超时时间后,中断事务(参与者等待协调者)
阶段三 : doCommit 1、执行提交
- 发送提交请求 协调者向所有参与者节点发送doCommit请求
- 事务提交 各参与者节点接受到doCommit请求后,执行事务提交操作
- 反馈事务提交结果
- 事务完成 协调者接受各个参与者反馈的ack后,完成事务
2、中断事务
- 参与者接受到abort请求后,执行事务回滚
- 参与者完成事务回滚以后,向协调者发送ack
- 协调者接受回滚ack后,回滚事务