相关参数
binlog_order_commits
— 控制事务的提交顺序,1为和binlog的写入顺序一致,0为事务并行进行;一般情况下两者在性能上并没有明显差别。
binlog_max_flush_queue_time
– 是指在flush queue里扫描的时长。
WHY 2PC
Binlog是server层记录数据改变的日志,存储引擎层是最终记录数据变化的地方,为了保证复制架构中,主从数据保持一致,就需要做到主库上binlog中的更新也一定在存储引擎层被记录(redo log),同时还需要保证存储引擎层上的提交顺序与binlog中记录更新的顺序保持一致,所以就需要这么一种提交机制two-phrase commit protocol(2PC)。
在2PC中,通过binlog中是否存在更新的事务来判断,存储引擎层的更新是全部提交还是全部回滚;通过prepare_commit_mutex使得事务顺序化提交,保证存储引擎端的commit顺序与binlog的写入顺序一致。
Commit Procedure Stages
为了实现binary log group commit特性,需要将prepare_commit_mutex去除,同时要保证commit顺序与binlog write()顺序一致,实现方法是将最后一步的commit分成3个阶段去完成,即1st – flush stage、2nd – sync stage、3rd – commit stage。
Flush stage — 将需要进行commit操作线程注册到队列里来,对于一个空队列,先注册进入的为leader,之后的为follower,这些队列中的线程都已经完成将binlog cache中的跟新写入(write())binlog文件(写入操作系统的文件cache)中。
Sync stage – 根据sync_binlog参数的设置选择同步(fsync())binlog 文件到磁盘(“真正”的数据落地,当然磁盘也会有cache,但对于文件系统来说数据已经写入磁盘已经被持久化)的方式,是one commit 对应one fsync(),还是由文件系统来决定。
Commit stage – 最会由leader按照线程注册的先后顺序,统一去完成每个session下的commit工作。
性能比对
Binary log group commit的实现对于MySQL5.6的性能有了强劲的提升,对于sync_binlog设置为0与1,随着并发连接数的不断增加,两者的差异越来越不明显,在起初并发连接数少的情况下,不能发挥group commit的效果,会带来20%的性能落差。Group commit使得一次commit的事务数增多,即便当sync_binlog为1时,由于现在一次commit的对象是一个queue,而一个queue里面包含不止一条要被commit的事务,所以,在参数binlog_max_flush_queue_time触发之前,当queue中注册执行commit操作的线程数越多,那么在sync stage执行fsync()的效率就越高。
学习资源
Binary Log Group Commit in MySQL 5.6 这是一篇关于group commit介绍非常细致的文章以上的文字都是基于对这篇文章的理解,希望大家也来仔细读一下,说说自己的理解,其实我对于这个东西也没有完全理解,尤其是flush stage,还有参数binlog_max_flush_queue_time何时触发。
深入学习
http://dev.mysql.com/worklog/task/?id=5223