达梦分布式集群DPC_分布式事务理解_yxy
达梦分布式集群DPC_分布式事务理解
- 1 分布式事务是什么?
- 2 分布式事务怎么实现?
- 2.1 两阶段提交保障一致性
- 2.1.1 预提交
- 2.1.2 提交
- 2.2 RAFT协议保障数据强一致
- 2.3 全局事务管理
- 2.3.1 全局事务信息的登记流程
- 2.3.2 数据可见性判断规则
1 分布式事务是什么?
在分布式系统架构下,不同的服务器之间通过网络远程协作而完成的事务,称为分布式事务。
分布式事务会遇到的问题:
在分布式集群中,一个事务可能涉及多个BP节点(数据存储节点)。
例如:
事务T1:在BP1上修改账户A余额,在BP2上修改账户B余额;
事务T2:同时在BP1上读取账户A余额。若BP1提交成功但BP2尚未提交,T2可能读到BP1已提交但BP2未提交的中间状态数据(如A扣款成功但B未到账),破坏事务隔离性(如“读未提交”)。
2 分布式事务怎么实现?
2.1 两阶段提交保障一致性
在分布式架构时,数据库一致性要求会变的更高。
DPC通过两阶段提交技术来保证多个BP(数据节点)之间的分布式事务一致性
两阶段提交SP(计算节点) 作为全局事务的协调者,统一处理全局事务。
BP 作为参与者,是被 SP 调度并执行事务的节点。
SP 根据 BP 的响应来决定是否真正的执行并提交事务。所有参与者 BP 要么一起提交要么一起回滚,始终保持事务一致性状态。
2.1.1 预提交
左边成功、右边失败示例
- 客户端发起请求:客户端想要提交一个事务,就向SP(协调者)发起了请求。
- SP广播预提交命令:SP收到请求后,向所有BP(参与者)发送预提交命令,问它们能不能完成这个事务的提交,然后等着BP们回复。
- BP响应:BP们收到预提交命令后,先把操作相关的回滚日志写到回滚段里,然后告诉SP自己这边的情况。
- SP判断并处理:
如果SP收到了所有BP都预提交成功的消息,那它就进入第二阶段,继续完成提交操作。
但如果有的BP没回复,SP就搞不清楚这个BP到底有没有完成预提交。这时候,SP会先试着通知那些还活着的BP去回滚操作。如果能有BP成功回滚,SP就可以直接告诉客户端“事务提交失败”。但如果回滚也失败了,SP就只能告诉客户端“未知的提交结果”。不管是哪种情况,客户端收到消息后,就知道这个事务没成功。
2.1.2 提交
- 进入提交阶段:如果SP(协调者)收到所有BP(参与者)都预提交成功的消息,就说明可以开始正式提交事务了。
- SP广播提交命令:SP向所有BP发送COMMIT命令,让BP们执行第二阶段的提交任务。BP们收到命令后,开始提交事务,释放占用的资源,并且把提交成功的消息反馈给SP。
- SP响应客户端:
3.1. 如果SP顺利收到所有BP的COMMIT成功消息,就直接告诉客户端“事务提交成功”,整个事务就完成了。
3.2. 但如果在二阶段提交过程中,BP和SP之间的通信中断了,SP不会一直等,而是把提交任务交给异步任务去处理,自己马上告诉客户端“事务提交成功”。
3.3. 等到故障的BP和SP重新连上后,异步任务会自动接着执行二阶段提交,直到成功为止。客户端收到“事务提交成功”的消息,就表示这个事务完成了。
2.2 RAFT协议保障数据强一致
DPC基于RAFT一致性协议实现多副本数据同步,每个BP组构成一个RAFT组(如3节点组),主库通过异步日志传输(XMAL模块)将Redo日志同步至备库,确保数据强一致。主库故障时,剩余节点自动选举新主库,实现秒级切换
同一个raft组的数据完全一致
例如
三副本架构:BP1_A 、BP1_B 、BP1_C
ABC数据完全相同,同一时间只有A为主库对外提供服务,A故障B自动接管
2.3 全局事务管理
DPC通过全局时钟(Global Timestamp Sequence, GTS) 统一所有节点的事务时序,其核心组件包括:
MP节点:全局时钟管理者,负责分配唯一递增的时钟值(cur_seq);
CA数组(BP端):记录事务预提交/提交状态及时钟值;
MCA数组(MP端):记录所有已提交事务的TID和提交时钟值。
2.3.1 全局事务信息的登记流程
步骤1:事务预提交(一阶段)
BP节点向MP申请当前时钟值pre_seq;
在本地CA数组登记:
TID (事务ID) | 状态=预提交 | 时钟值=pre_seq |
---|
步骤2:事务提交(二阶段)
BP节点向MP申请新时钟值commit_seq;
MP端:在MCA数组登记该事务的提交信息:
TID (事务ID) | 时钟值=commit_seq |
---|
BP端:更新本地CA数组中该事务的状态:
TID (事务ID) | 状态=提交 | 时钟值=commit_seq |
---|
整体流程
2.3.2 数据可见性判断规则
当一个事务(如T2)操作数据时:
- 获取当前时钟:向MP申请当前时钟值cur_seq;
- 定位数据修改者:找到目标数据最后一次修改的事务TID(记录在Redo日志中);
- 查询CA/MCA数组,按优先级判断可见性:
规则1:直接通过CA判断
① 若CA中该TID的状态为 “提交” 且 ca_seq ≤ cur_seq → 数据可见
(说明修改已提交,且在T2开始前完成)
② 若状态为 “预提交” 但 ca_seq ≤ cur_seq → 需进一步查MCA
规则2:结合MCA二次验证
在MCA中查询该TID:
① 若存在且 mca_seq ≤ cur_seq → 数据可见
(说明事务实际已提交,只是CA状态未及时更新)
② 其他情况(如MCA无记录或mca_seq > cur_seq) → 数据不可见
例如
假设以下场景:
T1:修改数据X(TID=100),在BP1预提交时获时钟pre_seq=50;
T2:在时钟cur_seq=55时尝试读取X;
T1:在时钟commit_seq=60时提交。判断过程:
T2读取X时,发现其最后修改者为TID=100;
查询CA:TID=100的状态为“预提交”,ca_seq=50 ≤ 55 → 需查MCA;
查询MCA:此时尚无TID=100的记录 → X对T2不可见(避免了读取未提交数据)。
总结
DPC的全局时钟系统(GTS)通过 CA/MCA双数组协作 + 全局时序化 设计,将复杂的分布式事务可见性问题转化为时钟值比较问题。
更多其他数据库相关专栏:
1.数据库优化
数据库优化基本思路、索引详解、执行计划、统计信息、CBO原理、单表优化、多表优化、分布式优化、子查询、优化案例等
数据库优化(sql优化)专栏连接
2.达梦分布式数据库:
部署详细步骤(DEM)、备份还原实战、核心特性理解、使用心得、表分区方式详细介绍、表分区最佳实践、DPC架构详解等
达梦分布式DPC专栏连接
3.应用开发类
jdbc、hibernate、ibatis、mybatis、MyBatis-Plus、Spring、中间件mycat、Sharding-JDBC等
达梦数据库应用开发专栏连接