两阶段提交如何防止最后一秒失败?

Gil*_*ili 64 database distributed-transactions

我正在研究两阶段提交如何在分布式事务中工作.据我所知,在阶段的最后阶段,事务协调器会询问每个节点是否准备好提交.如果每个人都同意,那么它会告诉他们继续并提交.

是什么阻止了以下失败?

  1. 所有节点都响应它们已准备好提交
  2. 事务协调器告诉他们"继续并提交",但其中一个节点在收到此消息之前崩溃
  3. 所有其他节点成功提交,但现在分布式事务已损坏
  4. 我的理解是,当崩溃的节点返回时,它的事务将被回滚(因为它从未得到提交消息)

我假设每个节点都运行一个普通的数据库,该数据库对分布式事务一无所知.我错过了什么?

Jas*_*aty 37

不,他们没有被指示回滚,因为在原始海报的情况下,一些节点已经提交.当崩溃的节点变得可用时,事务协调器会告诉它再次提交.

由于节点在"准备"阶段响应积极,因此即使从崩溃中恢复,也需要能够"提交".

  • 吉利:因为它承诺它能够在2PC的准备阶段. (7认同)
  • @Gili崩溃的数据库不必重放事务.传统数据库事务的工作方式是它们在事务日志中主动进行这些更改,只有在能够获取必要的行/表/页锁时才会发生这些更改.基本上在第一阶段之后,事务已经修改了数据库,但是其他查询在标记为已提交之前无法看到这些更改.剩下要做的就是将它们标记为已提交. (2认同)

Gil*_*ili 22

总结每个人的答案:

  1. 人们不能使用具有分布式事务的普通数据库.数据库必须明确支持事务协调器.

  2. 由于某些节点已经提交,因此未指示节点回滚.发生的事情是当崩溃的节点返回时,事务协调器告诉它再次提交.

  • 如果协调器在节点关闭时崩溃而节点在协调器仍然关闭时唤醒,会发生什么?节点然后做什么? (3认同)
  • 我建议为这个问题开一个单独的问题.我自己不知道答案,但我猜测节点在接受客户端连接之前等待协调器返回. (3认同)
  • 没有协调员,一切当然都会停下来。 (2认同)

Jon*_*ler 17

不是.第4点不正确.每个节点都在稳定的存储中记录它能够提交或回滚事务,因此它甚至可以在崩溃时执行命令.当崩溃的节点重新启动时,它必须意识到它具有处于预提交状态的事务,恢复任何相关的锁或其他控件,然后尝试联系协调器站点以收集事务的状态.

只有当崩溃的节点永远不会恢复时才会出现问题(然后其他一切都认为事务是正常的,或者当崩溃的节点返回时).

  • 没有; DBMS必须知道他们在2PC协议中的职责,并且关键职责是在协调器发出命令之前将事务保持在Go/No-Go状态.你失去了(自治).Informix实现了启发式回滚来处理消失的系统. (5认同)

小智 11

两阶段提交并非万无一失,只是为了在99%的时间内工作.

"该协议假定每个节点都有稳定的存储空间,其中有一个预写日志,没有节点永远崩溃,预写日志中的数据在崩溃中永远不会丢失或损坏,并且任何两个节点都可以进行通信彼此."

http://en.wikipedia.org/wiki/Two-phase_commit_protocol

  • 这句话说得不正确。在某些假设下,2PC 是 100% 正确的。对于这个问题,参与者必须持久存储预提交的数据,并且必须能够在重新启动后完成提交(如果协调员指示的话)。协调器还必须持久存储回滚或提交的最终决定,并在失败时重试。此外,所有参与者都不能永远崩溃,他们必须最终重新启动并拥有持久存储的数据。如果满足这些要求,2PC 就是 100% 正确的。如果不是,则可能是错误的。 (2认同)

Hen*_*ryR 7

有两种方法可以通过两阶段提交来解决问题.几乎所有这些都成为Paxos三阶段提交算法的一些变体.设计谷歌Chubby锁定服务的Mike Burrows基于Paxos,他说在我看到的一个讲座中有两种类型的分布式提交算法 - "Paxos和不正确的".

崩溃的节点在重新唤醒时可以做的一件事就是说"我从来没有听说过这个交易,它是否应该被提交?" 协调员,它将告诉它投票是什么.

请记住,这是一个更普遍的问题的示例:崩溃的节点在恢复之前可能会丢失许多事务.因此,非常重要的是,在恢复之后,应该先让协调员或其他副本与自己联系.如果节点本身无法判断它是否已经崩溃,那么事情就会变得更加复杂,但仍然易于处理.

如果使用仲裁系统进行数据库读取,则会掩盖不一致性(并使数据库本身知道).