深度理解分布式事务——强一致分布式事务解决方案

本节我将介绍一下强一致的分布式事务解决方案
同时在文章的末尾将重点阐述一下Mysql的相关具体的使用
本篇章大概会分为

  • 强一致事务概述
  • DTP模型
  • XA事务规范
  • 2PC模型
  • Mysql的强一致事务实践

强一致事务概述

在分布式事务领域,最早采⽤的是符合CAP理论的强⼀致性事务⽅案来解决分布式事务问题。
强⼀致性分布式事务要求在任意时刻查询参与全局事务的各节点的数据都是⼀致的。

典型模型:
2PC、3PC、DTP(XA是其典型的解决方案)

适用场景:
适合强一致性的方案,宁愿牺牲可用性都要保证数据的一致性
常见于金融等场景,但是一般不适合互联网的相关场景

DTP模型( Distributed Transaction Processing——分布式事务处理 模型)

DTP模型不能说是一个具体的解决方案,他更是一个通用的规范
这个是X/Open组织定义的一套分布式事务的标准
其中XA事务规范算是一个经典的解决方案

DTP模型的重要概念
1)事务——广义上的事务,一个操作要不全成功要不全失败
2)全局事务——事务管理器上的事务,保证事务管理器的操作全部成功
3)分支事务——全局事务的子资源事务管理器,负责管理子资源的事务
4)控制线程——执行全局事务的线程,这个线程⽤来关联应⽤程序、事务管理器和资源管理器三者之间的关系,也就是表示全局事务和分⽀事务的关系,通常称为事务上下⽂环境。(类似于一个TC的角色

这个就是DTP模型的主要执行流程[外链图片转存中…(img-XGVIOZuC-172d3a01ff9874b0aaf24f91fa9ede5c9.png)

XA事务

XA事务可以说是DTP规范的经典实现了
XA事务本质上是⼀种基于两阶段提交的分布式事务,分布式事务可以简单理解为多个数据库事务共同完成⼀个原⼦性的事务操作。参与操作的多个事务要么全部提交成功,要么全部提交失败。在使⽤XA分布式事务时,InnoDB存储引擎的事务隔离级别需要设置为串行化
正如下图所示,他有TM,RM,AP(是不是跟上面高度雷同),所以这就是一个DTP的经典的解决方案
像经典的系统都支持XA事务,比如Mysql、Oracle等

核心流程如下所示在这里插入图片描述

2PC——两阶段提交模型

为什么这么叫呢 2 指的是两个阶段 P指的是Prepare C指的是Commit
2PC先进行的是Prepare,Prepare预留资源成功之后就会进行Commit
整个流程属于同步阻塞的状态

来重点看看2PC怎么实现的吧
一般都是结合数据库系统来说的
说之前我们温习一下
Redo log 是 实现WAL的核心,目标是进行顺序写和落库的磁盘化
Undo log 是事务回滚的核心 有roll-pointer进行版本链的回滚
如果有不明确的可以看看小林coding的相关阐述
https://xiaolincoding.com/mysql/log/how_update.html#%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81-redo-log

以数据库系统为例,我们来仔细看看是怎么实现相关的两阶段提交的

准备阶段会进行Prepare的发送,相关的数据库会进行Redo log 和 Undo log的写入
在这里插入图片描述
在事务全部Prepare成功之后
便会执行Commit,RM(资源管理器)收到信号之后就会提交事务
在这里插入图片描述
事务执行失败怎么办?

1)事务Prepare阶段某个RM失败了
那么TM会收到相关的消息,然后触发RollBack行为,其他已经执行Prepare的RM会执行回滚(至于怎么回滚就是Undo log的事情了)

TM只需要负责发出RollBack消息即可,当然Rollback之后也需要向TM发出已回滚的消息在这里插入图片描述
两阶段提交不可避免的会有空回滚和悬挂的问题
这个注意业务方的状态校验即可

还有就是commit的失败的时候,TM进行全局性的重试也可以避免

综上所述,2PC存在着以下的问题
1)⽆法解决的问题:如果在Commit阶段,事务管理器发出Commit消息后宕机,并且唯⼀接收
到这条Commit消息的资源管理器也宕机了,则⽆法确认事务是否已经提交。
相对能解决的问题或者是潜在问题
1)同步阻塞问题:事务的执⾏过程中,所有参与事务的节点都会对其占⽤的公共资源加锁,导致其他访问公共资源的进程或者线程阻塞
2)单点故障问题:如果事务管理器发⽣故障,则资源管理器会⼀直阻塞。
3)数据不⼀致问题:如果在Commit阶段,由于⽹络或者部分资源管理器发⽣故障,导致部分
资源管理器没有接收到事务管理器发送过来的Commit消息,会引起数据不⼀致的问题

Mysql的强一致性事务实战

刚才我问其实一直聚焦于外部的XA事务,但是Mysql内部其实也有XA事务
我们就来以内部的XA协议为切入点详细讲一下2PC吧

两阶段提交保证binlog和redo log的一致性
在Mysql中如果在InnoDB引擎中开启binlog日志的时候,会有一个内部的XA事务进行
在这里插入图片描述
这里面的TM其实是binlog、RM是innodb存储
这里很有意思,因为binlog服务和innodb不是平等的RM,且binlog的提交完全依赖于innodb的存储引擎的结果,所以这个并不是经典的多个RM的存储场景——它这个更类似于追加写+事务的场景,不过其实核心还是用了2PC的

prepare阶段是写入redo log 然后事务状态设置为prepare,接着会把redo log持久化进入磁盘

commit的阶段,需要先把binlog提交,然后调用commit的接口,把redolog的状态设置为commit(不需要磁盘,因为状态以binlog为准的)

两阶段提交的异常处理机制
如果 binlog 中没有当前内部 XA 事务的 XID,说明 redolog 完成刷盘,但是 binlog 还没有刷盘,则回滚事务。对应时刻 A 崩溃恢复的情况。
如果 binlog 中有当前内部 XA 事务的 XID,说明 redolog 和 binlog 都已经完成了刷盘,则提交事务。对应时刻 B 崩溃恢复的情况。
本质上就是以binlog的状态来决定后续处理的状态

处于 prepare 阶段的 redo log 加上完整 binlog,重启就提交事务,MySQL 为什么要这么设计?
binlog 已经写入了,之后就会被从库(或者用这个 binlog 恢复出来的库)使用。
所以,在主库上也要提交这个事务。采用这个策略,主库和备库的数据就保证了一致性。

这就是内部的XA事务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值