分布式一致性协议 :2pc 二阶段提交的疑问

clipboard.png

为什么上图非要强调说 “唯一收到commit消息的参与者挂了之后”, 即使选举了新的协调者, 事务状态也无法确定

  1. 个人总感觉, 假设有三个参与者, 在第二阶段, 即使有两个参与者收到了commit, 第三个参与者在挂了之后, 重启后, 协调者也无法得知它的事务到底有没有被提交啊!
  2. 关于二阶段提交的另一个问题:
    在第二阶段, 参与者 无论是执行commit还是rollback, 在执行完成后, 都会响应ack
    那如果此时返回给协调者时, 协调者超时, 或者宕机, 这样到底算什么情况?

    感觉好多资料都是说的很简单(不一致, 单点, 同步阻塞), 但个人感觉, 这些问题也得细分, 看到底是哪个阶段中的哪个时段发生的, 这样问题才会暴露出来

阅读 857
评论 2018-04-17 提问
    1 个回答
    justjavac
    • 46.7k

    异常分 3 种情况:

    1. 协调者不宕机,参与者宕机;
    2. 协调者宕机,参与者不宕机;
    3. 协调者宕机,参与者也宕机;

    对于(1),当在事务进行过程中,有参与者宕机时,他重启以后,可以通过询问其他参与者或者协调者,从而知道这个事务到底提交了没有。

    对于(2),协调者宕机后,可以起新的协调者,然后查询所有参与者的状态是否有 commit 的,如果有,则继续 commit,如果都没有,则 abort。

    对于(3),是唯一 2PC 不能解决的:当协调者在发出 commit 消息后宕机了,而唯一收到这条命令的一个参与者也宕机了,这个时候这个事务就处于一个未知的状态,没有人知道这个事务到底是提交了还是未提交,从而需要数据库管理员的介入,防止数据库进入一个不一致的状态。当然,如果有一个前提是:所有节点或者网络的异常最终都会恢复,那么这个问题就不存在了,协调者和参与者最终会重启,其他节点也最终也会收到commit T的信息。

    评论 赞赏