分布式事务、3pc

对cmu440的3pc总结一下

前提回顾

这里几个问题回顾一下

  1. 分布式一致性?
    分布式系统中,数据库在许多节点都有副本,进行crud,需要每个节点达到一致性
  2. 什么是分布式事务?为什么要分布式事务?
    • 为了达到分布式一致性,需要分布式事务。
    • 分布式事务是指会涉及到操作多个数据库的事务。
  3. 分布式事务的关键?
    • 分布式事务处理的关键是必须有一种方法可以知道事务在任何地方所做的所有动作,提交或回滚事务的决定必须产生统一的结果(全部提交或全部回滚),所以需要一个协作者。
  4. 2pc的思想
    • 第一阶段:协作者广播VOTE_REQUEST,等待commit或者abort
    • 第二阶段:协作者根据收回的ack,广播一个全局commit或者abort

为什么需要3pc

这个问题还可以是"3pc解决了2pc存在的哪些问题?"

关于2pc的细节: cmu440(8) Distributed Concurrency Management 2
cmu440的3pc: cmu440(9) Distributed Concurrency Management 3
2pc存在的问题是当协作者崩溃时,参与者不能做出最后的选择。因此参与者可能在协作者恢复之前保持阻塞。
于是便有了3pc。避免了出现故障停机时的阻塞过程。

3pc的细节

分布式事务、3pc_第1张图片
3pc

分为了三阶段,将2pc的prepare阶段拆开两个阶段

  1. CanCommit阶段
    事务询问 协调者向参与者发送CanCommit请求。询问是否可以执行事务提交操作。然后开始等待参与者的响应。
    响应反馈 参与者接到CanCommit请求之后,正常情况下,如果其自身认为可以顺利执行事务,则返回Yes响应,并进入预备状态。否则反馈No
  2. PreCommit阶段
    根据参与者返回的请求,来决定是否进入PreCommit
  • 假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务的预执行。
    发送预提交请求 发送一个prepare-commit请求,进入PreCommit状态
    事务预提交 参与者接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。
    响应反馈 如果参与者成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。
  • 假如有任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。
    发送中断请求 协调者向所有参与者发送abort请求。
    中断事务 参与者收到来自协调者的abort请求之后(或超时之后,仍未收到协调者的请求),执行事务的中断。
  1. doCommit阶段
    进行真正的事务提交
  • 执行提交
    发送提交请求 协调接收到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者发送doCommit请求。
    事务提交 参与者接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。
    响应反馈 事务提交完之后,向协调者发送Ack响应。
    完成事务 协调者接收到所有参与者的ack响应之后,完成事务。
  • 中断事务 协调者没有接收到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。
    发送中断请求 协调者向所有参与者发送abort请求
    事务回滚 参与者接收到abort请求之后,利用其在阶段二记录的undo信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源。
    反馈结果 参与者完成事务回滚之后,向协调者发送ACK消息
    中断事务 协调者接收到参与者反馈ACK消息之后,执行事务的中断。

阻塞或故障恢复处理

  1. 参与者在pre-commit阶段阻塞,等待超时,判断协调者故障,集群其他的参与者可能处在ready、pre-commit或commit、abort状态。
    与COMMIT或者ABORT沟通,则转换为这个状态;
    如果全都处在pre-commit,则事务可以安全提交;
    如果全出在ready,则安全中止;
  2. 参与者在ready阻塞,则像2pc一样,询问其他所有节点所处在的状态,如果处在COMMIT、ABORT可以直接转换;如果处在INIT,就中止(存在INIT状态的节点);如果其他的节点都在ready状态,事务中止。

3pc总结

  1. 3pc是一个"非阻塞"协议,解决了2pc存在单点故障,导致节点持久阻塞的问题
  2. 3pc的状态满足下面2点:
    • 没有一个可以直接转换到Commit或者Abort状态的单独状态
    • 没有一个这样的状态:它不能做出最后决定,而且可以从它直接转换到- Commit状态。 Commit之前需要经过PRCOMMIT状态。

参考

三阶段提交-维基
三阶段提交协议如何避免协调者状态未知的情况?

你可能感兴趣的:(分布式事务、3pc)