MySQL/InnoDB和Group Commit(2)

今天发现Percona Release的Percona-Server-5-5-18-23-0已经完成了Group Commit工作,而且是用最优雅的方式(移植了MariaDB的实现,而不是workaround),心里难掩激动。

这篇文章接前篇继续介绍一下问题的背景:什么是Group Commit,现在的官方版本Group Commit做到了什么程度?

1. 什么是Group Commit

MySQL/InnoDB在做事务的时候使用的日志先行(Write-ahead logging)的方式保证事务的快速和持久,所以每次事务完成都要求日志必须持久化到磁盘,在Linux上对应的操作就是“write and fsync”,write速度是很快的,一般对应的写Page Cache,而fsync则要求文件系统把对应文件的哦Page Cache必须持久化到磁盘上,而对于传统磁盘一次写操作大约需要1~3ms(不说BBU),这意味着对于传统磁盘1秒钟最多最多做333~1000个事务,这是不理想的,对硬件的利用率(吞吐量)也是非常低。

所以,这里就有了Group操作的概念,即当好几个线程都要fsync同一个日志文件时,我们将这些fsync合并到一次来做。简单举例:我们让系统每2ms做一次fsync,这样如果这2ms内有100个线程都需要做fsync,那就赚到了,原本100个fsync都独立来做那耗时会非常多的。

你肯定会说,难道这不是很简单的想法吗?是的,这就是原本是很简单、也很自然的想法。

但对MySQL来说却变成了一种奢求(看看这个Bug讨论)。

2. 为啥MySQL一直没有实现?

MySQL是不是太弱了,这么简单的事情都搞不定?不是的。

MySQL从开源到现在,成功的一个非常重要的原因,就是MySQL的插件式架构。如果MySQL只是MyISAM估计不会有现在的流行程度,插件式的架构让诸如Heikki Tuuri有了发挥空间,在InnoDB和MySQL一起时,MySQL才能算是一个真正的DBMS。再到后来,有Infobright、 FEDERATED、PBXT等等。

插件式的架构给MySQL带来了活力,做出牺牲便是在上层(MySQL)和下层(存储引擎)交互时带来的额外消耗,有时甚至上层和下层需要做一些重复工作。无法做Group Commit就是这其中的牺牲之一。

3. 现在的官方版本Group Commit做到了什么程度

InnoDB在一次事务中,有两次fsync,分别是prepare阶段和commit阶段,对于这两次操作InnoDB都是实现了Group操作的。

如果你设置了binlog_sync=1,则又多了一次fsync操作(参考MYSQL_BIN_LOG::flush_and_sync),这次操作在innobase_xa_prepare和innodb_commit之间:

binlog_prepare (do nothing)
innodb_prepare
...
binlog_commit
innobase_commit

这次fsync,在MySQL中一直都无法做Group。所以,一直以来当innodb_flush_log_at_trx_commit和binlog_sync都等于1的时候,MySQL的性能就非常、非常糟糕。原因是为了保证InnoDB内部Commit的顺序和MySQL日志的顺序一致(参考)。

4. 开源社区的努力

难道没人去解决这个问题吗?不是的。有很多人已经做出了努力,直到Kristian Nielsen@MariaDB提出了理论和实际上的最优解决方案。

Mark Callaghan@Facebook关于Group Commit做的工作:FB的基本实现 | FB的问题和改进 | 性能 | 对比MariaDB的实现(对比的结果是MariaDB完胜,无论是方案架构还是性能)

Facebooke可以说是通过一个Trick快速实现了Group Commit。而Kristian Nielsen@MariaDB这是从架构上根本的解决了这个问题。

MariaDB关于Group Commit架构和实现: WL116 | WL132 | WL164

5. 未完待续

后面还有很多值得写的,我希望自己能够一直写完这个系列。

时间: 2024-11-03 22:04:49

MySQL/InnoDB和Group Commit(2)的相关文章

