MySQL里面的innodb_support_xa

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
日志服务 SLS,月写入数据量 50GB 1个月
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 在看innodb_support_xa之前我们要先看下什么是XA,什么是两阶段提交。 XA 一个协调分布式事务的标准接口,为了遵从ACID原则,允许多个DB参与事务。为了查看更多,请 Section 13.3.7, “XA Transactions”。

在看innodb_support_xa之前我们要先看下什么是XA,什么是两阶段提交。

XA

一个协调分布式事务的标准接口,为了遵从ACID原则,允许多个DB参与事务。为了查看更多,请 Section 13.3.7, “XA Transactions”。
通常情况下,默认都启用了XA分布式事务支持。如果你没有用这个特性,你可以配置innodb_support_xa,避免为每个事务执行fsync带来的性能损耗。
在MySQL 5.7.10版本不启用innodb_support_xa,因为它使主备复制不安全和降低了与二进制日志group commit相关的性能。
在MySQL 8.0中这个innodb_support_xa选项被移除掉了。

两阶段提交

简言之,两阶段提交是在XA规范下,分布式事务里面的一部分操作(有时也被称为2PC)。当事务里面有多个DB操作时,要么都提交,要么都回滚。下面的图更容易理解些。
下面的一段引用沃趣科技 MySQL数据库专家 @pickup112,找不到原文请见谅

第一阶段:

首先,协调者在自身节点的日志中写入一条的日志记录,然后所有参与者发送消息prepare T,询问这些参与者(包括自身),是否能够提交这个事务;
参与者在接受到这个prepare T 消息以后,会根据自身的情况,进行事务的预处理,如果参与者能够提交该事务,则会将日志写入磁盘,并返回给协调者一个ready T信息,同时自身进入预提交状态状态;如果不能提交该事务,则记录日志,并返回一个not commit T信息给协调者,同时撤销在自身上所做的数据库改;
参与者能够推迟发送响应的时间,但最终还是需要发送的。

第二阶段:

协调者会收集所有参与者的意见,如果收到参与者发来的not commit T信息,则标识着该事务不能提交,协调者会将Abort T 记录到日志中,并向所有参与者发送一个Abort T 信息,让所有参与者撤销在自身上所有的预操作;
如果协调者收到所有参与者发来prepare T信息,那么协调者会将Commit T日志写入磁盘,并向所有参与者发送一个Commit T信息,提交该事务。若协调者迟迟未收到某个参与者发来的信息,则认为该参与者发送了一个VOTE_ABORT信息,从而取消该事务的执行。
参与者接收到协调者发来的Abort T信息以后,参与者会终止提交,并将Abort T 记录到日志中;如果参与者收到的是Commit T信息,则会将事务进行提交,并写入记录。
一般情况下,两阶段提交机制都能较好的运行,当在事务进行过程中,有参与者宕机时,他重启以后,可以通过询问其他参与者或者协调者,从而知道这个事务到底提交了没有。当然,这一切的前提都是各个参与者在进行每一步操作时,都会事先写入日志。
引用结束

innodb_support_xa

innodb_support_xa的作用?

innodb_support_xa可以开关InnoDB的xa两段式事务提交。

如何开启?

innodb_support_xa=true,支持xa两段式事务提交。

如何运转?

innodb_support_xa=true,支持xa两段式事务提交。此时MySQL首先要求innodb prepare,对应的redolog 将写入log buffer;如果有其他的引擎,其他引擎也需要做事务提交的prepare,然后MySQL server将binlog将写入;并通知各事务引擎真正commit;InnoDB将commit标志写入,完成真正的提交,响应应用程序为提交成功。这个过程中任何出错将导致事务回滚,响应应用程序为提交失败。也就是说,在这种情况下,基本不会出错。

为什么启用innodb_support_xa?

