innodb_support_xa=1

mysql> show create table t;
CREATE TABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `num` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=gbk
)

mysql> select * from t;
+----+------+
| id | num  |
+----+------+
|  1 |    1 |
|  4 |    2 |
+----+------+
2 rows in set (0.01 sec)

http://www.gpfeng.com/?p=298

mysql> xa start ‘xa_2‘;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test.t(num) values(2);
Query OK, 1 row affected (0.18 sec)

mysql>  xa end ‘xa_2‘;
Query OK, 0 rows affected (0.00 sec)

mysql>  xa prepare ‘xa_2‘;
Query OK, 0 rows affected (0.18 sec)

mysql> show binlog events;
+----------+-----+----------------+-----------+-------------+---------------------------------------------+
| Log_name | Pos | Event_type     | Server_id | End_log_pos | Info                                        |
+----------+-----+----------------+-----------+-------------+---------------------------------------------+
| 1.000001 |   4 | Format_desc    |         1 |         120 | Server ver: 5.6.28-debug-log, Binlog ver: 4 |
| 1.000001 | 120 | Previous_gtids |         1 |         151 |                                             |
+----------+-----+----------------+-----------+-------------+---------------------------------------------+
2 rows in set (0.00 sec)

mysql> xa commit ‘xa_2‘;
Query OK, 0 rows affected (0.00 sec)

mysql> show binlog events;
+----------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name | Pos | Event_type     | Server_id | End_log_pos | Info                                                              |
+----------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| 1.000001 |   4 | Format_desc    |         1 |         120 | Server ver: 5.6.28-debug-log, Binlog ver: 4                       |
| 1.000001 | 120 | Previous_gtids |         1 |         151 |                                                                   |
| 1.000001 | 151 | Gtid           |         1 |         199 | SET @@SESSION.GTID_NEXT= ‘c35d11dd-4f0b-11e6-964d-000c29fcecda:1‘ |
| 1.000001 | 199 | Query          |         1 |         278 | BEGIN                                                             |
| 1.000001 | 278 | Intvar         |         1 |         310 | INSERT_ID=4                                                       |
| 1.000001 | 310 | Query          |         1 |         417 | use `test`; insert into test.t(num) values(2)                     |
| 1.000001 | 417 | Query          |         1 |         490 | COMMIT                                                            |
+----------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
7 rows in set (0.01 sec)

mysql> 
真正意义上了解innodb_support_xa(分布式事务)

从官方解释来看,innodb_support_xa的作用是分两类:第一,支持多实例分布式事务(外部xa事务),这个一般在分布式数据库环境中用得较多。第二,支持内部xa事务,说白了也就是说支持binlog与innodb redo log之间数据一致性。

今天的重点是讨论第二类内部xa事务。
        首先我们需要明白为什么需要保持binlog与redo log之间数据一致性,这里分两个方面来解释:
第一,保证binlog里面存在的事务一定在redo log里面存在,也就是binlog里不会比redo log多事务(可以少,因为redo log里面记录的事务可能有部分没有commit,这些事务最终可能会被rollback)。

先来看这样一个场景(后面的场景都是假设binlog开启):在一个AB复制环境下主库crash,然后进行crash recovery,此时如果binlog里面的的事务信息与redo log里面的信息不一致,那么就会出现主库利用redo log进行恢复后,然后binlog部分的内容复制到从库去,然后出现主从数据不一致状态。所以需要保证binlog与redo log两者事务一致性。
第二,保证binlog里面事务顺序与redo log事务顺序一致性。

这也是很重要的一点,假设两者记录的事务顺序不一致,那么会出现类似于主库事务执行的顺序是ta, tb, tc,td,但是binlog里面记录的是ta,tc, tb, td,binlog复制到从库后导致主从的数据不一致。当然也由于当初蹩脚的设计导致BGC被打破,这里就不详说了。

为了达到上面说的两点,mysql是怎么来实现的呢?没错,答案是内部xa事务(核心是2pc)。现在mysql内部一个处理流程大概是这样:
1. prepare ,然后将redo log持久化到磁盘 <Fsync>
2. 如果前面prepare成功,那么再继续将事务日志持久化到binlog  <Fsync>
3. 如果前面成功,那么在redo log里面写上一个commit记录      <Fsync>

