mysql主从复制-gtid节点错误解决ing

问题起因

  • 服务器意外关机后,再次开启后,可能是由于从库所需要的binlog日志在主库被purge掉了,从库获取不到所需要的数据就会出错

模拟报错

  • 以下是通过手动模拟出的报错信息
  • 从库先停止slave
    stop slave;
    
  • 主库模拟修改数据
    # 刷新 log日志
    flush logs;
    # 重新插入数据
    insert into kml values('123');
    # 再次刷新log日志
    flush logs;
    # 查看 master信息
    mysql> show master status\G
    *************************** 1. row ***************************
                 File: mysql-bin.000017
             Position: 446
         Binlog_Do_DB: 
     Binlog_Ignore_DB: 
    Executed_Gtid_Set: 8c31376c-36f4-11ec-9bc2-000c291e98fc:1-13
    1 row in set (0.00 sec)
    
    # 设置为最新的binlog日志
    purge binary logs to 'mysql-bin.000017';
  • 从库开启slave
    start slave;
    
    show slave status\G
    # 查看错误信息
    *************************** 1. row ***************************
                   Slave_IO_State: 
                      Master_Host: 192.168.100.200
                      Master_User: repl
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000015
              Read_Master_Log_Pos: 446
                   Relay_Log_File: localhost-relay-bin.000010
                    Relay_Log_Pos: 619
            Relay_Master_Log_File: mysql-bin.000015
                 Slave_IO_Running: No
                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: 446
                  Relay_Log_Space: 877
                  Until_Condition: None
                   Until_Log_File: 
                    Until_Log_Pos: 0
               Master_SSL_Allowed: No
               Master_SSL_CA_File: 
               Master_SSL_CA_Path: 
                  Master_SSL_Cert: 
                Master_SSL_Cipher: 
                   Master_SSL_Key: 
            Seconds_Behind_Master: NULL
    Master_SSL_Verify_Server_Cert: No
                    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.'
                   Last_SQL_Errno: 0
                   Last_SQL_Error: 
      Replicate_Ignore_Server_Ids: 
                 Master_Server_Id: 1
                      Master_UUID: 8c31376c-36f4-11ec-9bc2-000c291e98fc
                 Master_Info_File: /data/mysql/master.info
                        SQL_Delay: 0
              SQL_Remaining_Delay: NULL
          Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
               Master_Retry_Count: 86400
                      Master_Bind: 
          Last_IO_Error_Timestamp: 211029 14:45:44
         Last_SQL_Error_Timestamp: 
                   Master_SSL_Crl: 
               Master_SSL_Crlpath: 
               Retrieved_Gtid_Set: 8c31376c-36f4-11ec-9bc2-000c291e98fc:13
                Executed_Gtid_Set: 8c31376c-36f4-11ec-9bc2-000c291e98fc:1-13
                    Auto_Position: 1
             Replicate_Rewrite_DB: 
                     Channel_Name: 
               Master_TLS_Version: 
    1 row in set (0.00 sec)

解决方法-1

  • 需要根据从库报错来解决,这里是根据报错解决
  • 备份主库数据
    mysqldump -u root -p 数据库名 > db.sql
  • 从库恢复主库数据
    stop slave;
    
    reset master;
    # 删除所有的binglog日志文件,并将日志索引文件清空,重新开始所有新的日志文件。用于第一次进行搭建主从库时,进行主库binlog初始化工作;
    # 这里不执行的话 在恢复从库数据时会报错
    # ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
    mysql -u root -p 数据库名 < db.sql  # 数据库要提前创建好
  • 开启主从复制
    start slave;
    show slave status\G 检查是否正常
    # 一般这样基本就恢复了

解决方法-2

  • 也是要提前备份主库数据
  • 从库删除主从关系重新配置主从
    # 从库
    stop slave;
    reset slave;
    reset slave all;
    reset master;
    # 重新配置主从
    change master to MASTER_HOST='ip',
      MASTER_USER = 'user',
      MASTER_PASSWORD = 'password',
      MASTER_AUTO_POSITION=1;

解决方法-3

  • 如果上面两个方法还是解决不了的话需要判断一下,主库的gtid值和从库的gtid值是相同
    # 表示已经清除的事务
    Retrieved_Gtid_Set: 8c31376c-36f4-11ec-9bc2-000c291e98fc:13 
    # 表示正在执行的事务
    Executed_Gtid_Set: 8c31376c-36f4-11ec-9bc2-000c291e98fc:1-13
  • 判断从库中 Executed_Gtid_Set 的值是否和主库中的值相同,如果不同手动同步一下
  • 主库中(模拟的)
    *************************** 1. row ***************************
                 File: mysql-bin.000017
             Position: 446
         Binlog_Do_DB: 
     Binlog_Ignore_DB: 
    Executed_Gtid_Set:39103a6a-bd73-11e8-9f12-6c92bf623eda:1-20232110,     46843277-bd73-11e8-bb20-6c92bf613734:1-3330121,                                        daabd4c0-041e-11ec-bf92-7cd30ae410bc:1-1241735'
    1 row in set (0.00 sec)
    # 主库中有这些事务正在执行
  • 从库通过 show slave status\G 判断和主库的不相同
    # 从库手动修改
    stop slave;
    reset master;
    reset slave;
    set global gtid_purged='39103a6a-bd73-11e8-9f12-6c92bf623eda:1-20232110,        46843277-bd73-11e8-bb20-6c92bf613734:1-3330121,                                        daabd4c0-041e-11ec-bf92-7cd30ae410bc:1-1241735';
  • 开启同步 查看是否成功
    start slave;
    show slave status\G

参考博客

https://blog.csdn.net/fujiakai/article/details/82700457
https://blog.csdn.net/yabingshi_tech/article/details/104841186
https://blog.csdn.net/yabingshi_tech/article/details/101627914

命令

reset slave;  # 清除 master.info relay-log.info文件
reset slave all; # 删除所有的relay log 创建一个新的relay log 文件
reset master;  # 清理所有的binlog文件,创建一个新的文件,起始值从1开始。GTID环境中,reset master会清理掉gtid_executed的值
set global gtid_purged 

总结一下:

1reset master操作有两个功能,一个是把binary log进行清空,并生成新的编号为000001的binary log

2reset master会清空主库的GTID编号,在搭建主从的时候可以使用,但是要慎用(如果你的二进制日志还有需要的话)。

# 参考博客:https://cloud.tencent.com/developer/article/1533731

master_auto_position = 1 和 master_uto_position = 0的区别

Auto_Position=0,如果开启relay-log自动修复机制,发生crash时根据relay_log_info中记录的已执行的binlog位置从master上重新获取写入relay-log
Auto_Position=1Slave连接Master时,会把Executed_Gtid_Set中的GTIDs发给MasterMaster会跳过Executed_Gtid_Set,把没有执行过的GTIDs发送给Slave。如果Slave上的GTIDs大于Master上的GTIDs,5.7下直接报错,5.6下不会报错(有环境的自行验证,顺便看看relay-log会不会有记录写入)

# 参考博客: https://www.cnblogs.com/Uest/p/9225637.html#section1

本博客所有文章是以学习为目的,如果有不对的地方可以一起交流沟通共同学习 邮箱:1248287831@qq.com!