Distributed transaction, two-phase commit protocol, three-phase commit protocol

With the increasing number of scenarios such as high concurrent access and massive data processing of large websites, how to achieve the goals of high availability, scalability, scalability, and security of websites becomes more and more important.

In order to solve such a series of problems, the architecture of large websites is also constantly evolving. To improve the high-availability architecture of large-scale websites, it is necessary to mention distributed. In the article " Discussion on Consistency of Distributed Systems ", we mainly introduce the consistency problems existing in distributed systems. This article will briefly introduce how to effectively solve the distributed consistency problem, including what is a distributed transaction , two-phase commit and three-phase commit .

Distributed Consistency Review

In a distributed system, in order to ensure the high availability of data, we usually keep multiple copies of the data (replica), and these copies will be placed on different physical machines. In order to provide the correct semantics for adding, deleting, changing, and differing to users, we need to ensure that these copies placed on different physical machines are consistent.

In order to solve this distributed consistency problem, predecessors have summarized many typical protocols and algorithms in the process of repeated trade-offs between performance and data consistency. The more famous ones are the Two Phase Commitment Protocol, the Two Phase Commitment Protocol and the Paxos algorithm .

Distributed transaction

Distributed transactions are transactions that involve operating multiple databases. In fact, it is to expand the concept of transactions to the same library to transactions of multiple libraries. The purpose is to ensure data consistency in distributed systems. The key to distributed transaction processing is that there must be a way to know all the actions a transaction is doing anywhere, and the decision to commit or rollback a transaction must yield a uniform result (all commit or all rollback)

In a distributed system, each node is physically independent of each other, and communicates and coordinates through the network. Due to the existence of a transaction mechanism, data operations on each independent node can be guaranteed to satisfy ACID. However, independent nodes cannot accurately know the execution of transactions in other nodes. So theoretically, two machines cannot theoretically reach a consistent state. If you want to maintain consistency of data in multiple machines deployed in a distributed manner, you must ensure that data write operations on all nodes are executed, or all of them are not executed. However, when a machine executes a local transaction, it cannot know the result of the execution of local transactions in other machines. So he doesn't know whether this transaction should commit or rollback. Therefore, the conventional solution is to introduce a "coordinator" component to uniformly schedule the execution of all distributed nodes.

XA Specification

The X/Open organization (now the Open Group) defines a distributed transaction processing model. The X/Open DTP model (1994) includes four parts: application program (AP), transaction manager (TM), resource manager (RM), and communication resource manager (CRM). Generally, a common transaction manager ( TM ) is a transaction middleware, a common resource manager ( RM ) is a database, and a common communication resource manager ( CRM ) is a message middleware. Transactions within a database, such as operations on multiple tables, are usually treated as local transactions. The transaction object of the database is the local transaction, and the object of the distributed transaction is the global transaction. The so-called global transaction means that in a distributed transaction processing environment, multiple databases may need to work together to complete a work, which is a global transaction. For example, several different databases may be updated in one transaction. Operations on the database occur throughout the system but must all be committed or rolled back. At this time, the submission of a database's internal operations depends not only on the success of its own operation, but also on the success of other database operations related to the global transaction. If any operation of any database fails, all participating in the transaction will be All operations done by the database must be rolled back. In general, a database has no way of knowing what other databases are doing, so in a DTP environment, transaction middleware is required, which notifies and coordinates the commit or rollback of related databases. And a database only maps its own operations (recoverable) to global transactions.

XA 就是 X/Open DTP 定义的交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等。 XA 接口函数由数据库厂商提供。

二阶提交协议三阶提交协议就是根据这一思想衍生出来的。可以说二阶段提交其实就是实现XA分布式事务的关键(确切地说:两阶段提交主要保证了分布式事务的原子性:即所有结点要么全做要么全不做)

2PC

二阶段提交(Two-phaseCommit)是指,在计算机网络以及数据库领域内,为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种算法(Algorithm)。通常,二阶段提交也被称为是一种协议(Protocol))。在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点时,为了保持事务的ACID特性,需要引入一个作为协调者的组件来统一掌控所有节点(称作参与者)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等)。因此,二阶段提交的算法思路可以概括为:参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。

所谓的两个阶段是指:第一阶段:准备阶段(投票阶段)和第二阶段:提交阶段(执行阶段)

准备阶段

事务协调者(事务管理器)给每个参与者(资源管理器)发送Prepare消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务,写本地的redo和undo日志,但不提交,到达一种“万事俱备,只欠东风”的状态。

可以进一步将准备阶段分为以下三个步骤:

1)协调者节点向所有参与者节点询问是否可以执行提交操作(vote),并开始等待各参与者节点的响应。

2)参与者节点执行询问发起为止的所有事务操作,并将Undo信息和Redo信息写入日志。(注意:若成功这里其实每个参与者已经执行了事务操作)

3)各参与者节点响应协调者节点发起的询问。如果参与者节点的事务操作实际执行成功,则它返回一个”同意”消息;如果参与者节点的事务操作实际执行失败,则它返回一个”中止”消息。

提交阶段

如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源)

接下来分两种情况分别讨论提交阶段的过程。

当协调者节点从所有参与者节点获得的相应消息都为”同意”时:

success

1)协调者节点向所有参与者节点发出”正式提交(commit)”的请求。

