• 两阶段提交中的两个阶段,指的是 Commit-request 阶段Commit 阶段,两阶段提交的流程如下:一致性算法2PC 3PC了解一下-LMLPHP

    提交请求阶段

    在提交请求阶段,协调者将通知事务参与者准备提交事务,然后进入表决过程。在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地事务执行成功)或取消(本地事务执行故障),在第一阶段,参与节点并没有进行Commit操作。

    Commit阶段

    在提交阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消这个事务。在2PC和3PC算法中必须仅当所有的参与者同意提交,协调者才会通知各个参与者提交事务,否则协调者将通知各个参与者取消事务。

    参与者在接收到协调者发来的消息后将执行对应的操作,也就是本地 Commit 或者 Rollback。

    两阶段提交存在的问题

    两阶段提交协议有几个明显的问题,下面列举如下。

    在执行过程中,所有参与节点都是事务独占状态,当参与者占有公共资源时,那么第三方节点访问公共资源会被阻塞。

    一旦协调者发生故障,参与者会一直阻塞下去。

    在第二阶段中,假设协调者发出了事务 Commit 的通知,但是由于网络问题该通知仅被一部分参与者所收到并执行 Commit,其余的参与者没有收到通知,一直处于阻塞状态,那么,这段时间就产生了数据的不一致性。

    三阶段提交协议

    为了解决二阶段协议中的同步阻塞等问题,三阶段提交协议在协调者和参与者中都引入了超时机制,并且把两阶段提交协议的第一个阶段拆分成了两步:询问,然后再锁资源,最后真正提交。

    三阶段中的 Three Phase 分别为 CanCommit、PreCommit、DoCommit 阶段。

    CanCommit 阶段

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

    PreCommit 阶段

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

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

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

    DoCommit 阶段

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

    A. 执行提交

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

    C.超时提交 参与者如果没有收到协调者的通知,超时之后会执行 Commit 操作。

    三阶段提交做了哪些改进

    引入超时机制

    在 2PC 中,只有协调者拥有超时机制,如果在一定时间内没有收到参与者的消息则默认失败,3PC 同时在协调者和参与者中都引入超时机制。

    添加预提交阶段

    在 2PC 的准备阶段和提交阶段之间,插入一个准备阶段,使 3PC 拥有 CanCommit、PreCommit、DoCommit 三个阶段,PreCommit 是一个缓冲,保证了在最后提交阶段之前各参与节点的状态是一致的。

    三阶段提交协议存在的问题

    三阶段提交协议同样存在问题,具体表现为,在阶段三中,如果参与者接收到了 PreCommit 消息后,出现了不能与协调者正常通信的问题,在这种情况下,参与者依然会进行事务的提交,这就出现了数据的不一致性。

    两阶段和三阶段提交的应用

    两阶段提交是一种比较精简的一致性算法/协议,很多关系型数据库都是采用两阶段提交协议来完成分布式事务处理的,典型的比如 MySQL 的 XA 规范。

    在事务处理、数据库和计算机网络中,两阶段提交协议提供了分布式设计中的数据一致性的保障,整个事务的参与者要么一致性全部提交成功,要么全部回滚。MySQL Cluster 内部数据的同步就是用的 2PC 协议。

    MySQL 的主从复制

    在 MySQL 中,二进制日志是 server 层,主要用来做主从复制即时点恢复时使用的;而事务日志(Redo Log)是 InnoDB 存储引擎层,用来保证事务安全的。

    在数据库运行中,需要保证 Binlog 和 Redo Log 的一致性,如果顺序不一致, 则意味着 Master-Slave 可能不一致。

    在开启 Binlog 后,如何保证 Binlog 和 InnoDB redo 日志的一致性呢?MySQL 使用的就是二阶段提交,内部会自动将普通事务当做一个 XA 事务(内部分布式事务)来处理:



    朕已阅 一致性算法2PC 3PC了解一下-LMLPHP


    本文分享自微信公众号 - JAVA日知录(javadaily)。
    如有侵权,请联系 support@oschina.cn 删除。
    本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

    09-13 11:55