可以通过组提交把多个事物 fsync 提交合为一次fync
那么假如在进行着三步时又任何一步失败,crash recovery是怎么进行的呢? 此时会先从redo log将最近一个检查点开始的事务读出来,然后参考binlog里面的事务进行恢复。如果是在1 crash,那么自然整个事务都回滚;如果是在2 crash,那么也会整个事务回滚;如果是在3 crash(仅仅是commit记录没写成功),那么没有关系因为2中已经记录了此次事务的binlog,所以将这个进行commit。所以总结起来就是redo log里凡是prepare成功,但commit失败的事务都会先去binlog查找判断其是否存在(通过XID进行判断,是不是经常在binlog里面看到Xid=xxxx?这就是xa事务id),如果有则将这个事务commit,否则rollback。
在这三个步骤中因为持久化需求每一步都需要fsync,但是如果真的每一步都需要fsync,那么sync_binlog与innodb_flush_log_at_trx_commit两个参数的意义又在哪?这里还没理得很清楚,希望自己以后补上来或是谁帮忙解答一下。

        前面已经解释完了通过内部xa事务来保证binlog里记录的事务不会比redo log多(也可以间接的理解为binlog一定只记录提交事务),这么做的原因是为了crash recovery后主从保持一致性。接下来解释目前是怎么来保证binlog与redo log之间顺序一致的。
        为什么要保证binlog里事务与redo log里事务顺序一致性原因前面已经解释过。为了保证这一点带来的问题相信了解过BGC的朋友都知道----臭名昭著的prepare_commit_mutex,没错就是它导致了正常情况下无法实现BGC,原理是什么?在每次进行xa事务时,在prepare阶段事务先拿到一个全局的prepare_commit_mutex, 然后执行前面说的持久化(fsync)redo log与binlog,然后等fsync完了之后再释放prepare_commit_mutex,这样相当于串行化的效果虽然保证了binlog与redo log之间顺序一致性,但是却导致每个事务都需要一个fsync操作,而大家都知道在一次持久化的过程中代价最大的操作就是fsync了,而想write()这些不落地的操作代价相对来说就很小。所以BGC得核心在于很多事务需要的fsync合并成一个fsync去做。
         说了这么多就只为了解释innodb_support_xa=1的价值在哪,但是刚才也说了由于xa事务中需要多次fsync,所以开启后会对性能有一定影响。从percona博客上看到06年他们测试时开启后tps下降一半,但是我实际用mysql-5.5.12+sysbench-0.5+10块SAS(raid 10)测试结果性能下面没那么明显。在oltp模式下tps几乎没差别,不过它默认读写比例是4:1,后来换成纯update测试,开始xa事务性能下降也仅仅是5%左右,没有传说中那么大的差别。所以我怀疑可能的原因有两个:第一,现在的mysql性能相对于06有了较大提升;第二,我测试的机器较好(10块SAS盘做raid10),这样即使开启了xa事务,需要较多的fsync,但是由于存储方面能抗住,所以没有体现出太大的劣势。

innodb_flush_log_at_trx_commit意义以及合理设置。innodb_flush_log_at_trx_commit有0、1、2三个值分别代表不同的使redo log落地策略。

0:表示每秒进行一次flush,但是每次事务commit不进行任何操作(每秒调用fsync使数据落地到磁盘,不过这里需要注意如果底层存储有cache,比如raid cache,那么这时也不会真正落地,但是由于一 般raid卡都带有备用电源,所以一般都认为此时数据是安全的)<master thread 与 大于1/2的缓存>  <log cache>

1:代表每次事务提交都会进行flush,这是最安全的模式。<commit--->disk>

2:表示每秒flush,每次事务提交时不flush,而是调用write将redo log buffer里面的redo log刷到os page cache。  <写到缓存,由OS 管理>

        那现在来比较三种策略的优劣势:1由于每次事务commit都会是redo log落地所以是最安全的,但是由于fsync的次数增多导致性能下降比较厉害。 <0表示每秒flush,每次事务提交不进行任何操作,所以mysql crash或者os crash时会丢失一秒的事务。2相对于0来说了多了每次事务commit时会有一次write操作,此时数据虽然没有落地到磁盘但是只要没有 os crash,即使mysql crash,那么事务是不会丢失的。2相对于0来说会稍微安全一点点。
        所以关于这两个参数,我的建议是主库开始innodb_support_xa=1,从库不开(因为从库一般不会记binlog,),数据一致性还是很重要的。

而对于innodb_flush_log_at_trx_commit,除非是对数据很重要,不能丢事务,否则我建议设置成2。我看到有些公司设置成0。

其实我个人认为都设置成0了就没有多少理由不设置成2,因为2带来的性能损耗是每个事务一个write操作,write操作的开销相对于fsync还是小很多的,但是这点开销换来了即使mysql挂掉事务依然不会丢的好处。
时间: 2024-10-20 09:34:33

