MySQL中server_id一致带来的问题



简  介

我们都知道在MySQL搭建复制环境的时候,需要设置每个server的server_id不一致,如果主库与从库的server_id一致,那么复制会失败。但是最近在解决一个客户的问题的时候,遇到一个有意思的现象,客户环境有三台数据库服务器,一主两从,客户的两台从库设置了相同server_id,在排查问题的过程中,查看MySQL错误日志,发现有很多奇怪的信息。 
我们模拟了客户的环境,并进行测试、分析,最终在代码中找到了我们想要的答案。下面就是我们测试、分析、总结的步骤以及内容。

测试步骤


环境介绍

  • 主库 
    IP:192.168.1.130 
    server_id:3656

  • 从库A 
    IP:192.168.1.36 
    server_id:56

  • 从库B 
    IP:192.168.1.57 
    server_id:56


三台主机除server_id之外,其余配置如下:

server_id = 123

[client]

socket = /home/mysql/data/mysqldata5.5/sock/mysql.sock

[mysqld]

#server_id = 365

server_id = 123

port = 3306

skip_name_resolve = 1

binlog_format = ROW

#binlog_format = STATEMENT

basedir = /home/mysql/program/mysql5.5.36

datadir = /home/mysql/data/mysqldata5.5/mydata

socket = /home/mysql/data/mysqldata5.5/sock/mysql.sock

pid-file = /home/mysql/data/mysqldata5.5/sock/mysql.pid

tmpdir = /home/mysql/data/mysqldata5.5/tmpdir

log-error = /home/mysql/data/mysqldata5.5/log/error.log

slow_query_log

slow_query_log_file = /home/mysql/data/mysqldata5.5/slowlog/slow-query.log

log-bin = /home/mysql/data/mysqldata5.5/binlog/mysql-bin

relay-log = /home/mysql/data/mysqldata5.5/relaylog/mysql-relay-bin

innodb_data_home_dir = /home/mysql/data/mysqldata5.5/innodb_ts

innodb_log_group_home_dir = /home/mysql/data/mysqldata5.5/innodb_log

#innodb_undo_directory = /home/mysql/data/mysqldata5.5/undo/

sync_binlog=1

innodb_file_per_table=1

#skip_grant_tables

expire_logs_days = 1

log_slave_updates = ON

#replicate-same-server-id=1

skip_slave_start

#innodb_undo_tablespaces=1


5.5.36版本现象

初始搭建环境之后,查看各主机状态。搭建环境的步骤就省略。


主库(192.168.1.130)

主库通过show processlist语句查看,只有一个dump线程,但是通过多次刷新,可以看到连接的是不同的服务器。可以看到每次通过show processlist语句显示的dump线程的Host字段中,IP:PORT的值是不断在更新的,说明dump线程在不断的重连,才会出现占用不同的端口的现象。 


从库A(192.168.1.36)

通过show slave status\G命令查看复制状态,多次执行可以看到Slave_IO_Running字段显示的内容,出现YES或者Connnecting两种状态。可以看到I/O线程在不断的进行重连。 

并且通过tail -f命令查看error log,可以看到I/O线程一直在尝试重新连接。 

可以看到在错误日志中打印的信息是,I/O线程连接 。


从库B(192.168.1.57)

从库B现象与从库A一致。 


5.6.36版本现象

搭建环境步骤不在赘述。


主库(192.168.1.130)

show processlist查看有两个dump线程,并且多次刷新,发现Host字段中的IP:PORT并没有修改,说明dump线程一直保持连接。 


从库A(192.168.1.36)

tail -f /home/mysql/data/mysqldata5.6/log/error.log查看错误日志,没有不断断开连接 。


从库B(192.168.1.57)

tail -f /home/mysql/data/mysqldata5.6/log/error.log查看错误日志,没有不断断开连接 。


原因分析

http://www.penglixun.com/tech/database/mysql_multi_slave_same_serverid.html这是彭立勋写的关于多个slave使用相同server_id时冲突的原因的一篇文章。按照彭大大的分析,我理解的是,slave的I/O线程连接上主库的时候,主库上会调用register_slave()这个函数,在这个函数中又调用了unregister_slave()函数,会将之前使用相同server_id的线程给注销掉。从而导致从库的I/O线程不断断开重连。 
但是仔细看了一下unregister_slave()函数的代码,并没有发现MySQL是根据server_id来注销dump线程的。并且进一步比较了一下5.5.36和5.6.36版本的代码,并没有发现不同。而从库设置server_id一致导致I/O线程不断重连的现象只在5.5版本中看到,在5.6版本中并没有这个现象,所以导致5.5现象的原因不是在unregister_slave()函数中。 
进一步看了一下彭大大的文章,发现有人在下面评论,说主要是kill_zombie_slave_threads()函数导致的。于是看了一下kill_zombie_slave_threads()函数的逻辑,发现MySQL应该就是在这一步根据server_id将线程kill了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值