MySQL数据库是如何实现XA规范的

MySQL 的一致性日志

如果 MySQL 数据库断电了,未提交的事务怎么办?

答案:依靠日志。

因为在执行一个操作之前,数据库会首先把这个操作的内容写入到文件系统日志里,然后再进行操作。当宕机或者断电的时候,即使操作并没有执行完,但是日志在操作前就已经写好了,我们仍然可以根据日志的内容来进行恢复。

MySQL InnoDB 引擎中和一致性相关的有重做日志(redo log)、回滚日志(undo log)和二进制日志(binlog)。

redo log

每当有操作执行前,在数据真正更改前会先把相关操作写入 redo 日志。这样当发生断电等意外导致后续任务无法完成时,待系统恢复后就可以继续完成这些更改。

undo log

和 redo 日志对应,也叫撤消日志,记录事务开始前数据的状态。

当一些更改在执行一半时发生意外而无法完成,就可以根据撤消日志恢复到更改之前的状态。

举个例子,事务 T1 更新数据 X,对 X 执行 Update 操作,从 10 更新到 20,对应的 Redo 日志为 <T1, X, 20>,Undo 日志为 <T1, X, 10>。

binlog

是 MySQL sever 层维护的一种二进制日志,MySQL 最重要的日志之一,它记录了所有的 DDL 和 DML 语句,除了数据查询语句 select、show 等,还包含语句所执行的消耗时间。

binlog 与 InnoDB 引擎中的 redo/undo log 不同,主要目的是复制和恢复,用来记录对 MySQL 数据更新或潜在发生更新的 SQL 语句,并以事务日志的形式保存在磁盘中。

binlog 主要应用在 MySQL 的主从复制过程中,MySQL 集群在 Master 端开启 binlog,Master 把它的二进制日志传递给 slaves 节点,再从节点回放来达到 master-slave 数据一致的目的。

你可以连接到 MySQL 服务器,使用下面的命令查看真实的 binlog 数据:

//查看binlog文件的内容
show binlog events;

//查看指定binlog文件的内容
show binlog events in 'MySQL-bin.000001';

//查看正在写入的binlog文件
show master status\G

//获取binlog文件列表
show binary logs;

XA 规范是如何定义的

XA 是由 X/Open 组织提出的分布式事务规范,XA 规范主要定义了事务协调者(Transaction Manager)和资源管理器(Resource Manager)之间的接口。

事务协调者(Transaction Manager)

因为 XA 事务是基于两阶段提交协议的,所以需要有一个协调者,来保证所有的事务参与者都完成了准备工作,也就是 2PC 的第一阶段。

如果事务协调者收到所有参与者都准备好的消息,就会通知所有的事务都可以提交,也就是 2PC 的第二阶段。

之所以需要引入事务协调者,是因为在分布式系统中,两台机器理论上无法达到一致的状态,需要引入一个单点进行协调。

资源管理器(Resource Manager)

负责控制和管理实际资源,比如数据库或 JMS 队列。

目前,主流数据库都提供了对 XA 的支持,在 JMS 规范中,即 Java 消息服务(Java Message Service)中,也基于 XA 定义了对事务的支持。

XA 事务的执行流程

XA 事务是两阶段提交的一种实现方式,根据 2PC 的规范,XA 将一次事务分割成了两个阶段,即 Prepare 和 Commit 阶段。

Prepare 阶段

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

如果事务协调者 TM 收到所有参与者都准备好的消息,会通知所有的事务提交,然后进入第二阶段。

Commit 阶段

TM 接受到所有 RM 的 prepare 结果,如果有 RM 返回是不可提交或者超时,那么向所有 RM 发送 Rollback 命令。

如果所有 RM 都返回可以提交,那么向所有 RM 发送 Commit 命令,完成一次事务操作。

MySQL 如何实现 XA 规范

MySQL 中 XA 事务有两种情况,内部 XA 和外部 XA,其区别是事务发生在 MySQL 服务器单机上,还是发生在多个外部节点间上。

内部 XA

在 MySQL 的 InnoDB 存储引擎中,开启 binlog 的情况下,MySQL 会同时维护 binlog 日志与 InnoDB 的 redo log,为了保证这两个日志的一致性,MySQL 使用了 XA 事务,由于是在 MySQL 单机上工作,所以被称为内部 XA。

内部 XA 事务由 binlog 作为协调者,在事务提交时,则需要将提交信息写入二进制日志,也就是说,binlog 的参与者是 MySQL 本身。

外部 XA