innodb_support_xa=1的相关文章

了解innodb_support_xa(分布式事务)

innodb_support_xa可以开关InnoDB的xa两段式事务提交.默认情况下,innodb_support_xa=true,支持xa两段式事务提交.此时MySQL首先要求innodb prepare,对应的redolog 将写入log buffer:如果有其他的引擎,其他引擎也需要做事务提交的prepare,然后MySQL server将binlog将写入:并通知各事务引擎真正commit:InnoDB将commit标志写入,完成真正的提交,响应应用程序为提交成功.这个过程中任何出错将

浅析innodb_support_xa与innodb_flush_log_at_trx_commit

很久以前对innodb_support_xa存在一点误解,当初一直认为innodb_support_xa只控制外部xa事务,内部的xa事务是mysql内部进行控制,无法人为干预(这里说的内部xa事务主要是指binlog与innodb的redo log保持一致性所采用的内部xa事务).直到前阵子在微博上看到有人讨论mysql数据安全时才仔细去手册上查看了关于innodb_support_xa的解释,这几天又与同事再次讨论了这个问题,于是想着还是将其记录下来.先看官方手册上对innodb_suppo

innodb_support_xa

从官方解释来看,innodb_support_xa的作用是分两类: 第一,支持多实例分布式事务(外部xa事务),这个一般在分布式数据库环境中用得较多. 第二,支持内部xa事务,说白了也就是说支持binlog与innodb redo log之间数据一致性. 今天的重点是讨论第二类内部xa事务. 首先我们需要明白为什么需要保持binlog与redo log之间数据一致性,这里分两个方面来解释: 第一,保证binlog里面存在的事务一定在redo log里面存在,也就是binlog里不会比redo l

mysql 开发进阶篇系列 20 MySQL Server(innodb_lock_wait_timeout,innodb_support_xa,innodb _log_*)

1. innodb_lock_wait_timeout mysql 可以自动监测行锁导致的死锁并进行相应的处理,但是对于表锁导致的死锁不能自动监测,所以该参数主要用于,出现类似情况的时候等待指定的时间后回滚.系统默认值是50秒.用户可以根据业务自行设置.生产环境不推荐使用过大的 innodb_lock_wait_timeout 参数值. -- 查看事务超时时间 SHOW VARIABLES LIKE 'innodb_lock_wait_timeout'; 也可以对当前会话进行超时设置如: set

MySQL 主从复制、主主复制、半同步复制

MySQL 复制 =============================================================================== 概述: =============================================================================== MySQL Replication:   1.主从复制的目的和架构 ★Master/Slave(主/从) Master: write/read Slave

自动安装MySQL脚本

在Linux 上安装MySQL单实例SHELL脚本 在CentOS 6.5环境测试通过 #!/bin/bash user=mysql group=mysql port=3306 basedir=/usr/local/mysql datadir=/data/mysql/mysql_${port}/data sourcefile=$1 mysqlprofile=/etc/my.cnf logfile=/tmp/mysqlinstall.log nowtime=`date '+%Y-%m-%d %H:

Chapter 5 MySQL Server Administration_1

Chapter 5 MySQL Server Administration Table of Contents 5.1 The MySQL Server 5.1.1 Configuring the Server 5.1.2 Server Configuration Defaults 5.1.3 Server Option and Variable Reference 5.1.4 Server Command Options 5.1.5 Server System Variables 5.1.6

MySQL binlog相关分析

1.redolog.binlog的简单分析 图解:redolog和binlog机制 2.开启binlog及关注点 3.关注binlog的相关参数 4.binlog模式分析 5.关于binlog的使用 补充:双一模式 一.区别redolog和binlog 1.如下表格的一个简单对比   redolog binlog 日志作用 保护脏数据 数据库备份恢复使用 引擎支持 只适合InnoDB引擎 所有引擎 日志格式 物理日志 逻辑日志,SQL语句 提交方式 快速提交 提交时一次性写入 保存形式 会被循环

MySQL Group Replication

group replication是一种全新的高可用,高扩张的MySQL集群服务.高一致性,基于原生复制及paxos协议的组复制技术,以插件方式提供一致数据安全保证:高容错性,大多数服务正常就可继续工作,自动不同节点检测资源征用冲突,按顺序优先处理,内置自动防脑裂机制:高扩展性,自动添加移除节点,并更新组信息:高灵活性,单主模式和多主模式.单主模式自动选主,所有更新操作在主进行:多主模式,所有server同时更新. 0,修改hostsvim /etc/hostslocalhost 127.0.0