前言
本文主要介绍 MySQL 主备延迟,延迟产生的原因和主备切换策略。
主备延迟
主备同步过程中时间点主要有三个:
-
主库A执行完成一个事务,写入binlog,我们把这个时刻记为T1;
-
之后传给备库B,我们把备库B接收完这个binlog的时刻记为T2;
-
备库B执行完成这个事务,我们把这个时刻记为T3。
所谓主备延迟,指的就是同一个事务下,T3-T1 的时间差值。
主备延迟的计算,可以在备库下,通过 show slave status
命令查看,返回的结果中 seconds_behind_master
代表的就是主备延迟,单位是秒。它会等于(备机执行 binlog 时间戳 - binlog 记录的主机执行时间戳)。
一般在网络正常的情况下,备机接收主机发送的 binlog 很快,即 T2-T1 很小,可以忽略不计。主备延迟的主要来自于 T3-T2,这个时间差值代表备机执行中继日志(relay log)的速度比主机产生 binlog 日志的速度慢多少。
此外,你心里可能还会想主备机器系统时间不一致是否会影响主备延迟?
答案是不会的。因为在主备机器连接上之后,备机会获取主机的系统时间,然后和本机系统时间比较,计算出差值,在后面计算的时候都会带上这个差值
产生原因
1. 备机的性能比主机差
目前,这种部署少了,因为考虑到会进行主备切换,所以一般采用对称部署,即主备机采用一样的规格。
2. 备机压力大
主机用来完成写操作,而备机可能用于完成一些读操作,或者后台运营做一些数据分析的工作。备机的压力不比主机小,从而导致备机的同步延迟。
解决方案:
一主多从,多个从机分担查询压力
2、对于数据分析场景,可以将 binlog 同步到外部系统,像 hadoop。
3. 大事务
即便保证主备机压力基本一致,但大事务情况下,主备机都要耗费相近的执行时间,从而导致备机的同步延迟。所以,DBA 往往会叮嘱开发不要执行大事务。就算一定要执行,也要将大事务分割成多个小事务来执行。
4. 大表DDL
大表DDL会占用很多的 CPU 和 IO 资源,很容易造成主备延迟。所以,要比较安全的操作,建议采用 gh-ost 进行。
开发在线上执行 SQL 时一定要注意,不能执行大事务或者大表DDL这种耗时操作,尤其是比较重要的服务,否则会造成主备延迟,影响业务。
主备切换策略
1. 可靠性优先策略
切换步骤:
-
判断备库B现在的seconds_behind_master,如果小于某个值(比如5秒)继续下一步,否则持续重试这一步;
-
把主库A改成只读状态,即把readonly设置为true;
-
判断备库B的seconds_behind_master的值,直到这个值变成0为止;
-
把备库B改成可读写状态,也就是把readonly 设置为false;
-
把业务请求切到备库B。
可靠性优先的缺点在于主备机存在一段时间的不可用状态,不可用的时间长短取决于步骤 3,直到步骤 5 执行完成后才恢复。
2. 可用性优先策略
为了保证可用性优先,会先执行步骤 4、5,使得不可用时间为 0 。但是这可能会造成主备机的数据不一致。
参考
- [1] MySQL是怎么保证高可用的