MySQL:主从复制从库GTID大量空洞的问题

作者简介:高鹏,笔名八怪。《深入理解MySQL主从原理》图书作者,同时运营个人公众号“MySQL学习”,持续分享遇到的有趣case以及代码解析!

一、问题来源

这是今天的一个问题,是朋友杨长江给我的,版本MySQL 5.7.17。问题为show slave status遇到了大量的空洞,如下:

这里只是部分截屏,GTID SET已经分成了无数段。正常情况下我们的从库GTID SET应该是不会出现这种大量的空洞的。这种问题还是很常见的,如果这个时候重启从库,那么会根据GTID的下限去主库拿binlog,但是主库的binlog很可能已经清理了这些事务,也就必然会导致从库报错。

二、相关BUG

已知的一个BUG是skip-slave-error参数设置问题,这个我已经提交过BUG了,而且这个BUG在8.0.25依旧存在,参考如下:

  • https://mp.weixin.qq.com/s/dqky9htiUhM55zUoeS3dlg

而拿到朋友的参数文件后,发现并没有设置skip-slave-error参数,那么是其他什么BUG导致的呢?实际上这个BUG是5.7.23以下的版本,并且设置了replicate_wild_do_table等过滤规则后,对CREATE DATABASE/ALTER DATABASE/DROP DATABASE会做过滤掉操作,并且从库的GTID也会被抛弃掉,这样就产生了大量的空洞。

  • https://bugs.mysql.com/bug.php?id=88891
  • https://bugs.mysql.com/bug.php?id=91086

    When ever a statement is getting filtered out due the filter         rule, server adds the gtid of the filtered transaction to GTID_EXECUTED_SET         by executing an empty transaction on the slave. So that the same transaction will be replicated again in case of         re connections and also GTID_EXECUTED_SET will not have any GAPS.         But this is *not* happening in case of three statements that are         mentioned in problem description (CREATE/ALTER/DROP DATABASE).         Code has re factored to make sure that an empty transaction         will be executed for these three statements (CREATE/ALTER/DROP DATABASE)         also.