主从同步及主从延迟

简单的说,主从同步就是通过数据库底层二进制日志的复制来完成的。

1、 什么是二进制日志

二进制日志又称为binlog。当在配置项中开启二进制日志后,数据库会将每次操作(DDLDML)记录在二进制日志中。

mysql-binlog

进入datadir目录我们可以看到mysql-bin.xxxxx格式的文件就是二进制日志。

mysql-binlog

我们可以通过mysqlbinlog命令去查看这些日志中放了些什么东东。

2、 主从同步流程

主从原理

从图中我们我们可以看到,当客户端对主库进行操作的时候,主库会对改变数据库的操作进行记录二进制日志。这个时候从库的I/O线程(Slave_IO_Running)会将主库的二进制日志拉取到本机斌且写入中继日志中去,而从库的另一个SQL线程(Slave_SQL_Running)会将中继日志中的数据拉取出来,解析和执行。这就是一个主从同步的基本流程。

那我们可以将主从同步简单的分为3个步骤:

  1. 主库产生二进制日志
  2. 从库通过IO线程拉取二进制日志并存入中继日志
  3. 从库SQL线层从中继日志中拉取数据,解析并执行

3、 主从延迟

如果将上述三个步骤按照效率来排序的话那么会是这么一个结果: 1 > 2 > 3

为什么会是这个一个顺序呢?

  • 主库产生二进制日志是顺序写,并且有时卸载本地磁盘,所以效率是非常高的。(当然如果是SSD的话会更快)
  • 从库IO线程拉取二进制日志涉及到网络传输,所以效率就要比步骤1稍慢一些。
  • 从库SQL线程涉及到数据的操作,那么效率快慢就要看具体执行的SQL了。

那么问题就来了。因为IO线程SQL线程都是单线程。假设SQL线程执行一个SQL需要10分钟的话,此时SQL线程什么事情就不能做了,后续的SQL操作只能等待这次操作完成后才能继续执行。那么延迟自然而然的产生了。

回过头来,我们又会发现MASTER主库可以多并发写入,而多IO线程SQL线程都是单线程,当网站访问量上升,并发量增大,身为单线程的IO线程SQL线程是很难支撑的住,延迟也会自然而然的产生。

当然还有其他问题也会主从延迟,比如:SLAVE从库执行大型QUERY语句产生了锁等待。等等

虽然说MYSQL5.6.3开始支持多线程复制,事实上是针对每个database开启相应的独立线程。即每个库有一个单独的(sql thread)如果线上业务中,只有一个database或者绝大多数压力集中在个别database的话,多线程并发复制特性就没有意义了。

4、 总结

其实主从延迟是不可避免的,那么只有提升我们自己的危机的意识,码代码的时候时刻考虑着这个问题,才能避免各种BUG,从而避免为公司带来资损。