Mysql的分布式(XA)真面目

2023-11-14

一、XA是什么?

XA 协议本就是为一个分布式事务协议,它规定了 XA PREPARE、XA COMMIT、XA ROLLBACK 等命令。XA 协议规定了事务管理器(协调者)和资源管理器(数据节点)如何交互,共同完成分布式 2PC 的过程
在这里插入图片描述
XA主要规定了RM与TM之间的交互,下面来看下XA规范中定义的RM 和 TM交互的接口:
在这里插入图片描述

  • xa_start负责开启或者恢复一个事务分支,并且管理XID到调用线程

  • xa_end 负责取消当前线程与事务分支的关联

  • xa_prepare负责询问RM 是否准备好了提交事务分支

  • xa_commit通知RM提交事务分支

  • xa_rollback 通知RM回滚事务分支

XA协议是使用了二阶段协议的,其中:

第一阶段TM要求所有的RM准备提交对应的事务分支,询问RM是否有能力保证成功的提交事务分支,RM根据自己的情况,如果判断自己进行的工作可以被提交,那就就对工作内容进行持久化,并给TM回执OK;否者给TM的回执NO。RM在发送了否定答复并回滚了已经的工作后,就可以丢弃这个事务分支信息了。

第二阶段TM根据阶段1各个RM prepare的结果,决定是提交还是回滚事务。如果所有的RM都prepare成功,那么TM通知所有的RM进行提交;如果有RM prepare回执NO的话,则TM通知所有RM回滚自己的事务分支。

也就是TM与RM之间是通过两阶段提交协议进行交互的。

二、MySQL中XA实现

1.内部XA事务

MySQL中只有InnoDB引擎支持XA协议,内部XA事务主要用来协调存储引擎和二进制日志
在这里插入图片描述
确认下mysql是否启动了xa功能:
在这里插入图片描述
测试手动执行xa事务:
在这里插入图片描述
其中首先使用XA START ‘xid’ 启动了一个XA事务,并把它置于ACTIVE状态

对于一个ACTIVE状态的 XA事务,我们可以执行构成事务的多条SQL语句,也就是指定分支事务的边界,然后执行一个XA END ‘xid’语句,XA END把事务放入IDLE状态,也就是结束事务边界,在xa start和xa end之间的语句就构成了本分支事务的一个事务范围。当调用xa end 'xid1’后由于结束了事务边界,所以这时候如果在执行sql语句会抛出ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the IDLE state错误,也就是当分支事务处于IDLE状态时候不允许执行没有包含到分支事务边界里面的其他sql.

对于一个IDLE 状态XA事务,可以执行一个XA PREPARE语句或一个XA COMMIT…ONE PHASE语句,其中XA PREPARE把事务放入PREPARED状态。在此点上的XA RECOVER语句将在其输出中包括事务的xid值,因为XA RECOVER会列出处于PREPARED状态的所有XA事务。XA COMMIT…ONE PHASE用于预备和提交事务,也就是转换为一阶段协议,直接提交事务。

对于一个PREPARED状态的 XA事务,可以执行XA COMMIT 语句来提交或者执行XA ROLLBACK来回滚xa事务。

其中二阶段协议中第一阶段是执行 xa prepare时候,这时候MySQL客户端(TM)向MySQL数据库服务器(RM)发出prepare"准备提交"请求,数据库收到请求后执行数据修改和日志记录等处理,处理完成后只是把事务的状态改成"可以提交",然后把结果返回给事务管理器。

如果第一阶段中数据库都prepare成功,那么mysql客户端(TM)向数据库服务器发出"commit"请求,数据库服务器把事务的"可以提交"状态改为"提交完成"状态,然后返回应答。如果在第一阶段内数据库的操作发生了错误,或者mysql客户端(RM)收不到数据库的回应,则认为事务失败,执行rollback回撤所有数据库的事务。

两阶段提交PC

在这里插入图片描述
mysql的两阶段提交原理

