共计 1228 个字符,预计需要花费 4 分钟才能阅读完成。
背景
笔者在过来经典的两阶段提交算法过程中,发现会遇上局部节点在执行事务提交期间产生故障,导致如下的谬误,这些谬误都会导致用户数据失落或者出错。谬误如下:
1、一个分布式事务的一部分事务分支被提交,另一部分事务分支被回滚
2、应答给客户端事务提交胜利,然而分布式事务所有分支全副被回滚
3、应答给客户端事务被回滚,然而分布式事务局部或者全副分支被提交
4、存储节点故障复原时,某个存储节点的事务分支不能被正确地复原。
在下面这些谬误源中,第 #4 类错误处理由存储节点本身负责,分布式事务处理机制负责解决前 3 类谬误,笔者会在下篇文章做次要探讨。
对于第 #4 类谬误,笔者已经在 FOSDEM 2021 做过一次技术分享,https://fosdem.org/2021/sched…,国内视频连贯在:昆仑分布式数据库 MySQL XA 事务处理的容灾技术(https://b23.tv/h7zzmR)当前也会陆续撰文详述。
经典的两阶段提交算法原理
两阶段提交算法把事务的提交分为 preapre 和 commit 两个阶段。
第一阶段事务管理器 GTM 发送 prepare 命令给所有的 resourcemanager(RM),每个 RM 就 prepare 分布式事务的本地分支,也就是把它们的 WAL 日志刷盘以便即便 RM 宕机,复原之后依然能够提交(或者回滚)这些 prepared 状态的事务。
prepare 一个事务之后,这个事务进入 prepared 状态,之后既能够 commit 它,也能够 rollback 它。
如果 GTM 收到所有的 RM 返回的都是胜利,那么 GTM 发送 commit 给每个参加的 RM,于是 RM 就提交其 prepared 状态的事务分支,这样就实现了两阶段提交。
经典的两阶段提交算法缺点
如果两阶段提交流程中产生 GTM 或者 RM 宕机等故障,那么这个两阶段提交流程就可能中断并且无奈正确地持续的问题。
如何优化防止其缺点?
为防止此类事变产生,昆仑分布式数据库的分布式事务处理机制基于经典的两阶段提交算法,并在此基础上加强了其容灾能力和错误处理能力。
故此能够做到任意时刻昆仑数据库集群的任意节点宕机或者网络故障、超时等都不会导致集群治理的数据产生不统一或者失落等谬误。
一个昆仑分布式数据库集群蕴含若干个彼此独立且性能雷同的计算节点做分布式事务处理和分布式查询处理(下篇文章做详述):
蕴含若干个存储集群存储用户数据分片,每个存储集群应用高可用机制确保节点宕机数据不失落。
一个构造与存储集群完全相同的元数据集群,它存储着这个集群的要害元数据信息,包含本文所说的 commit log。
一个 cluster_mgr 模块, 负责保护集群运行状态,并且解决因为节点故障而残留的 prepared 状态的事务分支。
故此在上述的模块的有机配合下,经典的两阶段算法提交的缺点能够很好的防止!
总结
对于经典的两阶段提交算法流程,笔者及团队曾经做了优化用于解决这些问题,从而达到坚不可摧的容灾能力。对于优化的原理过程,笔者会在下篇文章做详述(有疑难可私聊~)