背景
笔者在过来经典的两阶段提交算法过程中,发现会遇上局部节点在执行事务提交期间产生故障,导致如下的谬误,这些谬误都会导致用户数据失落或者出错。谬误如下:
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 状态的事务分支。
故此在上述的模块的有机配合下,经典的两阶段算法提交的缺点能够很好的防止!
总结
对于经典的两阶段提交算法流程,笔者及团队曾经做了优化用于解决这些问题,从而达到坚不可摧的容灾能力。对于优化的原理过程,笔者会在下篇文章做详述(有疑难可私聊~)