【分布式】两阶段提交

参考:《数据库系统概念》19.3,19.4

概念

分布式事务由一个站点发起,多个站点参与。事务必须保证要么在所有站点上都提交,要么在所有站点上都中止。

两阶段提交Two-Phase Commit,2PC)协议是最简单且使用最广泛的提交协议之一。

考虑一个例子,站点 S 0 S_0 S0 发起了事务 T T T,用 S i S_i Si 来表示各个参与执行事务的站点。

提交协议

当所有 S i S_i Si 都通知 S 0 S_0 S0 完成了 T T T 的执行时, S 0 S_0 S0 启动 2 P C 2PC 2PC 协议。

阶段1

  1. S 0 S_0 S0 在稳定存储器上记录日志 ,然后给 S i S_i Si 发送消息 prepare T.
  2. S i S_i Si 收到消息,确认是否愿意提交。
    1. 如果选择不提交,就记录日志 ,然后向 S 0 S_0 S0 发送消息 abort T.
    2. 如果选择提交,就记录日志 ,并将所有与 T T T 相关的日志写入稳定存储器中,然后向 S 0 S_0 S0 发送消息 ready T.

阶段2

  1. 如果 S 0 S_0 S0 收到所有 S i S_i Siready T 消息,就将日志 写入稳定存储器中,然后向 S i S_i Si 发送消息 commit T.
  2. 如果 S 0 S_0 S0 收到至少一个 abort T 或者间隔一段时间后没有收到全部消息,就将日志 写入稳定存储器中,然后向 S i S_i Si 发送消息 abort T.
  3. S i S_i Si 收到消息后,将消息记录到日志中。

故障处理

S 0 S_0 S0 S i S_i Si 发生故障有不同的处理方式。

某个站点 S i S_i Si 故障

S 0 S_0 S0 的行动

  1. 如果 S 0 S_0 S0 S i S_i Si 发送 ready T 之前发现 S i S_i Si 故障,就假定它发送了 abort T.
  2. 如果 S 0 S_0 S0 S i S_i Si 发送 ready T 之后发现 S i S_i Si 故障,就忽略它的故障.

S i S_i Si 恢复措施

S i S_i Si 从故障中恢复时,检查它的日志以判断应该做什么。

  1. 日志中存在 ,此时应执行 r e d o ( T ) redo(T) redo(T).
  2. 日志中存在,此时应执行 u n d o ( T ) undo(T) undo(T).
  3. 日志中仅存在 ,此时 S i S_i Si T T T 称作疑问事务,应当向 S 0 S_0 S0 或者其它 S i S_i Si 询问最终的处理结果。
  4. 日志中不存在上述三者,此时应执行 u n d o ( T ) undo(T) undo(T)。这说明 S 0 S_0 S0 没有收到来自 S i S_i Si 的回复。

对疑问事务的处理可能导致一直询问且影响其它事务进行,一个简单的改进是, S i S_i Si 在记录 日志时,将 T T T 所使用的锁记录下来。等站点恢复后,将这些锁重新申请,这样就不会阻塞与这些锁无关的事务。

S 0 S_0 S0 故障

S 0 S_0 S0 发生故障时, S i S_i Si 通过检查自己或其它 S i S_i Si 的日志以做出决定。

  1. 日志中存在 ,此时应执行 r e d o ( T ) redo(T) redo(T).
  2. 日志中存在 ,此时应执行 u n d o ( T ) undo(T) undo(T).
  3. 所有 S i S_i Si 的日志中都是仅存在 ,此时所有 S i S_i Si 必须等待 S 0 S_0 S0 恢复后才能得到答案。如果 T T T 持有 S i S_i Si 上的锁,那么 S i S_i Si 的其它事务也会收到影响,称作阻塞(blocking)
  4. 某些 S i S_i Si 的日志不存在 ,说明它们没有向 S 0 S_0 S0 发送过 ready T,此时直接执行 u n d o ( T ) undo(T) undo(T).

评价

2 P C 2PC 2PC 的主要缺陷在于协调器故障可能会导致阻塞。

感想

概念基本理解了,想找个成型的代码实例学习一下。

你可能感兴趣的:(SQL,学习笔记)