注册 登录
  • 欢迎访问"运维那点事",推荐使用Google浏览器访问,可以扫码关注本站的"微信公众号"。
  • 如果您觉得本站对你有帮助,那么可以扫码捐助以帮助本站更好地发展。

关于MySQL主从复制中server_id的疑问

MySQL 彭东稳 122次浏览 已收录 0个评论

但凡做过MySQL主从复制的同学都知道,MySQL主从复制能够有效工作的一些基本原则,如下:

  • Master必须开启binlog,这是主从复制能够工作的基本要求,slave需要同步Master的binlog进行回放来同步数据。
  • 每个slave都需要设置server_id,且一个集群中所有的server_id不能够被重复。
  • 每个slave只能有一个Master,但每个Master可以有多个Slave(MySQL 5.7开始出现多源复制,就是允许Slave有多个Master)。
  • 如果你设置log_slave_updates参数,某个Slave可以是其它Slave的Master,从而扩散Master的更新,这种复制方式被称为联级复制。

MySQL 5.7之前,前三条可以说是构建一个一主一从复制结构的基础。MySQL 5.7加入多源复制后,自然第三条也就不算什么硬性规定了,所以就变成了前两条是构建一个一主一从复制结构的基本要求。Master需要开启binlog这个自然不用多说,但对于在一个复制集群(指各种复制拓扑)中server_id不能重复这点就有问题可以思考了。曾经面试被问到过,一个复制集群中server_id为什么不能一样?网上找了找资料,大概总结如下。

1. Master与Slave的server_id不能冲突,主要Master要依靠server_id来决定是否执行event。

在双主复制结构中,主库发生数据更新,会将更新记录为含有 server_id_1 的log event事件发送到备库,然后备库更新数据,将含有 server_id_1的 log event 事件发送给主库,因此最初主库上的 log event 更新事件又传了回来,这时候MySQL就要对复制事件的server_id进行判断,发现复制事件的server_id和自己的server_id相同时,放弃执行。如果不同,则执行该 log event 并记录到binlog里面继续发送给备库。 如果该event的server_id和主备的server_id都不相同,该 log event 则在主备库中无限循环执行,也就是通常所说的复制风暴。

主从替换之后的复制风暴

2. 当Master有多个Slave时,那么如何来区分这些Slave呢,就需要用到server_id了。

我们首先看看一个Slave注册到Master会发生什么,首先Slave需要向Master发送一个COM_REGISTER_SLAVE类型的请求(sql_parse.cc)命令请求,这里Master会使用register_slave函数注册一个Slave到slave_list。

在注册Slave线程的时候会发生什么呢(repl_failsafe.cc)?新的Slave一旦注册上去,Master会先删除相同server_id的Slave线程,然后把新的Slave线程注册到slave_list。这就是重连机制,因为有时Slave断开了,重新请求上来,Master当然需要kill原来的线程;slave_list是一个Hash表,server_id是Key,每一个线程注册上来,需要删掉同样server_id的Slave线程,再把新的Slave线程加到slave_list表中。线程注册上来后,请求Binlog,发送COM_BINLOG_DUMP请求,Master会发送binlog给Slave。所以一个MySQL集群中,绝不可以出现相同server_id的实例,否则各种诡异的问题可是接踵而来。

MySQL多个Slave同一server_id的冲突原因分析


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (0)or分享 (0)
关于作者:

您必须 登录 才能发表评论!