如果不启用innodb_support_xa,事务再写到binlog文件时可能会和现在的db在commit的时候顺序不一样,当这些binlog应用到恢复数据库或者在备库执行时,可能会产生不一样的数据
它可以保证InnoDB两阶段提交(prepare,commit).这不仅仅在用户发起的XA,在内部的XA协调InnoDB事务日志和MySQL的binlog日志,保证数据一致。数据一致是一个非常非常重要。内部的XA就是MySQL Server层,即以binlog为准。

开启innodb_support_xa带来的影响?

如果在XA事务里面启用了InnoDB支持两阶段提交,在事务准备阶段将会带来额外的刷盘操作,性能影响会达到5%,所有为了提高性能,有些DBA会设置innodb_support_xa=false。这样的话,redolog和binlog将无法同步,可能存在事务在主库提交,但是没有记录到binlog的情况。这样也有可能造成事务数据的丢失。

为什么会影响性能?

我们来看下两阶段提交的过程:

Prepare InnoDB [ha_prepare]:
1.1 Write prepare record to log buffer
1.2 fsync() log file to disk (this can currently do group commit)
1.3 Take prepare_commit_mutex
Log transaction to binary log [TC_LOG_BINLOG::log_xid]:
2.1 Lock binary log
2.2 Write transaction data to binary log
2.3 Sync binary log based on sync_binlog. This forces the binlog to always fsync() (no group commit) due to prepare_commit_mutex
2.4 Unlock binary log
Commit InnoDB:
3.1 Release prepare_commit_mutex
3.2 Write commit record to log buffer
3.3 Sync log buffer to disk (this can currently do group commit)
3.4 InnoDB locks are released

从上面的步骤里面,我们可以看到会调用会刷redolog和binlog,那会势必会影响写入的性能。那么这个可以控制刷盘的速度吗?可以。
redolog的控制参数是innodb_flush_log_at_trx_commit

描述
0 一秒InnoDB log buffer刷新一次到硬盘。在事务commit时不刷新log buffer到log file.由于调度问题,不保证一秒一刷新的操作一定能发生。mysqld crash后导致丢失最后一秒的事务。
1 出于完全遵从ACID原则的目的,默认值是1.在每个事务commit时,InnoDB log buffer里面的内容都要写入log file,并且log file刷到磁盘。With this value, the contents of the InnoDB log buffer are written out to the log file at each transaction commit and the log file is flushed to disk.
2 每个事务提交后,InnoDB log buffer里面的内容都要写入log file,log file大约每秒刷一次盘。the contents of the InnoDB log buffer are written to the log file after each transaction commit and the log file is flushed to disk approximately once per second.由于进程调度问题,每秒刷一次盘不保证100%的都能发生。Once-per-second flushing is not 100% guaranteed to happen every second, due to process scheduling issues. 因为innodb_flush_log_at_timeout.默认是1秒,操作系统crash或电源故障导致丢失最后一秒的事务。

InnoDB log 的刷新频率是由 innodb_flush_log_at_timeout 控制的, 这个值默认是1单位秒.
以下两种情况不受innodb_flush_log_at_trx_commit的限制:

  • DDL和其他InnoDB内部活动如果要刷新InnoDB日志的话
  • InnoDB crash recovery 工作, 事务要么整个被应用要么整个被回滚
    当然这里还有另外一个比较重要的参数innodb_flush_method,打开连接就可以了,在这里就不再说了。

binlog的控制参数是sync_binlog
默认参数是0。如果这个值比0大,在sync_binlog把commit groups提交到二进制日志,MySQL Server就会指定 通过调用fdatasync()的方式把binlog同步到磁盘。

描述
0 不用同步到磁盘。在这种情况下,MySQL Server就依赖操作系统像刷新其他文件一样,不时地刷新binlog日志。
1 最安全的选择,当MySQL crash后,在binlog里面最多丢失一个commit group的数据。然而,这也是最慢的选择(除非磁盘有个电池cache,可以让同步更快)。

对于InnoDB事务最安全的做法是:

sync_binlog=1
innodb_flush_log_at_trx_commit=1

