企业级运维——Mysql主从复制相关题


https://blog.csdn.net/qq_32534441/article/details/88632609

mysql 主从配置中的server-id的作用

serverid的作用

  • 1、 mysql的同步的数据中是包含server-id的,用于标识该语句最初是从哪个server写入的,所以server-id一定要有的

  • 2、 每一个同步中的slave在master上都对应一个master线程,该线程就是通过slave的server-id来标识的;每个slave在master端最多有一个master线程,如果两个slave的server-id 相同,则后一个连接成功时,前一个将被踢掉。 这里至少有这么一种考虑:

    slave主动连接master之后,如果slave上面执行了slave stop;则连接断开,但是master上对应的线程并没有退出;当slave start之后,master不能再创建一个线程而保留原来的线程,那样同步就可能有问题;

  • 3、 在mysql做多主同步时,多个主需要构成一个环状,但是同步的时候有要保证一条数据不会陷入死循环,这里就是靠server-id来实现的

第一种情况:两个slave有同样的server-id会有什么问题?

第一个问题比较复杂一点,牵涉到master怎么处理server-id相同的slave请求。这里冲突的焦点就是,master怎么区分各个slave的不同之处。

在MySQL中,就是用server id来区分slave的不同的。比如:左边的slave首先连上master,master会分配binlog dump线程并于该slave通讯,发送变更信息;这时,右边的slave连上来,server-id也是2,master以server-id来区别slave,所以它认为是同一个slave连过来,请求另外一个binlog和对应position处开始的数据,于是按照正常逻辑它清理了左边slave的binlog dump线程,并给右边的分配binlog dump线程。左边的slave发现复制断掉以后会自动重连,所以右边的又悲剧了…循环往复,两个slave一直这样相互冲突

在第一个场景下,你会发现两个slave在不断的重连master,日志里面也会有错误信息,说slave被断掉,尝试重连,并且也连上去了。然后又被断掉,又重连…循环往复。

第二种情况:如果是级联复制,再级联复制的路径上有相同的server-id会有什么问题。

第二个场景,最后一个slave不能得到master的变更,在master上做的任何操作都不会应用到最后一个slave上。

第二个问题更加直观,master和第三个slave的server-id是一样的,所以第三个slave发现master产生的binlog,误以为是它自己产生的,就会丢弃掉。这样的话,master产生的binlog在第三个slave就无法应用。

MySQL复制的原理这边就不详细描述。简单的说,就是如果开启了log-bin记录二进制日志,master会在自己的binlog中记录下变更发生的时间,query(如果是Row的话会转成具体的行变更),server-id等信息,然后当slave请求(请求的信息中包括连接master的ip,port等连接信息;以及需要从master的那个二进制文件的哪个位置开始,获得之后的所有master变更)发送到master之后,master启动一个binlog dump的线程用于发送变更信息给该slave。slave通过IO thread接受消息,记录到自己的relay log中,(如果发现server-id等于自己的,它就认为是在本地产生的,直接丢弃),然后SQL thread读取relay log应用到本地MySQL。我们理解了这个,其实上面的两个问题就能够迎刃而解了。

如何实现 MySQL 的读写分离?

就是基于主从复制架构,简单来说,就搞一个主库,挂多个从库,然后我们就单单只是写主库,然后主库会自动把数据给同步到从库上去。

MySQL 主从复制原理的是啥?

主库将变更写入 binlog 日志,然后从库连接到主库之后,从库有一个 IO 线程,将主库的 binlog 日志拷贝到自己本地,写入一个 relay 中继日志中。接着从库中有一个 SQL 线程会从中继日志读取 binlog,然后执行 binlog 日志中的内容,也就是在自己本地再次执行一遍 SQL,这样就可以保证自己跟主库的数据是一样的。

在这里插入图片描述

这里有一个非常重要的一点,就是从库同步主库数据的过程是串行化的,也就是说主库上并行的操作,在从库上会串行执行。所以这就是一个非常重要的点了,由于从库从主库拷贝日志以及串行执行 SQL 的特点,在高并发场景下,从库的数据一定会比主库慢一些,是有延时的。所以经常出现,刚写入主库的数据可能是读不到的,要过几十毫秒,甚至几百毫秒才能读取到。

而且这里还有另外一个问题,就是如果主库突然宕机,然后恰好数据还没同步到从库,那么有些数据可能在从库上是没有的,有些数据可能就丢失了。

所以 MySQL 实际上在这一块有两个机制,一个是半同步复制,用来解决主库数据丢失问题;一个是并行复制,用来解决主从同步延时问题。

这个所谓半同步复制,也叫 semi-sync 复制,指的就是主库写入 binlog 日志之后,就会将强制此时立即将数据同步到从库,从库将日志写入自己本地的 relay log 之后,接着会返回一个 ack 给主库,主库接收到至少一个从库的 ack 之后才会认为写操作完成了。

所谓并行复制,指的是从库开启多个线程,并行读取 relay log 中不同库的日志,然后并行重放不同库的日志,这是库级别的并行。

MySQL 主从同步延时问题(精华)

我们通过 MySQL 命令:

 show status

查看 Seconds_Behind_Master,可以看到从库复制主库的数据落后了几 ms。

一般来说,如果主从延迟较为严重,有以下解决方案:

  • 分库,将一个主库拆分为多个主库,每个主库的写并发就减少了几倍,此时主从延迟可以忽略不计。
  • 打开 MySQL 支持的并行复制,多个库并行复制。如果说某个库的写入并发就是特别高,单库写并发达到了 2000/s,并行复制还是没意义。
  • 重写代码,写代码的同学,要慎重,插入数据时立马查询可能查不到。
    如果确实是存在必须先插入,立马要求就查询到,然后立马就要反过来执行一些操作,对这个查询设置直连主库。不推荐这种方法,你要是这么搞,读写分离的意义就丧失了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值