Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 两阶段提交如何防止最后一秒失败?_Database_Distributed Transactions - Fatal编程技术网

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

Database 两阶段提交如何防止最后一秒失败?,database,distributed-transactions,Database,Distributed Transactions,我正在研究两阶段提交如何在分布式事务中工作。我的理解是,在阶段的最后一部分,事务协调器询问每个节点是否准备好提交。如果每个人都同意,那么它会告诉他们继续并做出承诺 如何防止以下故障 所有节点都响应它们是 准备好了吗 交易 协调员告诉他们“继续” 和提交“但其中一个节点 在收到此消息之前崩溃 信息 所有其他节点都已成功提交,但现在分布式事务已损坏 据我所知,当崩溃节点返回时,其事务将被回滚(因为它从未收到提交消息) 我假设每个节点都运行一个普通的数据库,它对分布式事务一无所知。我错过了什么?没有。

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

如何防止以下故障

  • 所有节点都响应它们是 准备好了吗
  • 交易 协调员告诉他们“继续” 和提交“但其中一个节点 在收到此消息之前崩溃 信息
  • 所有其他节点都已成功提交,但现在分布式事务已损坏
  • 据我所知,当崩溃节点返回时,其事务将被回滚(因为它从未收到提交消息)

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

    没有。第4点不正确。每个节点都在稳定的存储中记录它能够提交或回滚事务的信息,以便即使在崩溃时也能够按照命令执行。当崩溃节点恢复时,它必须意识到它有一个处于预提交状态的事务,恢复任何相关锁或其他控件,然后尝试联系协调器站点以收集事务的状态


    只有当崩溃的节点再也没有恢复时,才会出现问题(然后其他所有人都认为事务正常,或者当崩溃的节点恢复时事务正常)。

    两阶段提交不是万无一失的,只是设计为在99%的情况下工作

    该协议假定每个节点上都有稳定的存储,并带有预写日志,没有节点会永远崩溃,预写日志中的数据不会在崩溃中丢失或损坏,任何两个节点都可以相互通信


    不,没有指示他们回滚,因为在原始海报的场景中,一些节点已经提交。当崩溃的节点可用时,事务协调器会告诉它再次提交


    由于节点在“准备”阶段做出了积极响应,因此需要能够“提交”,即使它从崩溃中恢复。

    有很多方法可以解决两阶段提交的问题。几乎所有这些都是Paxos三阶段提交算法的变体。Mike Burrows在谷歌设计了基于Paxos的Chubby lock服务,他在我看到的一次讲座中说,有两种分布式提交算法——“Paxos,和不正确的”

    崩溃的节点在重新唤醒时可以做的一件事是对协调器说“我从来没有听说过这个事务,它是否应该被提交?”协调器会告诉它投票结果

    请记住,这是一个更普遍问题的示例:崩溃的节点在恢复之前可能会错过许多事务。因此,非常重要的一点是,在恢复时,它应该在使自己可用之前与协调器或另一个复制副本通信。如果节点本身无法判断是否崩溃,那么事情会变得更加复杂,但仍然可以处理


    如果对数据库读取使用仲裁系统,则不一致性将被屏蔽(并告知数据库本身)

    总结每个人的答案:

  • 不能将普通数据库用于分布式事务。数据库必须明确支持事务协调器

  • 不会指示节点回滚,因为某些节点已提交。发生的情况是,当崩溃的节点返回时,事务协调器告诉它完成提交


  • 这不是假设数据库知道分布式事务吗?我认为你应该能够在对分布式事务一无所知的普通数据库之上进行分布式事务处理……不;DBMS必须意识到它们在2PC协议中的责任,关键的责任是在协调器发出命令之前将事务保持在Go/No Go状态。你在那一点上失去了(自主权)。Informix实现了启发式回滚来处理消失的系统。即使满足了您提到的假设,我也不明白当事务从崩溃中恢复时,节点应该如何知道如何重放事务(而不是回滚)。据我所知,数据库不知道分布式事务;最重要的是,数据库必须了解分布式事务才能正确支持2PC。如果你在上面构建了一些东西,那么你就没有一个可靠的2PC实现。在某些假设下,2PC是100%正确的。对于这个问题,参与者必须持久地存储来自预提交的数据,并且必须能够在重启后完成提交(如果协调器指示)。协调器还必须持久地存储回滚或提交的最终决定,并在失败时重试。此外,所有参与者都不能永远崩溃,他们必须最终重新启动并拥有持久存储的数据。如果满足这些条件,则2PC是100%正确的。如果没有,它可能是不正确的。我不明白崩溃的节点如何能够重放事务,直到它停止的位置。如果在普通数据库上安装分布式事务库,是什么阻止数据库在崩溃时回滚?Gili:因为它承诺在2PC的准备阶段能够回滚。@Gili崩溃的数据库不必重放事务。传统数据库事务的工作方式是,它们在事务日志中积极地进行这些更改,只有当事务日志能够获得必要的行/表/页锁时,才会发生这些更改。基本上在第一阶段之后,事务已经修改了数据库,但是其他查询在修改之前无法看到这些更改