GaussDB(DWS)中两阶段事务的故障与恢复

举报
QWERT886 发表于 2020/10/24 16:38:10 2020/10/24
【摘要】 GaussDB(DWS) 是 share nothing 架构,使用分布式事务解决数据的一致性问题。当前 GaussDB(DWS) 使用的是两阶段提交(2PC)协议。2PC 协议有两类节点:协调者和参与者。一个事务会涉及一个协调者和多个参与者。当协调者或者参与者出现故障或者节点间出现网络问题时,2PC 事务就面临着失败或者残留的问题。


GaussDB(DWS) 是 share nothing 架构,使用分布式事务解决数据的一致性问题。当前 GaussDB(DWS) 使用的是两阶段提交(2PC)协议。2PC 协议有两类节点:协调者和参与者。一个事务会涉及一个协调者和多个参与者。当协调者或者参与者出现故障或者节点间出现网络问题时,2PC 事务就面临着失败或者残留的问题。在 GaussDB(DWS) 中,发起事务的 CN 节点就是协调者,其他参与此事务的 CN 或者 DN 节点就是参与者。


1.1. 2PC 事务失败/残留的原因

1.1.1. 2PC 事务的正常提交流程

首先看一下 2PC 事务的正常提交流程,一般情况下,对于一个事务,至少要经过一个 CN(执行 CN )、一个 DN 和 GTM。

  1. 如果涉及本地,先在本地进行 PREPARE;

  2. 在远端其他节点进行 PREPARE。如果任一节点失败,则报告错误并进行 ABORT 操作;

  3. 到这步时,所有涉及的节点都已经 PREPARE 了,可以进行 COMMIT 了:首先通知 GTM 当前事务已经 PREPARED,并提供一个节点列表给GTM;

  4. 先在本地 COMMIT PREPARED,然后在其他远端节点 COMMIT;

  5. 返回并做提交动作的收尾工作

1.1.2. 故障

对于上述流程,在任意执行路径上出错,都可能导致整个分布式事务的状态无法达到终点,最终当前事务整体提交失败。如果事务不能完整结束,那么它所占有的资源就会一直无法释放

1.1.3. 故障处理的总体原则

当故障发生后,通过全局回滚或者是由 gs_clean 工具进行残留事务清理,以保证事务完整结束。

1.1.4. 故障场景

  1. 在事务运行过程中,或者 prepare 阶段,对于 CN、DN、GTM 实例本身或者网络出现故障,事务都要进行回滚,根据实际情况,执行 CN 没问题的话,CN 提交回滚操作;否则需要由 gs_clean 工具进行清理。

  2. 在 commit prepared 阶段,CN 向其他 CN 和 DN 发送 commit prepared 命令,并收取返回信息,这时如果实例发生了故障,那么事务会残留,就需要等待 gs_clean 工具清理了。

1.2. gs_clean

上面的故障情况中,对于执行 CN 不能自动进行回滚的的场景,就需要 gs_clean 工具来协助进行清理了。

1.2.1. gs_clean 是干什么的

gs_clean 工具是用于清理 GaussDB(DWS) 集群中残留的两阶段事务的组件。

1.2.2. 为什么需要 gs_clean

由于 GaussDB(DWS) 集群使用多个工作节点一起来支持分布式事务,单个组件的故障会导致分布式事务(2PC)的全局状态产生异常。在某些情况下,异常的事务由于无法判断后续状态进而无法继续下去,这时就需要一个第三方的组件来判断事务状态并将事务圆满的结束。

1.2.3. gs_clean 在哪里

gs_clean 二进制文件跟随内核包一起部署在 $GAUSSHOME/bin 目录下。

1.2.4. 谁来调用 gs_clean

每个 CN 中有一个叫做 TwoPhaseCleanerMain 的辅助线程线程,所有的 gs_clean 调用都是由这个线程自动完成的。

一般情况下,不需要人工调用 gs_clean。

1.2.5. 什么时候调用 gs_clean

  1. 在 CN 正常运行过程中,每隔 5mins 会调一次 gs_clean 命令,对集群中所有的数据库中的两阶段残留事务进行扫描和清理;

  2. 如果是进程刚启动,或者上次 gs_clean 调用失败,则 60s 后会再次调用;

  3. sync 等待时,如果等待超时,会给这个线程发消息线程调用 gs_clean;

  4. 如果已经有 gs_clean 进程启动,则不会再调用;

1.2.6. gs_clean的结果与日志

gs_clean 的所有信息都保存在自己的日志文件中,日志文件路径为:$GAUSSLOG/bin/gs_clean/

1.2.7. gs_clean 的主要工作流程

  • 连接 CN,做一些前期的信息收集和准备工作:

  1. 获取要清理的 database 列表

  2. 连接 CN,设置为维护模式

  3. 获取自己的 node name 和 所有的 node list

  • 扫描两阶段残留信息:

  1. 去各个节点上执行视图 pg_prepared_xacts

  2. 获取 prepared 的事务信息,把结果和事务状态记录在链表里

  • 遍历链表,查看是否有要进行恢复的 2PC 事务

  • 针对每个处于 prepared 阶段的事务,去其他所有节点上查找对应事务是否已经提交,把结果也更新到链表中

  • 收集了所有需要的信息后,针对每个 database 中的每一个事务,根据规则判断应该进行提交、回滚还是继续等待,如果需要提交或回滚,那么直接向所有相关节点发起 commit/rollback prepared 动作

1.2.8. 残留事务的处理规则

  1. 如果有一个节点处于 committed 状态,则标记为提交,并最终提交该事务;

  2. 如果有一个节点处于 aborted 状态,则标记为回滚,并最终回滚该事务;

  3. 如果所有节点都处于 prepared 状态,则可选择回滚或者提交(参数),默认是回滚;

  4. 如果有节点连不上,则不提交也不回滚。

1.2.9. 实际运行过程中的一些事情

  • GUC 参数 gs_clean_timeout 可以用来控制 CN 调用 gs_clean 的周期间隔。默认为 5min。

  • 当 CN 上进行事务 sync 等待时,如果超过 transaction_sync_naptime 参数(默认5s),则会触发 gs_clean。

  • CN 自动触发的 gs_clean 命令为: gs_clean -a -p PORT -v -r

        1. -a:清理所有数据库

        2. -p:CN 端口

        3. -v:打印详细信息,包括数据库信息,残留事务信息等

        4. -r:将处于 PREPARED 状态的事务进行回滚

        5. 其他 gs_clean 参数可以参考 gs_clean --help


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。