一次MySQL主从同步异常,扒个底朝天都没排查出来……

一、现象
最近项目的测试环境遇到一个主备同步的问题:
备库的同步线程停止了,无法同步主库的数据更改 。
备库报错如下:

一次MySQL主从同步异常,扒个底朝天都没排查出来……

文章插图
从库同步报错信息
完整的错误信息:
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, 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.
上面的报错信息是什么意思呢?
翻译一下就是主库的 binlog 或者从库的 relay log 损坏了,造成这个问题的原因:
  • 可能是网络问题 。
  • 也可能是主库或备库的代码 bug 。
首先我们还是得复习下主从同步的原理才能更好地分析原因 。
二、主从同步的原理
一次MySQL主从同步异常,扒个底朝天都没排查出来……

文章插图
主从同步的原理
  • 从库会生成两个线程,一个 I/O 线程,名字叫做 Slave_IO_Running,另外一个是 SQL 线程,名字叫做 Slave_SQL_Running;
  • 从库的 I/O 线程会去请求主库的 binlog 日志文件,并将得到的 binlog 日志文件写到本地的 relay log (中继日志)文件中;
  • 主库会生成一个 dump 线程,用来给从库 I/O 线程传 binlog;
  • 从库 SQL 线程,会读取 relay log 文件中的日志,并解析成 SQL 语句逐一执行 。
三、排查思路
1、分析从库的同步状态
我们可以打印下从库的同步状态,看到如下几个关键信息:
一次MySQL主从同步异常,扒个底朝天都没排查出来……

文章插图
分析从库的同步状态
  • Master_Log_File:mysql-bin.000956,代表从库读到的主库的 binlog file
  • Read_Master_Log_Pos:528071913,代表从库读到的主库的 binlog file 的日志偏移量
  • Relay_Log_File:relay-bin.000094,代表从库执行到了哪一个 relay log
  • Relay_Log_Pos:123408769,代表从库执行的 relay log file 的日志偏移量
  • Relay_Master_Log_File:mysql-bin.000955,代表从库已经重放到了主库的哪个 binlog file 。
  • Exec_Master_Log_Pos:123408556,代表从库已经重放到了主库 binlog file 的偏移量 。
  • Slave_IO_Running:Yes,说明 I/O 线程正在运行,可以正常获取 binlog 并生成 relay log 。
  • Slave_SQL_Running:No,说明 SQL 线程已经停止运行,不能正常解析 relay log,也就不能执行主库上已经执行的命令 。
  • Master_Log_File 和 Read_Master_Log_Pos 这两个参数合起来表示的是读到的主库的最新位点 。
  • Relay_Master_Log_File 和 Exec_Master_Log_Pos,这两个参数合起来表示的是从库执行的最新位点 。
如果红色框起来的两个参数 Master_Log_File 和 Relay_Master_Log_File 相等,则说明从库读到的最新文件和主库上生成的文件相同,这里前者是 mysql-bin.000956,后者是 mysql-bin.000955,说明两者不相同,存在主从不同步 。
如果蓝色框起来的两个参数 Read_Master_Log_Pos 和 Exec_Master_Log_Pos 相等,则说明从库读到的日志文件的位置和从库上执行日志文件的位置相同,这里不相等,说明主从不同步 。
当上面两组参数都相等时,则说明主从同步正常,且没有延迟 。只要有任意一组不相等,则说明主从不同步,可能是从库停止同步了,或者从库存在同步延迟 。由于上面的 SQL 线程已经停止了,说明是从库同步出现问题了 。
从库同步出现的问题在最开始的报错信息里面已经提到了,可能是网络问题导致,还有可能是 binlog 或 relay log 损坏 。
2、重启万能大法
先通过重启来恢复从库的 SQL 线程试试看?重启方式就是两种:
  • 方式一:从库重新开启同步 。就是执行 stop slave; 和 start slave; 命令 。
  • 方式二:重启从库实例 。就是重启 mysql 实例或 mysql 容器 。
这两种方式试了后,都不能恢复从库的 SQL 线程 。
3、查看 binlog
再来看下 binlog 是否有损坏,在主库上通过这个命令打开 mysql-bin.000955 文件 。
mysqlbinlog /var/lib/mysql/log/mysql-bin.000955
没有报错信息,如下图所示:
一次MySQL主从同步异常,扒个底朝天都没排查出来……

文章插图


推荐阅读