注册 登录
  • 欢迎访问"运维那点事",推荐使用Google浏览器访问,可以扫码关注本站的"微信公众号"。
  • 如果您觉得本站对你有帮助,那么可以扫码捐助以帮助本站更好地发展。

MySQL GTID复制异常案例

MySQL FAQ 彭东稳 6125次浏览 已收录 0个评论

昨天处理了一个MySQL 5.6版本下开启GTID模式复制异常案例,MASTER上的任何操作都无法在SLAVE上应用,SLAVE的RELAY LOG里有记录,但SLAVE的BINLOG却找不到蛛丝马迹。由于开启了GTID,所以排查起来也简单,只需要在SLAVE上把RELAY LOG和BINLOG分别解析成文本文件,再直接搜索MASTER的UUID,就能找到SLAVE上是否应用了MASTER复制过来的事务。 排查过程中,曾经一度怀疑是因为设置了BINLOG-DO或者IGNORE规则,或者设置了REPLICATION-DO或IGNORE规则,甚至是GTID的严重BUG,但都没发现端倪。直到从 SHOW SLAVE STATUS 里发现下面这个信息:

从上面的日志发现什么了没?尤其是这两行:

这下有点明白了吧,意思是:

1、SLAVE从MASTER上复制了GTID范围是:1-451;

2、SLAVE上执行GTID的范围分为两段,一段是:1-2455,另一段是:792490-4517929;

尼玛,不应该是连续的嘛,怎么会这么奇葩⊙﹏⊙b,这可如何是好呀,好捉急~~~ 莫急,且容我们慢慢分析为啥GTID从MASTER到SLAVE之后发生了断点,产生了间隙。

正常滴,在MySQL 5.6启用GTID后,部署REPLICATION复制时,可以设定MASTER_AUTO_POSITION = 1,让SLAVE根据GTID自动选择适当的事务点进行复制,DBA基本上无需关注和担心主从不一致的问题,还是很让DBA省心的。 在启用MASTER_AUTO_POSITION = 1的情况下,正常是不会发生GTID中间有个空隙,产生断点的问题发生。除非是下面这种情况:

1、人工暂停SLAVE进程;

2、MASTER上继续写入数据;

3、MASTER上刷新LOG;

4、MASTER上删除旧BINLOG,只保留最新的BINLOG;

5、SLAVE上启动MASTER,这时候会报错,像下面这样:

针对这种问题的处理方法可以这么做:

1、关闭MASTER_AUTO_POSITION,即设置MASTER_AUTO_POSITION = 0;

2、手工CHANGE BINLOG FILE & POS;

这种情况下,不能再次设置MASTER_AUTO_POSITION = 1,否则还会再次报错。 还有一种情况会发生GTID间隙断点问题,例如这样:

1、正常配置REPLICATION复制,但是设置MASTER_AUTO_POSITION = 0,也就是人工指定BINLOG FILE & POS的传统方法;

2、在复制过程中,暂时关闭SLAVE进程;

3、手工修改BINLOG FILE & POS信息,指向新的BINLOG FILE & POS点;

4、启动SLAVE,这时候就会发现GTID断点的现象重现了;

在主从高可用模式下,可能主从间会发生切换,然后再次切换回来,这时候也可能发生上述的断点问题。因此我们建议采用双主来部署高可用切换,基本上可以实现任意来回切换,无需手工指定新的BINLOG FIEE & POS信息。

还有最后一种情况,就是在MASTER上执行了RESET MASTER,导致MASTER上的BINLOG FILE & POS全部重置,SLAVE上读取到的信息自然也就不一致了。

好了,说了那么多,我们最后来说下如何应对处理GTID断点的问题。

方法一:手工修改BINLOG FILE & POS

1、关闭SLAVE;

2、手工CHANGE BINLOG FILE & POS,指向MASTER上最新产生的BINLOG FILE & POS,并且设置 MASTER_AUTO_POSITION = 0;

3、启动SLAVE;

方法二:手工修改GTID_PURGED值

1、关闭SLAVE;

2、在SLAVE上执行RESET MASTER,重设SLAVE上的BINLOG FILE & POS(如果这个节点用于复制中继,要注意所有binlog是否都被读取完毕,避免数据丢失);

3、在SLAVE上执行SET @@GLOBAL.GTID_PURGED = ’35cc99c6-0297-11e4-9916-782bcb2c9453:1-2455′;

4、启动SLAVE;

这种做法比较费解一点,意思是,我们告诉SLAVE要主动抛弃掉MASTER上传输过来的某些区间的事务。在这个例子中,我们抛弃了1-2455这个区间,也就是在GTID从2466开始,又会继续应用RELAY LOG 了,相比我们最开始的那个信息:

我们强制SLAVE只忽略1-2455这个区间,从2466 开始继续复制,消除了本来也会被忽略的区间: 792490-4517929,确保新产生的事务都会被继续应用。这个做法可以参考MySQL手册:Excluding transactions with gtid_purged

还有另外一种费力不讨好的做法,就是在 MASTER 上执行一些没用的空事务,使得 GTID 的序号一直在加大,直到超过 2555 为止,然后在 792490-4517929 这个区间依法炮制一番,但我们非常不推荐采用这种做法,既麻烦又容易误操作。 说了这么多,在 MySQL 5.6及以上版本中,我们强烈建议启用 MASTER_AUTO_POSITION = 1,让 MySQL 自己去做判断,减少一些不必要的问题,并且采用双主(其中一个主设为只读)的方式,方便两个主之间可以随意相互切换,而不必担心数据不一致。


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (2)or分享 (0)
关于作者:

您必须 登录 才能发表评论!