MySql是如何实现分布式事务的呢?

在MySQL中,我们需要更新多个实例上的数据,并且保证全成则成,有一错则失败,那么MySQL XA是如何实现的呢?

MySQL通过支持XA规范的二阶段提交协议,不仅仅实现多个MYSQL数据操作的事务,而且还支持其他规范的数据库操作的事务

理解MySQL XA,不仅仅能够理解数据层分布式事务的原理,还能在实际系统汇总跟家理解二阶段提交

我们拿一个例子来看数据库XA

两个数据库 A B 分别位于不同的服务器节点上,我们需要实现多个数据库更新,UPDATE executed_table set status = true where id = 100和插入操作,INSERT into operation_table SET id = 100,op = ‘get-cdn-log’事务

图片

XA规范中,主要就是DTP模型,其中XA规范约定的是DTP模型中的2个模块的通讯方式,事务管理器和资源管理器,就是DTP,分布式事务处理

图片

DTP模型中各个模块的作用

AP:应用程序,事务的发起者,比如客户端或者访问数据库的程序,定义的事务操作,比如上面的sql语句

RM: 资源管理器,管理共享的资源,供外部的程序来访问共享资源,比如数据库,RM有事务提交和回滚的能力

TM:事务管理器,TM是分布式事务的协调者,TM和每个RM通信,完成事务的处理

如何理解这个架构呢?

应用程序访问,使用资源管理器的资源,并且通过事务管理器的事务接口,来执行事务操作,然后事务管理器和资源管理器基于XA,执行二阶段提交

图片

为了更好的理解这个过程,我们看下流程

AP联系TM事务管理器,发起全局事务;

TM调用ax_open()建立和资源管理器的会话

TM调用xa_start()标记事务分支的开头

AP访问RM,并定义具体的事务分支的操作,比如更新一个数据和插入一条数据

TM调用xa_end()标记事务分支的结尾

TM调用xa_perepare()通知RM做好事务提交的准备工作,锁定相关资源

TM调用xa_commit()通知RM提交事务分支,执行二阶段提交协议的提交执行阶段

TM调用xa_close关闭和RM的慧慧啊

利用TM和RM的二阶段提交,保证操作的原子性,’

xa_start()和xa_end()在准备和标记事务分支的内容,锁定事务,这是有一定顺序

对于同一个资源管理器,根据全局事务的要求,可以前后执行多个操作组合,现去标记一个插入,再去标记一个更新

事务管理器只是标记事务,并不执行事务,最终是由应用程序通知资源管理器来执行事务

整体的实现流程呢?

首先创建一个唯一的事务ID,来唯一标记事务,并且调用XA START和XA END来定义事务分支对应的操作

图片

一个操作对应着一个XID

然后执行XA PREPARE命令,来进行提交请求

图片

最后执行,XA COMMIT来提交事务,实现事务的一致性

图片

上面之中,客户端扮演事务管理器的角色,MySQL数据库扮演资源管理器的角色,上面的xid是唯一值

而且需要对应的存储引擎是InnoDB

但是MySQL XA的性能不高,适合在并发性能不高的场景中使用

XA规范总结下来

XA规范是一个标准的规范,无论是相同的数据库,还是不同数据库之间,只要支持XA规范,就能实现分布式事务

相比商业数据库对XA的支持,MySQL XA性能不高

实际开发过程中,为了降低单点压力,通常会根据业务情况进行分库分表,将表分布在不同的数据库中,后续需要保证事务的一致性,实现分布式事务

XA具有一些的局限

就是事务管理器的角色很关键,如果宕机了,就会导致一些被锁定的资源无法被释放

XA规范存在资源锁定的问题,降低了并发度

课后思考

XA性能不高,适用于并发性能不高的场景中,不妨想想,如何避免分布式事务呢?

我的思路是,首先只在主节点上执行事务,然后降低和跟随者的延迟,来保证,在主节点上执行成功了,必然会可以在从节点上执行成功,这是否是一种解决方案呢?

可以利用GTID来辅助查询工作

发表评论

邮箱地址不会被公开。 必填项已用*标注