MySQL源码学习:InnoDB关于group commit的简单QA

    前天同事问了个问题,今天又再翻了下group commit.关于这个话题Kristian Nielsen有一个很详尽的系列文章(http://kristiannielsen.livejournal.com/12254.html), 有四个页面,文中有链接.这里列出一些细节,主要是对上面文章补充一下. Q:什么是group commit. A:1) 简单说就是:好几个线程写文件,然后一个线程fsync: 2) 只有事务日志(ib_logfile)用到: 3) 注意是多个线程(多用户).一个

MySQL Group Commit的优化

最近花了一些时间在做MySQL Group Commit的优化,关于Group commit的原理,这里不再赘述,有兴趣的可以翻阅我之前的博客http://mysqllover.com/?p=581,这里简单描述下两点优化,主要基于MySQL5.6.16 1.优化binlog_order_commits=0并且sync_binlog>0时的性能  我们知道当binlog_order_commits关闭时,表示我们能接受binlog commit和innodb commit的顺序不同(这不会带来数

MySQL内核月报 2015.01-MySQL · 性能优化· Group Commit优化

背景 关于Group Commit网上的资料其实已经足够多了,我这里只简单的介绍一下. 众所周知,在MySQL5.6之前的版本,由于引入了Binlog/InnoDB的XA,Binlog的写入和InnoDB commit完全串行化执行,大概的执行序列如下: 当sync_binlog=1时,很明显上述的第二步会成为瓶颈,而且还是持有全局大锁,这也是为什么性能会急剧下降. 很快Mariadb就提出了一个Binlog Group Commit方案,即在准备写入Binlog时,维持一个队列,最早进入队列的

MySQL内核月报 2014.12-TokuDB· Binary Log Group Commit with TokuDB

MySQL在开启Binary Log的情况下,使用2PC(图1)来保证事务(XA)完整性的,每次提交事务需要做: 每个事务在提交的时候都要做3次fsync以确保日志真正的落盘,这样在log里,一个事务就会有3种状态: 这样,无论处于任何一个状态,事务的完整性都不会被破坏,但是每次提交会产生3次fsync,性能非常低. 为了提升性能,MySQL 5.6增加了group commit功能,当多个事务并发提交时,让多个都在等待fsync的事务合并做一次fsync,大大提升了吞吐量. 但是这个优化还需要

MySQL InnoDB Replication Slave 太慢解决办法

Master 的是标? MySQL, Slave 换成 Percona, 没想到反而跟不上进度, 而且 Slave 与 Master 差距越来越远. InnoDB 效能调校文件与说明 由文件找到有个参数可以调整: innodb_flush_log_at_trx_commit 此参数调整的原因: InnoDB 预设是每次写入, 就会将 Log 写入(Flush)硬碟, 所以会很慢. innodb_flush_log_at_trx_commit 的值可以设?橄率鋈?? (预设是 1), 下述取自此篇

Oracle和MySQL分组查询GROUP BY

Oracle和MySQL分组查询GROUP BY 真题1.Oracle和MySQL中的分组(GROUP BY)有什么区别?答案:Oracle对于GROUP BY是严格的,所有要SELECT出来的字段必须在GROUP BY后边出现,否则会报错:"ORA-00979: not a GROUP BY expression".而MySQL则不同,如果SELECT出来的字段在GROUP BY后面没有出现,那么会随机取出一个值,而这样查询出来的数据不准确,语义也不明确.所以,作者建议在写SQL语句

MySQL InnoDB Cluster环境搭建和简单测试

InnoDB Cluster初印象   记得MySQL Group Replicatioin 刚开始的时候,MySQL界很是轰动,等待了多年,终于有了官方的这个高可用解决方案.你要说还有一些方案补充,比如MySQL Cluster,MySQL Proxy,这些的使用率个人感觉还是不高,也就是经受的考验还不够,原因有很多,就不赘述了.    不久,我和一个MySQL DBA有了下面的一个基本对话.    我: MySQL GR GA之后,里面的自动切换功能确实很赞,能够做到读写分离,原本MHA的方

反驳"MySQL InnoDB (不行)的性能问题",千万级别记录来测试说明

在 JavaEye 上看到一篇对 MySQL FUD(Fear, uncertainty and doubt) 的文章 用MySQL InnoDB Benchmark 性能测试来说明 http://www.javaeye.com/topic/34676 文中提到:"InnoDB 的磁盘性能很令人担心,MySQL 缺乏良好的 tablespace 真是天大的缺陷! --网上有用户反映存在同样的插入性能问题,百万行记录插入之后,插入速度下降到了 1/30,从开始的 1600行/秒衰退到 50行/秒-

详解MySQL分组查询Group By实现原理

由于GROUP BY 实际上也同样会进行排序操作,而且与ORDER BY 相比,GROUP BY 主要只是多了排序之后的分组操作.当然,如果在分组的时候还使用了其他的一些聚合函数,那么还需要一些聚合函数的计算.所以,在GROUP BY 的实现过程中,与 ORDER BY 一样也可以利用到索引. 在MySQL 中,GROUP BY 的实现同样有多种(三种)方式,其中有两种方式会利用现有的索引信息来完成 GROUP BY,另外一种为完全无法使用索引的场景下使用.下面我们分别针对这三种实现方式做一个分