返回

为何MySQL中会出现大量小relay log,以及如何解决?

后端

一、案例来源和现象

本文的案例源于朋友@peaceful在生产环境中遇到的实际问题,最终线索也是由他自己找到的。现象如下:

  1. 出现大量非常小的relay log,大约堆积了2600个,如下所示:
000039  0  353407   353760:103318231  pos 3344787704  SQL_THREAD  mysql-bin.000038  3344787704  3344787704  3344787704
000040  0   145954  146100:103318234  pos 3344787704  SQL_THREAD  mysql-bin.000038  3344787704  3344787704  3344787704
  1. 主库错误日志出现如下错误:
[ERROR] Slave: SQL thread: purging relay log './mysql-relay-bin.000039' failed. Error code: 1236. Error message: Got fatal error 1236 from master when reading data from binary log. Slave SQL thread was killed because master semi-synchronous replication was not working. Please fix the reason and retry.

二、问题分析

  1. 产生小relay log的原因

产生大量小relay log的原因是主库开启了半同步复制,而从库的SQL线程在执行relay log时遇到了错误,导致SQL线程被kill掉。

  1. SQL线程被kill掉的原因

SQL线程被kill掉的原因是遇到了错误1236,即从库在从主库读取二进制日志数据时发生了致命错误。

  1. 导致错误1236的原因

导致错误1236的原因可能是多种多样的,例如:

  • 主库和从库的版本不兼容
  • 主库和从库的字符集不兼容
  • 从库的执行顺序与主库不一致
  • 从库的SQL线程遇到锁等待超时
  • 从库的磁盘空间不足
  • 从库的内存不足

三、解决方案

  1. 检查主库和从库的版本和字符集是否兼容

如果主库和从库的版本或字符集不兼容,需要升级或修改其中一方的版本或字符集,以确保兼容。

  1. 检查从库的SQL线程是否遇到锁等待超时

如果从库的SQL线程遇到锁等待超时,可以尝试调整从库的innodb_lock_wait_timeout参数,增大其值,以减少锁等待超时发生的概率。

  1. 检查从库的磁盘空间是否不足

如果从库的磁盘空间不足,需要清理或扩充磁盘空间,以确保有足够的空间存储relay log。

  1. 检查从库的内存是否不足

如果从库的内存不足,需要扩充内存,以确保有足够的内存运行SQL线程。

  1. 关闭半同步复制

如果以上方法都无法解决问题,可以尝试关闭半同步复制,以避免SQL线程被kill掉。

四、总结

本文分析了一个MySQL中产生大量小relay log的故障案例,并给出了相应的解决方案。通过这个案例,我们可以了解到MySQL主从复制中可能遇到的问题,以及如何解决这些问题。