日期:2014-05-16  浏览次数:20814 次

MySQL 5.6性能提升的武器:Binlog Group Commit

在MySQL发布第一个5.6的GA版本时,我们对5.5.28 VS 5.6.10 做了个简单的sysbench性能对比测试(见之前的博客),测试是基于我们自己的标准配置(innodb_flush_log_at_trx_commit=1 & sync_binlog=1)。从测试结果来看,5.6的性能提升非常明显,但是我们当时并没有进行深入研究,定位到实际带来性能提升的最大原因。

后来有次读到一篇Dimitri Kravtchuk关于MySQL 5.6的Binlog Group Commit的文章(

http://planet.mysql.com/entry/?id=33502),我突然意识到这可能正是MySQL 5.6在我们的测试中有如此明显性能提升的原因,因此,我们进一步针对Binlog Group Commit的特性对5.5和5.6进行的对比测试。

?

关于 binary logs group commit:
a) 什么是 group commit
一般情况下,对于 Innodb 在每次事务提交时,需要通过 fsync 操作来告诉文件系统将可能在缓存中的数据刷新到磁盘,以此来保证数据持久化到磁盘中。
而对于文件系统来说, fsync 操作本身要消耗很多的 IO 资源,响应比较慢。所以,对于 IO 密集性的数据库来说,如果每一次事务提交都要进行一次 fsync 操作,那么 fsync 操作将会是数据库的一个很大的瓶颈,所以就有了 group commit 的概念。
也就是说当多个事务并发时,将多个在等待提交的 fsync 操作,合并到为仅调用一次 fsync 操作。,
b) Innodb 与 group commit
Mysql 从 5.0 开始由于支持“分布式事务和两阶段提交协议”(distributed transactions and Two Phase Commit /2PC),在代码实现时为了保证Binlog中的事务顺序和InnoDB Log(Transaction Log或者叫redo log)事务顺序一致,被动放弃了Group Commit。如果Binlog顺序不一致,那么备库就无法确保和主库有一致的数据。
这个问题直到 mysql 5.5 才开始部分修复,到 mysql 5.6 完全修复。在 mysql 5.5 中,只有当 sync_binlog = 0 时,才能使用 group commit,在 mysql 5.6中都可以进行 group commit。

?

测试环境:

16核+32G内存的HP580服务器,磁盘是4块15000转 150GB的Raid10

在同一台服务器上分别安装5.5.28和5.6.10进行对比测试。

?

测试场景:

对以下不同场合进行测试

  • log_bin=0/1
  • sync_binlog =0/1
  • 是/否有semi-sync的半同步从机

测试结果:

图例说明

  • mysql 5.5_11 tps 表示 mysql 5.5 的tps
  • mysql 5.5_11 sync 表示 mysql 5.5 每秒 fsync 的次数
  • mysql 5.5_11 groups 表示 mysql 5.5 的 group commit 的比例
  • 11 表示 log_bin 和 sync_binlog 参数的值
    其他以此类推?



?

?

?

?

??

?

?总结:

  1. Binary logs group commit 特性对 tps 的影响非常大,在 mysql 5.5 中使用 group commit 时的 tps 比不使用 group commit 时的 tps 要高将近 10倍的样子。
  2. Mysql 5.5 在使用 group commit 的情况下,tps 与 mysql 5.6 相比并不低,并且在某些时候可能要比 mysql 5.6 的 tps表现的还要好。
  3. 半同步复制情况下,由于 master 要确认 binglog 在 slave 上写入到中转日志,所以,如果从库的 IO 性能不好,或者网络有瓶颈的情况,会比较大的影响master的tps,在本测试中下降了将近 40%,但是就是在这种情况下,如果使用了 group commit,tps 还是要比不使用group commit时要高将近5倍。
  4. Group commit 的效果在一定范围内时会随着并发的加大,效果越好,tps也会相应的越高。

?

?