外部 XA 就是典型的分布式事务,MySQL 支持 XA START/END/PREPARE/Commit 这些 SQL 语句,通过使用这些命令,可以完成分布式事务。

你也可以查看 MySQL 官方文档,了解更多的 XA 命令。

MySQL 外部 XA 主要应用在数据库代理层,实现对 MySQL 数据库的分布式事务支持,例如开源的数据库中间层,比如淘宝的 TDDL、阿里巴巴 B2B 的 Cobar 等。

外部 XA 一般是针对跨多 MySQL 实例的分布式事务,需要应用层作为协调者,比如我们在写业务代码,在代码中决定提交还是回滚,并且在崩溃时进行恢复。

binlog 中的 Xid

当事务提交时,在 binlog 依赖的内部 XA 中,额外添加了 Xid 结构,binlog 有多种数据类型:

  1. statement 格式,记录为基本语句,包含 Commit
  2. row 格式,记录为基于行
  3. mixed 格式,日志记录使用混合格式

不论是 statement 还是 row 格式,binlog 都会添加一个 XID_EVENT 作为事务的结束,该事件记录了事务的 ID 也就是 Xid,在 MySQL 进行崩溃恢复时根据 binlog 中提交的情况来决定如何恢复。

binlog 同步过程

下面来看看 binlog 下的事务提交过程,整体过程是先写 redo log,再写 binlog,并以 binlog 写成功为事务提交成功的标志。

当有事务提交时:

  • InnoDB 进入 Prepare 阶段,并且 write/sync redo log,写 redo log,将事务的 xid 写入到 redo 日志中,binlog 不作任何操作
  • 进行 write/sync binlog,写 binlog 日志,也会把 xid 写入到 binlog
  • 调用 InnoDB 引擎的 commit 完成事务的提交,将 commit 信息写入到 redo 日志中

如果是在第一步和第二步失败,则整个事务回滚

如果是在第三步失败,则 MySQL 在重启后会检查 xid 是否已经提交,若没有提交,也就是事务需要重新执行,就会在存储引擎中再执行一次提交操作,保障 redo log 和 binlog 数据的一致性,防止数据丢失。

实际执行还牵扯到操作系统缓存 buffer 何时同步到文件系统中,所以 MySQL 支持用户自定义在 commit 时如何将 log buffer 中的日志刷到 log file 中,通过变量 innodb_flush_log_at_trx_Commit 的值来决定。

在 log buffer 中的内容称为脏日志,感兴趣的话可以查询资料了解下。

以上就是MySQL数据库是如何实现XA规范的的详细内容,更多关于MySQL数据库XA规范的资料请关注我们其它相关文章!

(0)

