您的位置:首页 > 数据库 > > 正文

mysql主从模式与读写分离(磁盘写满导致MySQL复制失败的解决方案)

更多 时间:2021-10-16 00:11:31 类别:数据库 浏览量:893

mysql主从模式与读写分离

磁盘写满导致MySQL复制失败的解决方案

 

案例场景

      今天在线上发现一个问题,由于监控没有覆盖到,某台机器的磁盘被写满了,导致线上MySQL主从复制出现问题。问题如下:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • localhost.(none)>show slave status\G
  • *************************** 1. row ***************************
  •                Slave_IO_State:
  •                   Master_Host: 10.xx.xx.xx
  •                   Master_User: replica
  •                   Master_Port: 5511
  •                 Connect_Retry: 60
  •               Master_Log_File:
  •           Read_Master_Log_Pos: 4
  •                Relay_Log_File: relay-bin.001605
  •                 Relay_Log_Pos: 9489761
  •         Relay_Master_Log_File:
  •              Slave_IO_Running: No
  •             Slave_SQL_Running: No
  •                    Last_Errno: 13121
  •                    Last_Error: Relay log read failure: Could not parse relay log event entry. 
  • The possible reasons are: the master's binary log is corrupted (you can check this by running 
  • 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by
  • running 'mysqlbinlog' on the relay log), a network problem, the server was unable to fetch a
  •  keyring key required to open an encrypted relay log file, or a bug in the master's or 
  • slave's MySQL code. If you want to check the master's binary log or slave's relay log, 
  • you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.
  • 于是查看error log,发现error log中的内容如下:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 2021-03-31T11:34:39.367173+08:00 11 [Warning] [MY-010897] [Repl] Storing MySQL user name or
  • password information in the master info repository is not secure and is therefore not
  • recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; 
  • see the 'START SLAVE Syntax' in the MySQL Manual for more information.
  •  
  • 2021-03-31T11:34:39.368161+08:00 12 [ERROR] [MY-010596] [Repl] Error reading relay log 
  • event for channel '': binlog truncated in the middle of event; consider out of disk space
  •  
  • 2021-03-31T11:34:39.368191+08:00 12 [ERROR] [MY-013121] [Repl] Slave SQL for channel '': Relay 
  • log read failure: Could not parse relay log event entry. The possible reasons are: the master's 
  • binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the 
  • slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log),
  •  a network problem, the server was unable to fetch a keyring key required to open an encrypted
  •  relay log file, or a bug in the master's or slave's MySQL code. If you want to check the 
  • master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW
  •  SLAVE STATUS' on this slave. Error_code: MY-013121
  •  
  • 2021-03-31T11:34:39.368205+08:00 12 [ERROR] [MY-010586] [Repl] Error running query, slave SQL
  •  thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We 
  • stopped at log 'mysql-bin.000446' position 9489626
  • 从描述中可以看到,error log是比较智能的,发现了磁盘问题,并提示我们需要"consider out of disk space"

     

    解决问题

          登录服务器,很快就发现是MySQL所在的服务器磁盘使用率达到100%了,问题原因跟error log中的内容一致。

          现在就解决这个问题。基本的思路就是清理磁盘文件,然后重新搭建复制关系,这个过程似乎比较简单,但是实际操作中,在搭建复制关系的时候出现了下面的报错:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • ### 基于gtid的复制,想重新搭建复制关系
  • localhost.(none)>reset slave;
  • ERROR 1371 (HY000): Failed purging old relay logs: Failed during log reset
  •  
  • localhost.(none)>reset slave all;
  • ERROR 1371 (HY000): Failed purging old relay logs: Failed during log reset
  • 第一步:因为复制是基于gtid进行的,所以直接记录show slave status的状态后,就可以重新reset slave,并利用change master语句来重建复制关系了。

    但是却出现上面的报错,从报错信息看是mysql无法完成purge relay log的操作,这看起来不科学。好吧,既然你自己不能完成purge relay logs的操作,那就让我来帮你吧。

    第二步:手工rm -f 删除所有的relay log,发现报错变成了:

  • ?
  • 1
  • 2
  • localhost.(none)>reset slave all;
  • ERROR 1374 (HY000): I/O error reading log index file
  • 嗯,好吧,问题没有得到解决。

    然后思考了下,既然不能通过手工reset slave 来清理relay log,直接stop

    slave 然后change master行不行呢?

    第三步:直接stop slave,然后change master,不执行reset slave all的语句,结果如下:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • localhost.(none)>change master to master_host='10.13.224.31',
  •     -> master_user='replica',
  •     -> master_password='eHnNCaQE3ND',
  •     -> master_port=5510,
  •     -> master_auto_position=1;
  • ERROR 1371 (HY000): Failed purging old relay logs: Failed during log reset
  • 得,问题依旧。

    第四步:反正复制已经报错断开了,执行个start slave看看,结果戏剧性的一幕出现了:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • localhost.(none)>start slave;
  • ERROR 2006 (HY000): MySQL server has gone away
  • No connection. Trying to reconnect...
  • Connection id:    262
  • Current database: *** NONE ***
  •  
  •  
  • Query OK, 0 rows affected (0.01 sec)
  •  
  •  
  • localhost.(none)>
  • [root@ ~]#
  • 执行start slave之后,实例直接挂了。

    到这里,复制彻底断开了,从库实例已经挂了。

    第五步:看看实例还能不能重启,尝试重启实例,发现实例还能起来。实例重新起来后,查看复制关系,结果如下:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • localhost.(none)>show slave status\G
  • *************************** 1. row ***************************
  •                Slave_IO_State: Queueing master event to the relay log
  •                   Master_Host: 10.xx.xx.xx
  •                   Master_User: replica
  •                   Master_Port: 5511
  •                 Connect_Retry: 60
  •               Master_Log_File: 
  •           Read_Master_Log_Pos: 4
  •                Relay_Log_File: relay-bin.001605
  •                 Relay_Log_Pos: 9489761
  •         Relay_Master_Log_File:
  •              Slave_IO_Running: Yes
  •             Slave_SQL_Running: No
  •                    Last_Errno: 13121
  •                    Last_Error: Relay log read failure: Could not parse relay log event entry.
  •  The possible reasons are: the master's binary log is corrupted (you can check this by running 
  • 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by
  • running 'mysqlbinlog' on the relay log), a network problem, the server was unable to fetch 
  • keyring key required to open an encrypted relay log file, or a bug in the master's or slave'
  • MySQL code. If you want to check the master's binary log or slave's relay log, you will be able 
  • to know their names by issuing 'SHOW SLAVE STATUS' on this slave.
  •                  Skip_Counter: 0
  • 复制关系依旧报错。

    第六步:重新reset slave all看看,结果成功了。

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • localhost.(none)>stop slave;
  • Query OK, 0 rows affected (0.00 sec)
  •  
  •  
  • localhost.(none)>reset slave all;
  • Query OK, 0 rows affected (0.03 sec)
  • 第七步:重新搭建复制关系并启动复制

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • localhost.(none)>change master to master_host='10.xx.xx.xx',
  •     -> master_user='replica',
  •     -> master_password='xxxxx',
  •     -> master_port=5511,
  •     -> master_auto_position=1;
  • Query OK, 0 rows affected, 2 warnings (0.01 sec)
  •  
  •  
  • localhost.(none)>start slave;
  • Query OK, 0 rows affected (0.00 sec)
  •  
  •  
  • localhost.(none)>show slave status\G
  • *************************** 1. row ***************************
  •                Slave_IO_State: Waiting for master to send event
  •                   Master_Host: 10.xx.xx.xx
  •                   Master_User: replica
  •                   Master_Port: 5511
  •                 Connect_Retry: 60
  •                           ...
  •              Slave_IO_Running: Yes
  •             Slave_SQL_Running: Yes
  • 发现实例的复制关系可以建立起来了。

     

    一点总结

        当磁盘写满的情况发生之后,mysql服务无法向元信息表中写数据,relay log也可能已经不完整了,如果直接清理了服务器上的磁盘数据,再去重新change master修改主从复制关系,可能会出现报错,不能直接修复,因为这不是一个正常的主从复制关系断裂场景。

       所以,正确的做法应该是:

    1、清理服务器的磁盘

    2、重启复制关系断开的那个从库

    3、重新reset slave all、change master来搭建主从复制关系即可

       如果有更好的方法,还请不吝赐教。

    以上就是磁盘写满导致MySQL复制失败的解决方案的详细内容,更多关于MySQL复制失败的解决方案的资料请关注开心学习网其它相关文章!

    原文链接:https://mp.weixin.qq.com/s/2BdF-HwKDdH9LsLixXGPcg

    您可能感兴趣