在GaussDB分布式集群中,单机事务是指一个事务中所有操作都发生在同一个分片(即DN)上,而分布式事务是指一个事务中有两个或以上的分片参与了该事务的执行。
对于单机事务,写操作的原子性和读操作的一致性由该DN自身的事务机制进行保证,对于分布式事务,不同分片之间写操作的原子性和不同分片之间读操作的一致性需要额外的机制来保障。
GaussDB分布式事务的写一致性
GaussDB分布式数据库的写一致性是通过两阶段提交(2PC)协议实现的,两阶段提交协议将分布式事务的提交操作分为两个阶段,如图4所示:
图4 分布式事务两阶段协议提交示意图
阶段一,准备阶段(prepare phase),在这个阶段,将所有提交操作所需要使用到的信息和资源全部写入磁盘,完成持久化。
阶段二,提交阶段(commit prepared phase),根据之前准备好的提交信息和资源,执行提交或回滚操作。
2PC 协议有两类节点:协调者和参与者。一个事务会涉及一个协调者和多个参与者。当协调者或者参与者出现故障或者节点间出现网络问题时,2PC 事务就面临着失败或者残留的问题。在 GaussDB中,发起事务的 CN 节点就是协调者,其他参与此事务的 CN 或者 DN 节点就是参与者。
表1 GaussDB发生故障或执行失败时事务的最终状态
如表1所示,两阶段提交协议之所以能够保证分布式事务原子性的关键在于:一旦准备阶段执行成功,那么提交需要的所有信息都完成持久化下盘(写入磁盘),即使后续提交阶段某个DN发生执行错误,该DN可以再次从持久化的提交信息中尝试提交,直到提交成功。最终该分布式事务在所有DN上的状态一定是相同的,要么所有DN都提交,要么所有DN都回滚。对外来说,该事务的状态变化是原子性的。
图5 GaussDB分布式事务的写一致性流程图
如图5所示,CN节点作为协调者,DN节点作为参与者,GTM提供全局唯一的CSN值。
参与者节点(DN)在完成prepare阶段后,会将事务的状态设置为commit-in-progress。当所有DN prepare完毕后,协调者节点(CN)通知GTM进行事务提交,并获取到一个全局唯一的事务提交序列号CSN值。
在提交阶段(commit prepared phase),CN向所有DN发送包含事务唯一标识符和其他必要信息的提交(Commit)请求。DN收到提交请求后,执行实际的事务提交,修改事务状态为commit_determined已提交状态。
当CN收集到所有DN的提交确认后,它将向客户端返回分布式事务的最终提交结果。