Mysql主从、双主及主从同步1236错误

最近迁机房,Mysql集群换到新环境出现主从不一致的情况,具体为1236报错,集群架构采用的是双主+keepalived高可用,测试了几种恢复的方法,记录一下。

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Slave has more GTIDs than the master has, using the master's SERVER_UUID. This may indicate that the end of the binary log was truncated or that the last binary log file was lost, e.g., after a power or disk failure when sync_binlog != 1. The master may or may not have rolled back transactions that were already replica'
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'could not find next log; the first event '' at 4, the last event read from './slave-bin.000135' at 234, the last byte read from './slave-bin.000135' at 234.'

先回忆下Mysql主从同步:

Mysql主从、双主及主从同步1236错误

主从复制中分为「主服务器(master)「和」从服务器(slave)」「主服务器负责写,而从服务器负责读」MySQL的主从复制的过程是一个「异步的过程」这样读写分离的过程,能够使整体的服务性能大大提升,即使写操作时间比较长,也不影响读操作的进行。

MySQL的主从复制中主要有三个线程:master(binlog dump thread)、slave(I/O thread 、SQL thread,Master一条线程和Slave中的两条线程。

主从复制大致步骤如下:

在从库上执行 change master to,将主库的信息保存到从库中的 master.info 文件中,再执行 start slave,开启 I/O ThreadSQL Thread,主从复制开始

1. I/O Thread 通过 master.info 文件中主库的连接信息去连接主库,连接成功后主库就会开启 Dump Thread

2. Dump Thread 读取主库新产生的二进制日志,然后投递给 I/O Thread

3. I/O Thread 接收 Dump Thread 投递的新的二进制日志,将日志写入到中继日志 relay log 中,I/O Thread 就会等待主库 Dump Thread 主动把新产生的二进制日志投递

4. SQL Thread 会将 relay log 新产生的日志恢复到数据库,写到磁盘

Mysql < 5.7 dump_thread 读binlog与主库写binlog是串行的操作,5.7+ dump_thread读与写binlog是并行的,主从延迟高可以配置并行复制和增强半同步复制

MySQL半同步复制是介于异步和全同步之间,主库只需要等待至少一个从节点,收到并且flush binlog到relay log文件即可。主库不需要等待所有从库给主库反馈,主库只需要收到任意一个从库反馈,而且并不是从库已经完成并提交的反馈,而是从库只用完成io_thread内容即可反馈,无需等到sql_thread的执行完成。

Mysql主从、双主及主从同步1236错误

图片来源

常用命令:

start slave; #开启io_thread和sql_thread

start slave io_thread;

start slave sql_thread;

stop slave; #关闭io_thread和sql_thread

stop slave io_thread;

stop slave sql_thread;

reset slave; #删除master.info,relay-log.info数据;删除所有relay log;将延迟选项master_delay设为0

reset master; #删除所有二进制日志文件

show master status; #查看主库状态

show global variables like '%gtid%';

show binary logs;

show processlist;

show binlog events;

从库状态详解:

show slave status \G; #查看从库状态

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.11.22        #主库IP
                  Master_User: repl                #主库用户
                  Master_Port: 3306                #主库端口号
                Connect_Retry: 60
              Master_Log_File: master-bin.000002   #当前从库io_thread正在读取主库的二进制日志文件
          Read_Master_Log_Pos: 775058446           #当前从库io_thread正在读取主库二进制文件的位置
               Relay_Log_File: relay.000004        #当前从库sql_thread正在读取从库的中继日志文件
                Relay_Log_Pos: 407                 #当前sql_thread正在读取从库中继日志文件的位置
        Relay_Master_Log_File: master-bin.000002   #当前从库sql_thread从relay log中读取的正在进行的sql语句,对应主库的sql语句是在哪个binlog中
             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: 775058446           #从库sql_thread当前执行的事件,对应主库的binlog中的position
              Relay_Log_Space: 691
              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: 0                   #主从复制延迟的时间(s),如果是0表示主从无延迟
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0                   #最后一次IO线程错误信息
                Last_IO_Error: 
               Last_SQL_Errno: 0                   #最后一次SQL线程错误信息
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 2
                  Master_UUID: a67d2e10-b10c-11ed-948f-fa163e521e8a
             Master_Info_File: mysql.slave_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: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: a67d2e10-b10c-11ed-948f-fa163e521e8a:6-11        #当前io_thread已经接受到的binlog
            Executed_Gtid_Set: a66803a8-b10c-11ed-be14-fa163e8dddf7:1-2410271,  #当前从库sql_thread执行的二进制日志位置
a67d2e10-b10c-11ed-948f-fa163e521e8a:6-11
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

主从搭建详见:


双主搭建:

Mysql主从、双主及主从同步1236错误

图片来源

1.双主Master ⇌ Standby,my.cnf配置文件中 server-id 设置要不同,配置上log_slave_updates

2.auto_increment_offset、auto_increment_increment差开,防止两个节点双写时出现主键冲突。

  • auto_increment_offset 自增字段起始值,设置为 2 表示自增字段从 2 开始算

  • auto_increment_increment 自增字段步增数值,设置为 2 表示每次递增 2,根据主节点设置,自增字段的值可能是这样的: 1,3,5,7...

  • log_slave_updates 将复制事件写入 binlog, 一台服务器既做主库又做从库此选项必须要开启, 这里在 Master 和 Standby 开启

从库开启log-bin参数,如果直接往从库写数据,是可以记录log-bin日志的,但是从库通过I0线程读取主库二进制日志文件,然后通过SQL线程写入的数据,是不会记录binlog日志的。也就是说从库从主库上复制的数据,是不写入从库的binlog日志的。所以从库做为其他从库的主库时需要在配置文件中添加log-slave-updates参数。

双主配置参考:

1236报错修复测试结果:

1.standby执行reset slave,master上没有执行reset slave
主从同步不报错,master同步到standby没有问题,standby写入有时不会同步到master,两边数据会有可能造成不一致
stop slave;
CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001',MASTER_LOG_POS=34978,master_auto_position=0;
start slave;

2.standby和master都执行reset slave
master,standby两边写入都能正常同步,两边写入数据没有看到不一致的情况
stop slave;
reset slave;
CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001',MASTER_LOG_POS=126974,master_auto_position=0;
start slave;

3.standby执行reset slave & reset master(这种情况是从库的binlog已经无效了,所以要执行这个命令清空binlog,在从库执行), master 执行reset slave
master,standby两边写入都能正常同步,两边写入数据没有看到不一致的情况

4.standby和master都执行reset slave & reset master,再change master(危险操作,线上慎用可能丢数据)
master,standby两边写入都能正常同步,两边写入数据没有看到不一致的情况

生产建议:

1. 备节点最好动态设置只读(set global read_only = 0|1,主节点 read_only=0,备节点 read_only=1),Keepalived设置为非抢占模式,切换时,备节点要等待主节点同步完成。

2. 迁移时停服务最好是先停Standby,再停Master;启动先启Master,再启Standby。

测试数据:

Master执行:
create database mytest;
use mytest;
CREATE TABLE `test1` (
  `id` int(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `name` varchar(125) NOT NULL,
  `age` int(3) DEFAULT NULL
);

insert into test1 values (0, 'a', 16);
insert into test1 values (0, 'b', 24);
insert into test1 values (0, 'c', 18);

mysql> SHOW TABLES;
+------------------+
| Tables_in_mytest |
+------------------+
| test1            |
+------------------+
1 row in set (0.00 sec)

mysql> insert into test1 values (0, 'a', 16);
Query OK, 1 row affected (0.02 sec)

mysql> insert into test1 values (0, 'b', 24);
Query OK, 1 row affected (0.01 sec)

mysql> insert into test1 values (0, 'c', 18);
Query OK, 1 row affected (0.01 sec)

mysql> select * from test1;
+----+------+------+
| id | name | age  |
+----+------+------+
|  1 | a    |   16 |
|  3 | b    |   24 |
|  5 | c    |   18 |
+----+------+------+
3 rows in set (0.00 sec)

Standby执行:
insert into test1 values (0, 'e', 16);
insert into test1 values (0, 'f', 24);
insert into test1 values (0, 'g', 18);

mysql> select * from test1;
+----+------+------+
| id | name | age  |
+----+------+------+
|  1 | a    |   16 |
|  3 | b    |   24 |
|  5 | c    |   18 |
+----+------+------+
3 rows in set (0.01 sec)


mysql> insert into test1 values (0, 'e', 16);
Query OK, 1 row affected (0.01 sec)

mysql> insert into test1 values (0, 'f', 24);
Query OK, 1 row affected (0.02 sec)

mysql> insert into test1 values (0, 'g', 18);
Query OK, 1 row affected (0.01 sec)

mysql> select * from test1;
+----+------+------+
| id | name | age  |
+----+------+------+
|  1 | a    |   16 |
|  3 | b    |   24 |
|  5 | c    |   18 |
|  6 | e    |   16 |
|  8 | f    |   24 |
| 10 | g    |   18 |
+----+------+------+
6 rows in set (0.00 sec)


参考:

anzhihe 安志合个人博客,版权所有 丨 如未注明,均为原创 丨 转载请注明转自:https://chegva.com/5767.html | ☆★★每天进步一点点,加油!★★☆ | 

您可能还感兴趣的文章!

发表评论

电子邮件地址不会被公开。 必填项已用*标注