zoukankan      html  css  js  c++  java
  • XA事务与MySQL

    XA事务就是两阶段提交的一种实现方式

    XA规范主要定义了事务管理器TM,和资源管理器RM之间的接口

    根据2PC的规范,将一次事务分割成两个阶段

    1. prepare阶段

    TM向所有RM发送prepare指令,RM接受到指令后执行数据修改和日志记录等操作,然后返回 可以提交/不可提交 给TM

    (按照我的理解应该类似于MySQL在开启一个事务之后,只差最后的COMMIT或者ROLLBACK的状态)

    2. commit阶段

    TM接受到所有RM的prepare结果

    如果有RM返回是 不可提交 或者超时,那么向所有RM发送ROLLBACK命令

    如果所有RM都返回可以提交,那么向所有RM发送COMMIT命令

    XA的异常情况处理

    MySQL与XA事务的关系有两种情况

    1. 内部XA

    在使用innodb作为存储引擎,并且开启binlog的情况下,MySQL同时维护了binlog日志与innodb的redo log

    为了保证这两个日志的一致性,MySQL使用了XA事务,由于只在单机上工作,所以被称为内部XA

    2. 外部XA

    就是一般谈论的分布式事务了

    MySQL支持XA START/END/PREPARE/COMMIT这些sql语句,通过使用这些命令,我们是可以完成分布式事务的

    状态转移图如下

     (我有点不能理解的是,为什么一定需要XA END这个语句,直接XA PREPARE不行吗)

    在MySQL5.7.7之前,XA事务是有bug的

    如果有一个XA事务处于PREPARE状态

    1. 如果连接关闭,或者MySQL服务器正常退出,这个事务会被回滚(但是根据XA规范,这个事务应该被保留)

    2. 如果MySQL服务器被强制结束,在重启之后,用XA RECOVER命令可以看到这个事务,这个事务也可以被XA COMMIT所提交,但是相关的binlog记录会丢失,这样就会导致数据库引擎中的数据与binlog中的数据不一致   (参考资料

    这两个bug被提出了十年之久,终于在5.7.7中被修正了第一个bug阿里自己也搞了个修正

    就目前来看,MySQL的XA事务现在做得还不错,应该是可用的

    还是有一些不能理解的地方

    1. 官方文档中强调:在使用分布式事务的时候,需要使用串行隔离级别,为什么?

    (As with nondistributed transactions, SERIALIZABLE may be preferred if your applications are sensitive to read phenomena. REPEATABLE READ may not be sufficient for distributed transactions.)

     原因:为了尽可能提高分布式事物的隔离级别,如果分库上使用MySQL默认的RR,那么导致总的分布式事务的隔离级别为RU

    参考资料

    1. MySQL binlog 组提交与 XA(两阶段提交)

    2. MySQL redolog与组提交 资料1 资料2 资料3 资料4

    3. MySQL官方的XA文档

    4. XA事务的隔离级别

  • 相关阅读:
    数据结构之双向链表
    数据结构入门之链表(C语言实现)
    机器人操作臂运动学入门一--D-H参数标定
    机器学习--逻辑回归
    python字符串方法的简单使用
    python学习之网页数据获取
    《机器学习实战》学习笔记一K邻近算法
    杂事
    洛谷 P1926 小书童——刷题大军
    洛谷 P1968 美元汇率
  • 原文地址:https://www.cnblogs.com/stevenczp/p/6265686.html
Copyright © 2011-2022 走看看