相关推荐

  • mysql跨库事务XA操作示例

    本文实例讲述了mysql跨库事务XA操作.分享给大家供大家参考,具体如下: 前一段时间在工作中遇到了跨库事务问题,后来在网上查询了一下,现在做一下整理和总结. 1.首先要确保mysql开启XA事务支持 SHOW VARIABLES LIKE '%XA%' 如果innodb_support_xa的值是ON就说明mysql已经开启对XA事务的支持了. 如果不是就执行: SET innodb_support_xa = ON <?PHP $dbtest1 = new mysqli("172.20.

  • mysql的XA事务恢复过程详解

    mysql数据库开机报错: InnoDB: The log sequence number in ibdata files does not match InnoDB: the log sequence number in the ib_logfiles! 100224 12:24:20 InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery. InnoDB: Reading tablespace

  • MySQL存储表情时报错:java.sql.SQLException: Incorrect string value:‘\xF0\x9F\x92\xA9\x0D\x0A...’的解决方法

    前言 本文主要介绍了关于MySQL存储表情报错:java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\xA9\x0D\x0A...'的相关解决方法,分享出供大家参考学习,下面话不多说了,来一起看看详细的介绍: 本项目是基于Spring MVC + MySQL + Druid DataSource.在往数据库插入表情Emoji字符时报错: java.sql.SQLException: Incorrect string value:

  • xampp修改mysql默认密码的方法

    在这里介绍xampp修改mysql默认密码的大概过程是先利用xampp的phpmyadmin进入修改mysql密码,修改之后我们再修改xampp中phpmyadmin的密码,这样就完整的修改mysql默认密码了. 大概过程 在mysql里设密码打开IE输入网址localhostphpadmin之后,点用户看到有root用户,往下拉,找到修改密码的地方,输入密码,进行执行操作,最后再去到在你的xampp安装目录下找到phpadmin文件夹,打开找到config.inc.php文件之后,打开找关于m

  • ThinkPHP框架搭建及常见问题(XAMPP安装失败、Apache/MySQL启动失败)

    本文为大家详细分享了搭建ThinkPHP框架时遇到的问题,为大家提供了解决方法,具体内容如下 第一部分:框架搭建 我也是刚接触ThinkPHP,所以将目前的心得以及学习步骤按照我认为更容易理解的方式记录下来. 要使用ThinkPHP首先是要把环境搭建好,下面两个大体步骤来介绍: 第一步:下载软件 1.Xmapp(此软件将Apache.MySQL等集成了,使用起来很方便) 2.ThinkPHP3.2.3下载 第二步:搭建框架 1.将xmapp安装好,我们可以看到一个htdocs文件夹,我们可以将下

  • xampp中修改mysql默认空密码(root密码)的方法分享

    参考了网上提供的一些方法,发现说的都挺复杂.下面同大家分享一种简单快捷的方法. 首先说明下mysql用户的相关信息是保存在mysql数据库的user表中的,并且该表的密码字段(Password)是通过PASSWORD方法加密存储的. 明白了以上提示,那么修改密码就简单了,直接运行如下SQL语句即可(这里将密码修改为jb51.net): 复制代码 代码如下: UPDATE user SET password=PASSWORD('jb51.net') WHERE user='root'; 经过以上操

  • 解决xampp自启动和mysql.sock问题

    装了ubuntu好长一段时间了,都没去用,国庆的时候折腾了下,配置了一些基本的开发环境,一上手就感觉喜欢上了ubuntu,说不上为什么.为了搞本地的测试php测试环境而装了xampp,安装超简单,但是我发现它没有自启动.解决办法也很简单,通过下面的命令打开启动的资源文件: 复制代码 代码如下: x@zst:~$ cd /etc/init.d x@zst:/etc/init.d$ sudo gedit rc.local 在启动文件里加入一行代码: 复制代码 代码如下: /opt/lampp/lam

  • 在mac上如何使用终端打开XAMPP自带的MySQL

    直接开始,过程中对每一步可能出现的错误都进行了说明. 1.安装好xampp,然后打开终端,输入: mysql -u root -p 成功进入了,擦,你运气真好,后面不用看了. 2.如果提示command not found,则在终端继续输入执行: ln -s /applications/xampp/bin/mysql /usr/bin 注意:usr别写成来user! 如果成功执行,返回到第1步,就可以进入啦! 3.如果没有成功,返回operation not permitted,说明没有权限,这

  • 如何修改Xampp服务器上的mysql密码(图解)

    今天自己在搞php的过程中发现,如果我们使用Xampp服务器自带数据库mysql,就必须先修改mysql的密码,大家都知道,mysql的初始面为空,但是如果连接数据库是密码为空就会报错,在网上查找了很多解决类似问题的办法,都是打开mysql的命令控制台,解决办法如下图 但是按照网上的说法,顺着步骤坐下来还是有问题,mysql的密码还是没有修改,接下来我将为大家介绍自己修改成功的步骤: 1.点击MySQL的admin进入phpMyAdmin页面: 2.点击账户,进入账户管理页面: 3.选中root

  • MySQL数据库是如何实现XA规范的

    MySQL 的一致性日志 如果 MySQL 数据库断电了,未提交的事务怎么办? 答案:依靠日志. 因为在执行一个操作之前,数据库会首先把这个操作的内容写入到文件系统日志里,然后再进行操作.当宕机或者断电的时候,即使操作并没有执行完,但是日志在操作前就已经写好了,我们仍然可以根据日志的内容来进行恢复. MySQL InnoDB 引擎中和一致性相关的有重做日志(redo log).回滚日志(undo log)和二进制日志(binlog). redo log 每当有操作执行前,在数据真正更改前会先把相

  • MySQL数据库使用规范总结

    导读: 关于MySQL数据库规范,相信大家多少看过一些文档.本篇文章给大家详细分类总结了数据库相关规范,从库表命名设计规范讲起,到索引设计规范,后面又给出SQL编写方面的建议.相信这些规范适用于大多数公司,也希望大家都能按照规范来使用我们的数据库,这样我们的数据库才能发挥出更高的性能. 关于库: 1.[强制]库的名称必须控制在32个字符以内,英文一律小写. 2.[强制]库的名称格式:业务系统名称_子系统名. 3.[强制]库名只能使用英文字母,数字,下划线,并以英文字母开头. 4.[强制]创建数据

  • Mysql数据库锁定机制详细介绍

    前言 为了保证数据的一致完整性,任何一个数据库都存在锁定机制.锁定机制的优劣直接应想到一个数据库系统的并发处理能力和性能,所以锁定机制的实现也就成为了各种数据库的核心技术之一.本章将对MySQL中两种使用最为频繁的存储引擎MyISAM和Innodb各自的锁定机制进行较为详细的分析. MySQL锁定机制简介 数据库锁定机制简单来说就是数据库为了保证数据的一致性而使各种共享资源在被并发访问访问变得有序所设计的一种规则.对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自然也不能例外.MyS

  • java基于jdbc连接mysql数据库功能实例详解

    本文实例讲述了java基于jdbc连接mysql数据库的方法.分享给大家供大家参考,具体如下: 一.JDBC简介 Java 数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法.JDBC也是Sun Microsystems的商标.它JDBC是面向关系型数据库的. 1.JDBC架构: JDBC API支持两层和三层处理模型进行数据库访问,但在一般的JDBC体系结构由

  • Python MySQLdb模块连接操作mysql数据库实例

    mysql是一个优秀的开源数据库,它现在的应用非常的广泛,因此很有必要简单的介绍一下用python操作mysql数据库的方法.python操作数据库需要安装一个第三方的模块,在http://mysql-python.sourceforge.net/有下载和文档. 由于python的数据库模块有专门的数据库模块的规范,所以,其实不管使用哪种数据库的方法都大同小异的,这里就给出一段示范的代码: #-*- encoding: gb2312 -*- import os, sys, string impo

  • Python连接mysql数据库的正确姿势

    Python 数据库接口支持非常多的数据库,你可以选择适合你项目的数据库: GadFly mSQL MySQL PostgreSQL Microsoft SQL Server 2000 Informix Interbase Oracle Sybase 不同的数据库你需要下载不同的DB API模块,例如你需要访问Oracle数据库和Mysql数据,你需要下载Oracle和MySQL数据库模块. DB-API 是一个规范. 它定义了一系列必须的对象和数据库存取方式, 以便为各种各样的底层数据库系统和

  • 在MySQL数据库中使用C执行SQL语句的方法

    他们将讨论返回数据的语句,例如INSERT以及不返回数据的语句,例如UPDATE和DELETE.然后,他们将编写从数据库检索数据的简单程序 执行SQL语句 现在,我们已经有了一个连接,并且知道如何处理错误,是时候讨论使用我们的数据库来作一些实际工作了.执行所有类型的SQL的主关键字是mysql_query: int mysql_query(MYSQL *connection, const char *query) 正如您所见,它非常简单.它取一个指向连接结构的指针和包含要执行的SQL的文本字符串

  • Mysql数据库之Binlog日志使用总结(必看篇)

    binlog二进制日志对于mysql数据库的重要性有多大,在此就不多说了.下面根据本人的日常操作经历,并结合网上参考资料,对binlog日志使用做一梳理: 一.binlog日志介绍 1)什么是binlog binlog日志用于记录所有更新了数据或者已经潜在更新了数据(例如,没有匹配任何行的一个DELETE)的所有语句.语句以"事件"的形式保存,它描述数据更改. 2)binlog作用 因为有了数据更新的binlog,所以可以用于实时备份,与master/slave主从复制结合. 3)和b

  • python 专题九 Mysql数据库编程基础知识

    在Python网络爬虫中,通常是通过TXT纯文本方式存储,其实也是可以存储在数据库中的:同时在WAMP(Windows.Apache.MySQL.PHP或Python)开发网站中,也可以通过Python构建网页的,所以这篇文章主要讲述Python调用MySQL数据库相关编程知识.从以下几个方面进行讲解: 1.配置MySLQ 2.SQL语句基础知识 3.Python操作MySQL基础知识 4.Python调用MySQL示例 一. 配置MySQL 首先下载mysql-5.0.96-winx64,安装

  • Python操作MySQL数据库的三种方法总结

    1. MySQLdb 的使用 (1) 什么是MySQLdb? MySQLdb 是用于 Python 连接 MySQL 数据库的接口,它实现了 Python 数据库 API 规范 V2.0,基于 MySQL C API 上建立的. (2) 源码安装 MySQLdb: https://pypi.python.org/pypi/MySQL-python $ tar zxvf MySQL-python-*.tar.gz $ cd MySQL-python-* $ python setup.py buil

随机推荐