2011-05-20 19 views
2

在MySQL的文档以下称有关innodb_support_xa选项:在MySQL中,为什么关闭innodb_support_xa进行单线程更新是安全的?

启用InnoDB的支持两阶段提交的XA事务,导致了交易准备一个额外的磁盘刷新。该设置是默认设置。 XA机制在内部使用,对于其二进制日志处于打开状态且正在接受来自多个线程的数据更改的任何服务器而言都是必不可少的。 如果将其关闭,则事务可以以与实时数据库提交它们的顺序不同的顺序写入二进制日志。当在灾难恢复或复制从服务器上重播二进制日志时,这可能会产生不同的数据。不要在复制主服务器上关闭它,除非您有一个不寻常的设置,只有一个线程可以更改数据。

对于只接受来自一个线程的数据更改的服务器,这是安全的,建议关闭此选项以提高InnoDB表的性能。例如,您可以在只有复制SQL线程正在更改数据的复制从站上将其关闭。

然而,从阅读臭名昭著group commit bug我的理解,2PC来保证事务日志和二进制日志包含相同的交易,而prepare_commit_mutex负责确保相同的顺序。

使用prepare_commit_mutex,写入事务日志和binlog已经被序列化,那么多线程和单线程更新之间有什么区别?另一方面,即使没有2PC,只有一个线程可以改变数据,如果事务写入到二进制日志但在写入事务日志之前发生崩溃,Innodb如何去处理这种复苏状况?理论上,它可以简单地执行binlog中的未完成事务,就像奴隶做的一样,但我怀疑Innodb是否真的这样做,因为否则为什么我们需要2PC?

我并不熟悉MySQL的内部,所以请原谅我,如果我非常错误。谢谢!

回答

2

首先...

http://yoshinorimatsunobu.blogspot.com/2009/08/great-performance-effect-of-fixing.html

之前InnoDB的插件1.0.4,它是这样的:

obtain mutex 
    write innodb log and fsync, for prepare-phase (skip if innodb_support_xa=0) 
    write binlog (fsync as appropriate if sync_binlog > 0) 
    write innodb log and fsync, for commit-phase 
release mutex 

在和InnoDB插件1.0.4(和MySQL 5.5)后, ,现在是:

write innodb log and fsync, for prepare-phase (skip if innodb_support_xa=0) 
obtain mutex 
    write binlog (fsync as appropriate if sync_binlog > 0) 
    write innodb log, for commit-phase 
release mutex 
fsync innodb log, for commit-phase 

正如你所看到的,在新版本中,除了在案例sync_binlog> 0)在临界区域是fsync'd。这样,现在组提交工作并确保更好的并发吞吐量。例如,如果你有100个线程的并发提交,所有的fsyncs都被序列化,你可以得到100个fsyncs用于准备,另外100个fsyncs用于提交。因此团体提交被彻底打破。

现在使用较新的实现,fsyncs根据事务的并发性进行分组,同时确保innodb日志和binlog之间的操作顺序。这也意味着,如果只有一个线程,就没有性能提升。

至于你的问题,当一个事务写入二进制日志后,但在写入事务日志之前发生崩溃时 - 我和你在同一页面上。

如果服务器的最后一步之前坠毁,有你有InnoDB日志和二进制日志之间的差异(或者一个可能是领先于其他的)轻微的机会,但可以保证你有上的所有信息如何在innodb日志中检查,因为它是在准备阶段记录的。

但是,如何处理未提交的内容仍然是不确定的。例如,除非sync_binlog = 1有一个机会,奴隶收到的数据,但没有完全fsync'd在主机上的二进制日志尚未。您不能只重做失败的事务,因为它可能已经在其中一个从属服务器上运行。

这也意味着binlog可能比innodb日志短,返回“二进制日志[file_name]比预期的大小短。”正如在官方文档中所描述的那样,你必须从头开始重新构建奴隶。不太友善。

http://dev.mysql.com/doc/refman/5.1/en/binary-log.html

如在操作顺序的规定保持一致,保证独立的innodb_support_xa设定的(这违背了什么在innodb_support_xa官方文档说,也许是因为它是之前迄今为止写了关于股票的InnoDB 5.0.3并发修复),并且即使使用innodb_support_xa,也不能严格保证从服务器上的主日志和中继日志上innodb日志的一致性,但我没有看到使用innodb_support_xa的任何一点。尽管不遵循官方的建议,但是它很可怕,但是在许多方面它似乎是陈旧和错误的。

我不知道是否有当前设置为innodb_flush_log_at_trx_commit设置和innodb_support_xa行为之间的关系2或0

思维

一个实际的方式是,故障转移到从属是安全的 - 之后所有这些失败的交易都是你想要完成的事情,但从未失败回复掌握,因为数据可能存在一些差异。在将主设备设置为新的从设备之前,您需要完全复制从设备的数据。换句话说,当主人崩溃时,从此相信奴隶 - 这样,您就不需要为innodb日志混淆崩溃恢复。

另请注意,MySQL 5.5支持半同步复制,与“信任奴隶”一样 - 认为您可能会感兴趣。

http://dev.mysql.com/doc/refman/5.5/en/replication-semisync.html

+0

innodb_support_xa已被弃用在5.7 ... – Sebas 2016-03-07 00:21:36

+0

@Sebas评论是有点模糊,根据MySQL的文档:“innodb_support_xa已取消,将在未来的MySQL版本支持InnoDB移除,以用于两相。 XA事务中的提交始终从MySQL 5.7.10开始启用“因此它已被弃用,但仅仅因为它始终处于打开状态。 – 2016-04-13 15:44:41

相关问题