Mysql主从同步中Binlog Dump线程僵尸问题

(by 刘延允)

Mysql主从同步中Binlog Dump线程僵尸问题

问题起因

  • 自己开发程序伪造为mysql的从服务器,不停重连、以及重启后出现如下错误:
    too many connections(1040)

  • 在主服务上运行:show processlist发现大量Binlog Dump线程
    在主服务运行后截图

Mysql主从同步机制

  • 主库上记录二进制日志,也就是binlog日志。

  • 备库将主库的二进制日志复制到其本地的中继日志中。首先,备库会启动一个工作线程,称为I/O线程,I/O线程跟主库建立一个普通的客户端连接,然后在主库上启动一个特殊的二进制转存(Binglog Dump)线程,这个转存线程会读取主库上的二进制日志中事件,并发送给从库的I/O线程;如果主库没有更新信息将进入休眠。

  • 备库的SQL线程执行最后一步,该线程从中继日志中读取事件并在备库执行,从而实现备库数据的更新。

Binlog Dump线程的工作原理

  • MySQL主从同步的实现中,从库连接到主库,并向主库发送一个COM_BINLOG_DUMP命令,主库会启动一个专门的线程为其服务,也就是Binglog Dump线程。该过程和一个用户访问MySQL的过程类似,主库中的Binglog Dump线程和用户线程都是由统一的连接管理机制管理,属于同一个线程池;不同的是Binglog Dump线程会一直存活。

  • Binglog Dump线程按照从库请求的binlog名字和pos找到对应的binlog文件,然后读取binlog的envent不断的发往从库,当主库处于空闲状态时,binlog dump线程会在一个信号量(update_cond即主库的binlog更新状态)上等待。

  • 在主库端一旦有新的日志产生后,立刻会发送一次广播,Binglog Dump线程在收到广播后,则会读取二进制日志并通过网络向备库传输日志,所以这是一个主库向备库不断推送的过程。

Binlog Dump线程的工作缺陷

  • 上面这种机制存在一个问题,由于Binglog Dump线程在等待主库中的update_cond信号量时,不能感知到从库的变化,如果从库这时候死亡,或者执行了stop slave,或者断掉连接重连,则该Binglog Dump线程将一直存活。主库上执行show processlist将会看到上面截图一样的信息。

  • 假如在一个空闲的主库上面不停的重连就将会出现大量的僵尸Binlog Dump线程【我遇到的就是这个情况;Mysql有相应的解决方法下面会说明,但不清楚我遇到没起作用】

Mysql对Binlog Dump线程僵尸解决之道

  • 当主库的binlog中有新的写入时激活所有的Binglog Dump线程,这些线程再次和从库连接时才发现从库已经退出,然后该线程自己也会退出。【实验证明,并不会清理掉所有僵尸线程,还是有残留】

  • 从库向主库发送COM_BINLOG_DUMP命令过程中。会遍历当前的Binglog Dump线程,如果发现连接上来的从库的server-id和既有线程对应的server-id相同,则将既有的那些server-id相同的线程杀死,防止一个从库对应两个Binglog Dump线程。【不知道为什么没起作用???】

转载注明出处:http://blog.csdn.net/gdutliuyun827/article/details/51968869

你可能感兴趣的:(数据库)