最近遇到一个主从同步断开的案例,是由于运维新手在执行GRANT语句时,语法写错了,也就可以理解为无效的GRANT语句,我们收到slave库同步断开的报警信息,然后去找问题,发现binlog有报错,报错提示谷歌一下,才知道原来这是一个bug,下面我们进行问题还原,看看发生了什么。
当时用的MySQL版本是:5.6.10
下面我们在MySQL 5.6.10版本做测试,查看slave库信息是处于同步的一个状态:
在master库上查看status信息:
在master库上执行无效grant语句:
mysql> grant file on sakila.* to [email protected]‘192.168.10.129‘;
相信大家都看到图了吧,binlog由mysql-bin.000012变成了mysql-bin.000013,那就意味着当执行了无效的grant的时候,可能做了类似flush logs的操作,我们查看mysql-bin.000012发现报这样的错:
RELOAD DATABASE; # Shall generate syntax error
现在我们回到slave库查看一下信息:
看到了,同步已经断开,报The incident LOST_EVENTS occured on the master. Message: error writing to the binary log错误!!!!
以下几种grant写法,都触发刷新了binlog:
解决方法:
1)使用sql_slave_skip_counter跳过事件,但此方法只适用于基于二进制日志原理的复制,不适用于基于GTID原理的复制。
2)使用slave_skip_errors跳过错误。
3)在从库上做change master操作,重新切换master_log_file和master_log_pos。(由于无效的grant语句执行后会创建新的二进制日志,所以可以指定主库show master status的master_log_file和master_log_pos)
下面我们在MySQL 5.5.40测试:
查看slave库的信息如下:
在mater查看status并执行无效grant语句:
可以看到,binlog还是原来的binlog,并没有出现像MySQL5.6的那种情况,我们查看下slave的情况可以看到依然处于同步状态:
总结:现在越来越多公司用MySQL5.6的版本了,的确MySQL5.6的版本,相对MySQL5.5版本已经改善了不少,所以很多公司已经升级或者直接用上了MySQL5.6,如果线上用的中5.6版本的MySQL,grant授权的时候就要注意了,无效grant可能会触发刷新了binlog,特别对于那种一主多库的架构,slave提供读的情况,就更要注意了,这可能是一个bug,在网上找资料的时候,看到5.6.11还有5.6.13都有出现这样的情况,如果有别的见解的朋友,希望能一起请请讨论分享下,谢谢。
参考资料:
http://www.psce.com/blog/2013/04/09/granting-privileges-may-break-replication-in-mysql-5-6-10/
https://bugs.mysql.com/bug.php?id=68892(自备梯子)