(1) perpare阶段 写入redo日志
1、设置undo state=TRX_UNDO_PREPARED;
2、刷事务更新产生的redo日志;
(2) commit阶段 写入binlog日志
1、将事务产生的binlog写入文件,刷入磁盘;
2、设置undo页的状态,置为TRX_UNDO_TO_FREE或TRX_UNDO_TO_PURGE; //标记可以清理回滚段
3、记录事务对应的binlog偏移,写入系统表空间。
两阶段提交是跨系统维持数据逻辑一致性时常用的一个方案。两阶段存在阻塞难题,提出的三阶段提交,在二阶段的基础上增加了一个预提交。
(3)假设法验证为什么分两阶段:
A. 先写 redo log 后写 binlog。假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行 c 的值是 1。
但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。
然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行 c 的值就是 0,与原库的值不同。
B. 先写 binlog 后写 redo log。如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,所以这一行 c 的值是 0。但是 binlog 里面已经记录了“把c 从 0 改成 1”这个日志。所以,在之后用 binlog 来恢复的时候就多了一个事务出来,恢复出来的这一行 c 的值就是 1,与原库的值不同。
(4)redo和binlog这两种日志有以下三点不同。
1、 redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
2、 redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
3、redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

2.外部XA事务

参与到外部分布式事务中(比如多个数据库实现的分布式事务),目前mysql对外部事务的支持还不够,这里也就不进行太多的描述了。

总结

以上就是这次对mysqlXA的理解和总结,主要参照mysql官方文档资料并加入自己的实践和理解,贴一下mysql官方文档地址,希望大家多多支持和关注。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mysql的分布式(XA)真面目 的相关文章

  • Java 枚举与创建位掩码和检查权限的混淆

    我想将此 c 权限模块移植到 java 但是当我无法将数值保存在数据库中然后将其转换为枚举表示形式时 我很困惑如何执行此操作 在 C 中 我创建一个如下所示的枚举 public enum ArticlePermission CanRead
  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • org.apache.hadoop.security.AccessControlException:客户端无法通过以下方式进行身份验证:[TOKEN,KERBEROS] 问题

    我正在使用 java 客户端通过 Kerberos 身份验证安全访问 HDFS 我尝试打字klist在服务器上 它显示已经存在的有效票证 我收到的异常是客户端无法通过以下方式进行身份验证 TOKEN KERBEROS 帮助将不胜感激 这是一
  • HSQL - 识别打开连接的数量

    我正在使用嵌入式 HSQL 数据库服务器 有什么方法可以识别活动打开连接的数量吗 Yes SELECT COUNT FROM INFORMATION SCHEMA SYSTEM SESSIONS
  • 如何在 Spring 中禁用使用 @Component 注释创建 bean?

    我的项目中有一些用于重构逻辑的通用接口 它看起来大约是这样的 public interface RefactorAwareEntryPoint default boolean doRefactor if EventLogService wa
  • 如何获取之前的URL?

    我需要调用我的网络应用程序的 URL 例如 如果有一个从 stackoverflow com 到我的网站 foo com 的链接 我需要 Web 应用程序 托管 bean 中的 stackoverflow 链接 感谢所有帮助 谢谢 并不总是
  • jQuery AJAX 调用 Java 方法

    使用 jQuery AJAX 我们可以调用特定的 JAVA 方法 例如从 Action 类 该 Java 方法返回的数据将用于填充一些 HTML 代码 请告诉我是否可以使用 jQuery 轻松完成此操作 就像在 DWR 中一样 此外 对于
  • 谷歌应用程序引擎会话

    什么是java应用程序引擎 默认会话超时 如果我们将会话超时设置为非常非常长的时间 会不会产生不良影响 因为谷歌应用程序引擎会话默认情况下仅存储在数据存储中 就像facebook一样 每次访问该页面时 会话仍然永远存在 默认会话超时设置为
  • 来自 dll 的 Java 调用函数

    我有这个 python 脚本导入zkemkeeperdll 并连接到考勤设备 ZKTeco 这是我正在使用的脚本 from win32com client import Dispatch zk Dispatch zkemkeeper ZKE
  • 没有 Spring 的自定义 Prometheus 指标

    我需要为 Web 应用程序提供自定义指标 问题是我不能使用 Spring 但我必须使用 jax rs 端点 要求非常简单 想象一下 您有一个包含键值对的映射 其中键是指标名称 值是一个简单的整数 它是一个计数器 代码会是这样的 public
  • 检测并缩短字符串中的所有网址

    假设我有一条字符串消息 您应该将 file zip 上传到http google com extremelylonglink zip http google com extremelylonglink zip not https stack
  • 从Django中具有外键关系的两个表中检索数据? [复制]

    这个问题在这里已经有答案了 This is my models py file from django db import models class Author models Model first name models CharFie
  • 无法创建请求的服务[org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]-MySQL

    我是 Hibernate 的新手 我目前正在使用 Spring boot 框架并尝试通过 hibernate 创建数据库表 我知道以前也问过同样的问题 但我似乎无法根据我的环境找出如何修复错误 休眠配置文件
  • 在 android 中建立与 MySQL 的池连接

    我需要从我的 Android 应用程序访问 MySQL 数据库 现在所有的工作都通过 DriverManager getConnection url 等等 但我必须从多个线程访问数据库 所以我必须使用连接池 问题1 是 com mysql
  • 快速将列的副本添加到 MySQL 表

    我需要一种快速的方法来复制表中的 DATETIME 列并为其指定一个新名称 我的表中有一个名为 myDate 的列 名为 myResults 我需要一个查询来在名为 newDate 的表中创建一个新列 该列的数据与 myDate 列完全相同
  • tomcat 中受密码保护的应用程序

    我正在使用 JSP Servlet 开发一个Web应用程序 并且我使用了Tomcat 7 0 33 as a web container 所以我的要求是tomcat中的每个应用程序都会password像受保护的manager applica
  • 如何访问JAR文件中的Maven资源? [复制]

    这个问题在这里已经有答案了 我有一个使用 Maven 构建的 Java 应用程序 我有一个资源文件夹com pkg resources 我需要从中访问文件 例如directory txt 我一直在查看各种教程和其他答案 但似乎没有一个对我有
  • 在我的 Spring Boot 示例中无法打开版本 3 中的 Swagger UI

    我在 Spring Boot 示例中打开 swagger ui 时遇到问题 当我访问 localhost 8080 swagger ui 或 localhost 8080 root api name swagger ui 时出现这种错误 S
  • java for windows 中的文件图标叠加

    我正在尝试像 Tortoise SVN 或 Dropbox 一样在文件和文件夹上实现图标叠加 我在网上查了很多资料 但没有找到Java的解决方案 Can anyone help me with this 很抱歉确认您的担忧 但这无法在 Ja
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db

