一个事务提交时,采取的是先写日志后刷入磁盘的方式。假如此时有多个用户同时提交,那么按照顺序把写入的事务日志页刷入磁盘上,就会导致磁盘做多次I/O操作,从而降低IOPS吞吐率。
从MySQL5.5.X版本开始,会采用组提交的方式来将事务刷入磁盘中,也就是说,如果有多个用户同时提交事务,那么就合并在一起一次性来刷入磁盘,大大提高了吞吐量。
举个搬饮料放入库房的例子:以前,搬运工每次搬一箱饮料放入库房,这样进入库房的频率就很高,他来来回回的也很累,后来他索性每次搬5箱饮料,这样一次搬的东西多了,进出库房的频率也就变低了。
注意
组提交工作模式只支持在sync_binlog = 0的情况下, 同样,innodb_support_xa也必须等于0。其目的是保证InnoDB存储引擎的redo log事务日志与binlog日志的顺序一致。
例如,在1分钟里有5条更新记录,其顺序是:
1) begin;update t1 set money= money +1000 where uid=11; commit;
2) begin;update t1 set money= money -2000 where uid=11; commit;
3) begin;insert into t2(uid,money) values(12,2000); commit;
4) begin;insert into t3(uid,money) values(13,3000); commit;
5) begin;insert into t4(uid,money) values(14,4000); commit;
未采用组提交模式时,t1表的uid=11账户里有1000元,按照正常顺序是先存入1000,然后再取出2000元,接着其他uid做后面的开户插入操作。而如果采用组提交模式,其顺序是:
1) begin;
update t1 set money= money +1000 where uid=11;
insert into t2(uid,money) values(12,2000);
insert into t3(uid,money) values(13,3000);
insert into t4(uid,money) values(14,4000);
commit;
2) begin;update t1 set money= money -2000 where uid=11; commit;
在sync_binlog等于1时,先写入binlog_cache,事务提交后会马上刷入binlog日志,这样按照MySQL源码编写方式是不能合并到一起提交的。而如果sync_binlog 等于1,仍旧采取组提交模式,其顺序有可能是这样:
1) begin;update t1 set money= money -2000 where uid=11;commit;
2) begin;
update t1 set money= money +1000 where uid=11;
insert into t2(uid,money) values(12,2000);
insert into t3(uid,money) values(13,3000);
insert into t4(uid,money) values(14,4000);
commit;
这样就出现了问题,t1表的uid=11账户里只有1000元,取出2000元会提示报错,并回滚,导致该用户取钱失败,如果开启了同步复制,也会把binlog日志同步到slave上,所以采取组提交模式,sync_binlog 必须等于0。
此特性无须更改任何参数即可实现。
关于恢复组提交介绍,请参见MySQL5.5手册: