作者在之前写的一篇关于mysql 5.6与mysql 5.7的半同步性能对比测试的文章中,提到mysql的半同步的一个bug . 当时提出了在mysql 5.6中并未曾遇到这个bug (作者确实未曾在5.6上遇到这个bug,回头看来,这个原因也很可能是性能上的差异导致),而事实上,这个bug在5.6就存在,周末在bug库里面找到了这个bug ,确实目前还没有程序员分享(贡献)解决这个Bug的代码。
下面来看这个bug的详细信息:
代码描述的详细地址:http://bugs.mysql.com/bug.php?id=78680
bug触发的条件是:当事务执行到正在提交的函数Trans_delegate::after_commit() 时,同时将master的半同步状态设置为on .
如何重复,如下(截取bug 提交者的说明进行描述)
This was interesting to reproduce. (这是一个非常有趣的重现)
I attached a log file with details, but in short: (我提交了一个日志文件进行描述,简单说来如下)
– run mysqld with semi-sync DISABLED (首先mysqld将半同步的插件运行在异步状态下,也就是semi-sync DISABLED )
– run a DML statement , but block it when Trans_delegate::after_commit() is called (通过debug_sync函数设置断点,将执行dml 语句的会话堵塞在Trans_delegate::after_commit() 这个函数的入口处)
– in another thread, enable semi-sync (用另外一个会话,将半同步开启)
– let the DML statement complete with semi-sync ENABLED (然后之前被block的dml 语句的会话继续运行)。
– mysqld will crash (mysqld crash).
因此,只有当其他会话正执行到这个函数Trans_delegate::after_commit() 时,将半同步从异步状态设置会同步状态时,则会引发mysqld crash . 因此,事务并发越多,越容易刚好在这个函数点上撞上,导致mysqld crash 。
现在来说说,为什么在mysql 5.6上,作者为什么未曾遇到设置mysql半同步时出现crash的现象,通过对比测试发现,mysql 5.6的事务提交速度比mysql5.7低,因此事务并发提交的速度也没有mysql5.7快,所以刚好撞上的概率也就低。