下面的情况可以关闭innodb_support_xa,即innodb_support_xa=false:

  • 可以接受在服务器上只有一个线程修改数据,对于InnoDB表为了提高性能可以关闭这个选项
  • 当只有一个SQL线程修改数据的时候,可以在slave上关闭innodb_support_xa
  • 不需要保证binlog或者主备复制的数据安全,不需要一个外部的XA事务管理者时,你可以关闭这个选项

参考

https://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_support_xa
https://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_xa
https://dev.mysql.com/doc/refman/5.6/en/replication-options-binary-log.html#sysvar_sync_binlog
https://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
http://mysqlmusings.blogspot.com/2010/04/binary-log-group-commit-implementation.html
https://linux.cn/article-1157-2.html

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
23天前
|
存储 关系型数据库 MySQL
介绍MySQL的InnoDB引擎特性
总结而言 , Inno DB 引搞 是 MySQL 中 高 性 能 , 高 可靠 的 存 储选项 , 宽泛 应用于要求强 复杂交易处理场景 。
63 15
|
6月前
|
存储 网络协议 关系型数据库
MySQL8.4创建keyring给InnoDB表进行静态数据加密
MySQL8.4创建keyring给InnoDB表进行静态数据加密
150 1
|
10月前
|
存储 缓存 关系型数据库
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
MySQL的存储引擎是其核心组件之一,负责数据的存储、索引和检索。不同的存储引擎具有不同的功能和特性,可以根据业务需求 选择合适的引擎。本文详细介绍了MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案。
1677 57
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
|
6月前
|
SQL 缓存 关系型数据库
使用温InnoDB缓冲池启动MySQL测试
使用温InnoDB缓冲池启动MySQL测试
105 0
|
11月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
341 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
10月前
|
存储 关系型数据库 MySQL
MySQL存储引擎详述:InnoDB为何胜出?
MySQL 是最流行的开源关系型数据库之一,其存储引擎设计是其高效灵活的关键。InnoDB 作为默认存储引擎,支持事务、行级锁和外键约束,适用于高并发读写和数据完整性要求高的场景;而 MyISAM 不支持事务,适合读密集且对事务要求不高的应用。根据不同需求选择合适的存储引擎至关重要,官方推荐大多数场景使用 InnoDB。
230 7
|
10月前
|
存储 关系型数据库 MySQL
Mysql索引:深入理解InnoDb聚集索引与MyisAm非聚集索引
通过本文的介绍,希望您能深入理解InnoDB聚集索引与MyISAM非聚集索引的概念、结构和应用场景,从而在实际工作中灵活运用这些知识,优化数据库性能。
556 7
|
10月前
|
存储 关系型数据库 MySQL
MySQL引擎InnoDB和MyISAM的区别?
InnoDB是MySQL默认的事务型存储引擎,支持事务、行级锁、MVCC、在线热备份等特性,主索引为聚簇索引,适用于高并发、高可靠性的场景。MyISAM设计简单,支持压缩表、空间索引,但不支持事务和行级锁,适合读多写少、不要求事务的场景。
150 9
|
11月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的表空间
InnoDB是MySQL默认的存储引擎,主要由存储结构、内存结构和线程结构组成。其存储结构分为逻辑和物理两部分,逻辑存储结构包括表空间、段、区和页。表空间是InnoDB逻辑结构的最高层,所有数据都存放在其中。默认情况下,InnoDB有一个共享表空间ibdata1,用于存放撤销信息、系统事务信息等。启用参数`innodb_file_per_table`后,每张表的数据可以单独存放在一个表空间内,但撤销信息等仍存放在共享表空间中。
159 6
|
11月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的段、区和页
MySQL的InnoDB存储引擎逻辑存储结构与Oracle相似,包括表空间、段、区和页。表空间由段和页组成,段包括数据段、索引段等。区是1MB的连续空间,页是16KB的最小物理存储单位。InnoDB是面向行的存储引擎,每个页最多可存放7992行记录。
216 5

推荐镜像

更多