GTID模式复制异常处理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GTID模式复制异常处理相关的知识,希望对你有一定的参考价值。

GTID模式复制异常处理

GTID区间有中断导致复制异常处理案例

昨天处理了一个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 里发现下面这个信息:

[[email protected]]> show slave status\G

*************************** 1. row **************

               Slave_IO_State: Waiting for master to send event

...              Master_Log_File: mysql-bin.000001

          Read_Master_Log_Pos: 2539

               Relay_Log_File: mysql-relay-bin.000003

                Relay_Log_Pos: 1996

        Relay_Master_Log_File: mysql-bin.000001

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

# 两个线程工作正常

              Replicate_Do_DB:

          Replicate_Ignore_DB:

           Replicate_Do_Table:

       Replicate_Ignore_Table:

      Replicate_Wild_Do_Table:

  Replicate_Wild_Ignore_Table:

#没设置任何规则

                   Last_Errno: 0

                   Last_Error:

                 Skip_Counter: 0

          Exec_Master_Log_Pos: 2539

# 无论binlog file 还是 pos,都和MASTER保持一致,也就是说BINLOG的接收和RELAYR LOG的APPLY都很正常,有条不紊工作着

              Relay_Log_Space: 2778

              Until_Condition: None

               Until_Log_File:

                Until_Log_Pos: 0

...

        Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error:

               Last_SQL_Errno: 0

               Last_SQL_Error:

  Replicate_Ignore_Server_Ids:

# 没设置忽略某些 server-id 上的BINLOG

             Master_Server_Id: 123315

                  Master_UUID: 35cc99c6-0297-11e4-9916-782bcb2c9453

             Master_Info_File: /data/db11_3316/master.info

                    SQL_Delay: 0

# 没有设置复制延迟策略

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

           Master_Retry_Count: 4294967295

                  Master_Bind:

      Last_IO_Error_Timestamp:

     Last_SQL_Error_Timestamp:

               Master_SSL_Crl:

           Master_SSL_Crlpath:

           Retrieved_Gtid_Set: 35cc99c6-0297-11e4-9916-782bcb2c9453:1-451      

            Executed_Gtid_Set: 35cc99c6-0297-11e4-9916-782bcb2c9453:1-2455:792490-4517929                

                Auto_Position: 1


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

           Retrieved_Gtid_Set: 35cc99c6-0297-11e4-9916-782bcb2c9453:1-451      

           Executed_Gtid_Set: 35cc99c6-0297-11e4-9916-782bcb2c9453:1-2455:792490-4517929                

               Auto_Position: 1


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


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,这时候会报错,像下面这样:

Last_IO_Errno: 1236

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: ‘The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.‘


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

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;

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

4、启动 SLAVE;


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

Retrieved_Gtid_Set: 35cc99c6-0297-11e4-9916-782bcb2c9453:1-451            

Executed_Gtid_Set: 35cc99c6-0297-11e4-9916-782bcb2c9453:1-2455:792490-4517929


我们强制 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 自己去做判断,减少一些不必要的问题,并且采用双主(其中一个主设为只读)的方式,方便两个主之间可以随意相互切换,而不必担心数据不一致。


上面过程我采用的MySQL版本:

5.6.17-65.0-rel65.0-log Percona Server with XtraDB (GPL), Release rel65.0, Revision 587


http://mp.weixin.qq.com/s?__biz=MjM5NzAzMTY4NQ==&mid=506446076&idx=4&sn=9679b905e9f474a72c78667c6b3b8c0f&scene=19#wechat_redirect



本文出自 “梁小明的博客” 博客,请务必保留此出处http://7038006.blog.51cto.com/7028006/1894683

以上是关于GTID模式复制异常处理的主要内容,如果未能解决你的问题,请参考以下文章

基于GTID的主从架构异常处理流程

MySQL Replication--复制异常1

GTID复制异常的解决步骤

mysql8.0.17复制搭建及其gtid的1062和1032异常

mysql8.0.17复制搭建及其gtid的1062和1032异常

mysql从传统模式切到GTID模式后启动主从,主从异常报错1236