在MySQL中,为什么关闭innodb_support_xa单线程更新是否安全?

时间:2011-05-20 03:16:53

标签: mysql innodb

在MySQL的文档中,关于innodb_support_xa选项的说法如下:

  

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

     

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

但是,根据我对臭名昭着的group commit bug阅读的理解,2PC用于保证事务日志和binlog包含相同的事务集,而prepare_commit_mutex负责确保同样的顺序。

使用prepare_commit_mutex,对事务日志和binlog的写入已经被序列化,那么多线程和单线程更新之间有什么区别?

另一方面,即使只有一个线程可以更改数据,没有2PC,如果在将事务写入binlog后发生崩溃,但在将其写入事务日志之前,Innodb将如何进行处理这种复苏情况?理论上它可以简单地执行binlog中的未完成事务,就像奴隶一样,但我怀疑Innodb实际上是这样做的,因为否则为什么我们需要2PC?

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

1 个答案:

答案 0 :(得分: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个线程并发提交,则所有fsync都被序列化,您将获得100个fsyncs用于准备,另外100个fsyncs用于提交。因此,群组提交完全被破坏。

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

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

如果服务器在最后一步之前崩溃,那么innodb日志和binlog之间的差异很小(任何一个可能先于另一个),但保证你拥有所有信息如何在innodb日志中检查,因为它记录在准备阶段。

然而,如何处理未提交的仍然是不确定的。例如,除非sync_binlog = 1,否则从属设备可能会收到数据但尚未完全fsync对主设备上的binlog。您不能只重做失败的事务,因为它可能已经在其中一个从设备上运行。

这也意味着,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时看不到任何意义。然而,不遵循官方建议是可怕的,但在许多方面它似乎陈旧和错误。

我想知道当前者设置为2或0时,innodb_flush_log_at_trx_commit设置和innodb_support_xa行为之间是否存在任何关联。

一种实用的思维方式是,故障转移到从属设备是安全的 - 毕竟,失败的事务是您想要完成的事情 - 但绝不会失败回到主设备,因为数据可能存在一些差异。在将主设备作为新从设备之前,需要从从设备完全复制数据。换句话说,当主机崩溃时,从那时起就信任奴隶 - 这样,你就不需要乱用innodb日志来进行崩溃恢复。

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

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