说下主从复制原理?

#每天一道面试题# 52

主从复制主要有以下流程:

  1. master服务器将数据的改变记录到binlog中;

  2. slave服务器会在一定时间间隔内对master 的binlog进行检查,如果发生改变,则开始一个I/OThread请求读取master中binlog;

  3. 同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒;

大白话就是:

从库会生成两个线程,一个I/O线程,一个SQL线程;

I/O线程会去请求主库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中;

主库会生成一个dump线程,用来给从库I/O线程传binlog;

SQL线程,会读取relay log文件中的日志,并解析成sql语句逐一执行;

主从复制存在数据丢失问题的解决方案:在使用过程中需要开启半同步复制;

主从复制的使用场景主要有以下两种:HA、读写分离。

高可用(HA)架构:

MySQL的高可用由互为主从的MySQL构成,平时只有主库提供服务,备库不提供服务。当主库停止服务时,服务自动切换到备库。

  • MHA管理工具 MHA存在Manager、Node两种节点;Manager节点通过探测Node节点去判断 MySQL运行是否正常,如果发现 Master故障。

  • 就把他的一个Slave提升为Master,然后剩余Slave都挂到新的Master。

  • LVS+Keepalived

    Keepalived可以进行检查心跳和动态漂移;当Master节点出现异常主服务所在keepalived会发出通知,然后slave节点的keepalived通知从节点切换为master。

读写分离架构:

高并发下读写分离会出现数据延迟问题。

解决方案如下:

  • 分库分表;
  • 开启并行复制;
  • 在业务逻辑上避免;

补充资料:

  1. master提交完事务后,写入binlog。
  2. slave连接到master,获取binlog。
  3. master创建dump线程,推送binglog到slave。
  4. slave启动一个IO线程读取同步过来的master的binlog,记录到relay log中继日志中。
  5. slave再开启一个sql线程读取relay log事件并在slave执行,完成同步。
  6. slave记录自己的binglog。

由于mysql默认的复制方式是异步的,主库把日志发送给从库后不关心从库是否已经处理,这样会产生一个问题就是假设主库挂了,从库处理失败了,这时候从库升为主库后,日志就丢失了。由此产生两个概念。

全同步复制

主库写入binlog后强制同步日志到从库,所有的从库都执行完成后才返回给客户端,但是很显然这个方式的话性能会受到严重影响。

半同步复制

和全同步不同的是,半同步复制的逻辑是这样,从库写入日志成功后返回ACK确认给主库,主库收到至少一个从库的确认就认为写操作完成。