随机推荐

  • WebSocket协议之NGINX代理转发无法建立连接问题处理

    WebScoket协议如需要通过nginx代理 需要location 节点增加以下节点即可正常建立连接 需要配置以下节点 proxy http version 1 1 proxy set header Upgrade http upgrad
  • Python入门网络爬虫之精华版,赶快收藏

    相关文件 关注小编 私信小编领取哟 当然别忘了一件三连哟 公众号 Python日志 前言 Python学习网络爬虫主要分3个大的版块 抓取 分析 存储 另外 比较常用的爬虫框架Scrapy 这里最后也详细介绍一下 举例子 当我们在浏览器中输
  • STL 中集合操作相关算法

    merge 头文件 merge 算法定义在头文件 include 中 算法作用 merge 算法是合并两个有序的序列 合并结果拷贝到一个新的序列 前提是这两个序列的排序规则一样 代码示例 vector
  • vue---UI框架elementUI实现系统登录注册页

    https blog csdn net maidu xbd article details 87943243已经搭建好了vue开发环境 在本博客中 来介绍些结合element ui实现登录注册界面 界面效果展示如下图 实现的功能包括 首先安
  • 【数据结构】红黑树模拟实现

    一 红黑树底层原理 红黑树的底层可以看作是AVL树的变种 先前我们了解过AVL的模拟实现 avl对整棵树的控制还是非常严格的 因为高度差不能大于2 导致会经常发生旋转 旋转这个过程也会降低效率 所以为了整体的效率衍生出了红黑树 红黑树旋转的
  • 稳压二极管工作原理、重要参数意义和典型电路参数计算

    稳压二极管的工作原理 稳压二极管也叫稳压管 它在电路中一般起到稳定电压的作用 也可以为电路提供基准电压值 稳压二极管使用特殊工艺制造 这种工艺使它在反向击穿时仍然可以长时间稳定工作 不损坏 而工作在反向击穿状态的稳压管只要工作电流保持在一定
  • 电感磁芯公式

    NBA LI
  • [机缘参悟-89]:《本质思考》- 本质思考的7种习惯

    目录 一 精准性思考 精确 表面词语要精确 二 非歧义思考 深度 明确表面词语背后的动机 三 多维度思考 广度 全方面思考 四 反馈式思考 确认 反复确认 五 适应性思考 变化 因环境变化而变化 六 循环式思考 持续改进 逐渐得到问题的本质
  • linux more 下一页_Linux more命令如何使用?

    Linux下的more命令主要用于分屏显示 即内容超过一屏的文件 与cat命令有点区别 下面小编就给大家详细介绍下more命令 有兴趣的话不妨来了解下吧 more会以一页一页的显示方便使用者逐页阅读 而最基本的指令就是按空白键 space
  • git:分支合并

    1 git 分支的合并 merge 假设我们此时需要修复dev分支上的某个bug 此时在dev分支上创建修复分支fix 然后推进fix分支 当前的git仓库如图 注 为了方便演示 dev分支上只有一个test cpp源文件 然后我们在fix
  • 利用Visio绘制数据流图

    http blog sina com cn s blog a3059cda01011meg html 利用Visio 2007来绘制网上书店系统的数据流图 利用Visio 2007创建Gane Sarson数据流图 可以选择 软件和数据库
  • 【满分】【华为OD机试真题2023 JS】简单的自动曝光

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 简单的自动曝光 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 一个图像有n个像素点 存储在一个长度为n的数组img里 每个像素点的取值范围 0 255 的正整数
  • 使用OpenCV库实现的模板轮廓匹配定位功能块

    c include
  • 批处理替换修改文件名

    echo off echo echo title 批量替换文件名中的部分字符串 color 3f echo Note echo 本批处理可批量替换本文件所在文件夹下的所有文件名的相同字符 echo echo echo echo echo e
  • CentOS 8 通过二进制安装 MySQL

    需求 CentOS8下采用二进制安装包的形式安装MySQL 并且指定数据库文件存放的路径地址 步骤如下 在 MySQL下载地址 中下载 MySQL 二进制安装包 注意 在版本选择的时候 版本号在8 0 11及以下包后缀都是 tar gz 但
  • Python中from from __future__ import *的用法

    from future import 参考 https blog csdn net zzc15806 article details 81133045 我们在读代码的时候 总是会看到代码开头会加上from future import 这样的
  • NoClassDefFoundError/ClassNotFoundException 到底从哪引用到了这个类?排查思路

    1 背景 公司内网登录改造升级 使用方需要配合升级 jar 包 本以为很简单的事情 升级版本上线就 OK 了 没想到升级头一个服务 部署到测试环境就有问题 2 表象 访问所有页面报 404 3 排查思路 3 1 排除法 确定是不是升级 ja
  • cmd简单游戏代码_制作一个猜数字的游戏

    十一节假日 我在敲代码 外甥女突然问我 舅舅 你能不能给我编个游戏啊 看着外甥女期盼的眼神 我当然不好拒绝啊 而且如果写一点代码 能让小朋友对编程有个简单的了解 甚至激发她对编程学习的兴趣 那也是极好的啊 话不多说 我立马敲一个猜数字的文字
  • api-ms-win-core-path-l1-1-0.dll丢失怎么解决?

    api ms win core path l1 1 0 dll文件可以帮助用户快速的启动一些相关的应用程序 让应用程序可以正常的使用 但是近期有用户在电脑的使用中 遇到了系统提示提示 api ms win core path l1 1 0
  • Mysql的分布式(XA)真面目

    Mysql XA 一 XA是什么 二 MySQL中XA实现 1 内部XA事务 两阶段提交PC 2 外部XA事务 总结 一 XA是什么 XA 协议本就是为一个分布式事务协议 它规定了 XA PREPARE XA COMMIT XA ROLLB