MySQL里面的innodb_support_xa

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: 在看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

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
14天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
123 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
14天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的表空间
InnoDB是MySQL默认的存储引擎,主要由存储结构、内存结构和线程结构组成。其存储结构分为逻辑和物理两部分,逻辑存储结构包括表空间、段、区和页。表空间是InnoDB逻辑结构的最高层,所有数据都存放在其中。默认情况下,InnoDB有一个共享表空间ibdata1,用于存放撤销信息、系统事务信息等。启用参数`innodb_file_per_table`后,每张表的数据可以单独存放在一个表空间内,但撤销信息等仍存放在共享表空间中。
|
14天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的段、区和页
MySQL的InnoDB存储引擎逻辑存储结构与Oracle相似,包括表空间、段、区和页。表空间由段和页组成,段包括数据段、索引段等。区是1MB的连续空间,页是16KB的最小物理存储单位。InnoDB是面向行的存储引擎,每个页最多可存放7992行记录。
|
15天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL的InnoDB存储引擎
InnoDB是MySQL的默认存储引擎,广泛应用于互联网公司。它支持事务、行级锁、外键和高效处理大量数据。InnoDB的主要特性包括解决不可重复读和幻读问题、高并发度、B+树索引等。其存储结构分为逻辑和物理两部分,内存结构类似Oracle的SGA和PGA,线程结构包括主线程、I/O线程和其他辅助线程。
【赵渝强老师】MySQL的InnoDB存储引擎
|
1月前
|
存储 缓存 关系型数据库
详细解析MySQL中的innodb和myisam
总之,InnoDB和MyISAM各有千秋,选择合适的存储引擎应基于对应用程序特性的深入理解,以及对性能、数据完整性和可扩展性的综合考量。随着技术发展,InnoDB因其全面的功能和日益优化的性能,逐渐成为更广泛场景下的首选。然而,在特定条件下,MyISAM依然保留其独特的价值。
128 0
|
3月前
|
监控 关系型数据库 MySQL
在Linux中,mysql的innodb如何定位锁问题?
在Linux中,mysql的innodb如何定位锁问题?
|
3月前
|
SQL 存储 关系型数据库
"MySQL增列必锁表?揭秘InnoDB在线DDL,让你的数据库操作飞一般,性能无忧!"
【8月更文挑战第11天】在数据库领域,MySQL凭借其稳定高效的表现深受开发者喜爱。对于是否会在给数据表添加列时锁表的问题,MySQL的行为受版本、存储引擎等因素影响。从5.6版起,InnoDB支持在线DDL,可在改动表结构时保持表的可访问性,避免长时间锁表。而MyISAM等则需锁表完成操作。例如,在使用InnoDB的表上运行`ALTER TABLE users ADD COLUMN email VARCHAR(255);`时,通常不会完全锁表。虽然在线DDL提高了灵活性,但复杂操作或大表变更仍可能暂时影响性能。因此,进行结构变更前应评估其影响并择机执行。
73 6
|
4月前
|
存储 SQL 关系型数据库
(十三)MySQL引擎篇:半道出家的InnoDB为何能替换官方的MyISAM?
MySQL是一款支持拔插式引擎的数据库,在开发过程中你可以根据业务特性,从支持的诸多引擎中选择一款适合的,例如MyISAM、InnoDB、Merge、Memory(HEAP)、BDB(BerkeleyDB)、Example、Federated、Archive、CSV、Blackhole.....
|
4月前
|
存储 关系型数据库 MySQL
MySQL InnoDB存储引擎的优点有哪些?
上述提到的特性和优势使得InnoDB引擎非常适合那些要求高可靠性、高性能和事务支持的场景。在使用MySQL进行数据管理时,InnoDB通常是优先考虑的存储引擎选项。
178 0
|
5月前
|
关系型数据库 MySQL 调度
深入理解MySQL InnoDB线程模型
深入理解MySQL InnoDB线程模型
下一篇
无影云桌面