2)参与者节点正式完成操作,并释放在整个事务期间内占用的资源。

3)参与者节点向协调者节点发送”完成”消息。

4)协调者节点受到所有参与者节点反馈的”完成”消息后,完成事务。

如果任一参与者节点在第一阶段返回的响应消息为”中止”,或者 协调者节点在第一阶段的询问超时之前无法获取所有参与者节点的响应消息时:

fail

1)协调者节点向所有参与者节点发出”回滚操作(rollback)”的请求。

2)参与者节点利用之前写入的Undo信息执行回滚,并释放在整个事务期间内占用的资源。

3)参与者节点向协调者节点发送”回滚完成”消息。

4)协调者节点受到所有参与者节点反馈的”回滚完成”消息后,取消事务。

不管最后结果如何,第二阶段都会结束当前事务。

二阶段提交看起来确实能够提供原子性的操作,但是不幸的事,二阶段提交还是有几个缺点的:

1、同步阻塞问题。执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。

2、单点故障。由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)

3、数据不一致。在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象。

4、二阶段无法解决的问题:协调者再发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。

由于二阶段提交存在着诸如同步阻塞、单点问题、脑裂等缺陷,所以,研究者们在二阶段提交的基础上做了改进,提出了三阶段提交。

3PC

三阶段提交(Three-phase commit),也叫三阶段提交协议(Three-phase commit protocol),是二阶段提交(2PC)的改进版本。

3

与两阶段提交不同的是,三阶段提交有两个改动点。

1、引入超时机制。同时在协调者和参与者中都引入超时机制。
2、在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。

也就是说,除了引入超时机制之外,3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommitPreCommitDoCommit三个阶段。

CanCommit阶段

3PC的CanCommit阶段其实和2PC的准备阶段很像。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。

1.事务询问 协调者向参与者发送CanCommit请求。询问是否可以执行事务提交操作。然后开始等待参与者的响应。

2.响应反馈 参与者接到CanCommit请求之后,正常情况下,如果其自身认为可以顺利执行事务,则返回Yes响应,并进入预备状态。否则反馈No

PreCommit阶段

协调者根据参与者的反应情况来决定是否可以记性事务的PreCommit操作。根据响应情况,有以下两种可能。

假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务的预执行。

1.发送预提交请求 协调者向参与者发送PreCommit请求,并进入Prepared阶段。

2.事务预提交 参与者接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。

3.响应反馈 如果参与者成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。

假如有任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。

1.发送中断请求 协调者向所有参与者发送abort请求。

2.中断事务 参与者收到来自协调者的abort请求之后(或超时之后,仍未收到协调者的请求),执行事务的中断。

doCommit阶段

该阶段进行真正的事务提交,也可以分为以下两种情况。

执行提交

1.发送提交请求 协调接收到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者发送doCommit请求。

2.事务提交 参与者接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。

3.响应反馈 事务提交完之后,向协调者发送Ack响应。

4.完成事务 协调者接收到所有参与者的ack响应之后,完成事务。

中断事务 协调者没有接收到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。

1.发送中断请求 协调者向所有参与者发送abort请求

2.事务回滚 参与者接收到abort请求之后,利用其在阶段二记录的undo信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源。

3.反馈结果 参与者完成事务回滚之后,向协调者发送ACK消息

4.中断事务 协调者接收到参与者反馈的ACK消息之后,执行事务的中断。

在doCommit阶段,如果参与者无法及时接收到来自协调者的doCommit或者rebort请求时,会在等待超时之后,会继续进行事务的提交。(其实这个应该是基于概率来决定的,当进入第三阶段时,说明参与者在第二阶段已经收到了PreCommit请求,那么协调者产生PreCommit请求的前提条件是他在第二阶段开始之前,收到所有参与者的CanCommit响应都是Yes。(一旦参与者收到了PreCommit,意味他知道大家其实都同意修改了)所以,一句话概括就是,当进入第三阶段时,由于网络超时等原因,虽然参与者没有收到commit或者abort响应,但是他有理由相信:成功提交的几率很大。 )

2PC与3PC的区别

相对于2PC,3PC主要解决的单点故障问题,并减少阻塞,因为一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit。而不会一直持有事务资源并处于阻塞状态。但是这种机制也会导致数据一致性问题,因为,由于网络原因,协调者发送的abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到abort命令并执行回滚的参与者之间存在数据不一致的情况。


After understanding 2PC and 3PC, we can find that neither the two-phase commit nor the three-phase commit can completely solve the distributed consistency problem. Mike Burrows, the author of Google Chubby, said  there is only one consensus protocol, and that’s Paxos” – all other approaches are just broken versions of Paxos. that there is only one consensus algorithm in the world, and that is Paxos , and all other consensus algorithms are incomplete versions of the Paxos algorithm. Subsequent articles will introduce this Paxos algorithm, which is known to be difficult to understand but works well.

References:

  1. Distributed Protocol Two-Phase Commit Protocol (2PC) and Improved Three-Phase Commit Protocol (3PC)
  2. Research on Distributed Transaction, Two-Phase Commit, One-Phase Commit, Best Efforts 1PC Mode and Transaction Compensation Mechanism
  3. Two-phase commit protocol and three-phase commit protocol

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326529423&siteId=291194637