在一个主备关系中,每个备库接受主库的binlog并执行。只要主库执行更新生成的所有binlog,都可以传到备库并被正确的执行,备库就能达到跟主库一致的状态—最终一致性。
主备切换可能是主动运维动作(软件升级、主库所有机器按计划下线),也可能是被动操作(主库所在机器掉电)。
主备延迟
所谓主备延迟就是同一个事务,在备库执行完成的时间和主库执行完成的时间之间的差值。
同步延迟:
- 主库A执行完成一个事务,写入binlog,这个时刻记为T1;
- 传给备库B,把备库B接受完成这个binlog的时刻记为T2;
- 备库B执行完成这个事务,把这个时刻记为T3。主备延迟=T3-T1。
在备库上执行show slave status命令,返回结果中的seconds_behind_master表示当前备库延迟了多少秒。
- 每个事务的binlog里面都有一个时间字段,用于记录主库上写入的时间;
- 备库取出当前正在执行的事务的时间字段的值,计算它与当前系统的差值,得到seconds_behind_master。
备库链接到主库时,通过执行select unix_timestamp()函数来获得当前主库的系统时间。如果发现主库的时间与自己不一致,备库在执行seconds_behind_master计算的时候会自动扣掉这个差值。
SBM不能当做真正的延迟时间。主库没有把日志都发给备库,备库没收到新的binlog时,从库不知道延迟。但主库提交了,从库查不到就算延迟。
网络正常,日志从主库传给备库所需的时间很短,T2-T1的值很小(io_thread),主备延迟的主要来源是备库接收完binlog和执行完这个事务之间的时间差(sql_thread)。最直接表现:备库消费中转日志(relay log)的速度,比主库生产binlog的速度慢。
延迟来源
备库所在机器的性能比主库所在的机器性能差
更新请求对IOPS的压力,在主库和备库上是无差别的。备库主机的性能差,一般将备库设置为“非双1”的模式。
更新过程中触发大量的读操作,备库主机上的多个备库都在争抢中资源时,也可能会导致主备延迟。
解决:
主备可能发生切换,备库随时可能变为主库,主备选用相同规格的机器,并做对称部署。
备库的压力大
主库提供写能力,备库提供读能力,不影响业务的分析语句在备库上跑。备库查询耗费大量的CPU资源,影响同步速度,造成主备延迟。
解决:
- 一主多从。除了备库(可被选成新主库)外,多接几个从库,让从库分担读的压力。(同时从库可以用来做定期全量备份)
- 通过binlog输出到外部系统,如Hadoop,让外部系统提供统计类查询的能力。
大事务
主库必须等事务执行完成才会写入binlog,再传给备库。主库语句执行时间长,就会导致从库延迟。未开并行复制,默认串行导致一个堵全部堵。
一次性的用delete语句删除太多数据
归档类数据,平时没有删除历史数据,等到空间快满了,一次性的删除大量历史数据。
解决:
避免高峰期操作,同时控制每个事务删除的数据量。
大表DDL
解决:
计划内的DDL,建议使用gh-ost方案。
备库的并行复制能力
// todo 待补充
可靠性优先

双M结构下,主备切换过程(可靠性优先):
- 判断备库B现在的seconds_behind_master,如果小于某个值(5秒)继续下一步,否则持续重试这一步;
- 把主库A改成只读状态,readonly=true;
- 判断备库B的seconds_behind_master的值,直到整个值变成0为止;(最耗时的步骤,确保步骤1中SBM值足够小)
- 把备库B改成可读写状态,readonly=false;
- 把业务请求切换到备库B。
步骤2之后,主库A和备库B都处于readonly状态,系统处于不可写状态,直到步骤5完成后才恢复。
主库掉电时,采用可靠性优先,备库只读,且中转日志未完成应用,系统不可用。且主库可能有来不及传的binlog(通过semi-sync解决)
可用性优先
把步骤4、5调整到最开始执行,不等主备数据同步,直接把连接切换到备库B,并且让备库可以读写,系统没有不可用时间。但是可能出现数据不一致的情况。
- row格式,数据不一致更容易被发现。主键自动递增,binlog未同步时,连续两条新增语句被主备分别执行,导致主键冲突。(主库新增,binlog未同步,主备切换,备库新增。binlog互相同步时,由于记录了所有字段,发现主键相同的两条不同记录)
- statement格式,数据悄悄的就不一致了。binlog记录的只是SQL语句,先后执行两次,分别生成两条不同的数据。
使用场景:
- 有一个库的作用是记录操作日志。如果数据不一致可以通过binlog来修补,短暂的不一致不会引发业务问题。
- 业务系统依赖于这个日志写入逻辑,如果这个库不可写,会导致线上的业务操作无法执行。
在满足数据可靠性的前提下,MySQL高可用系统的可用性,是依赖于主备延迟的,延迟时间越小(1s),在主库故障的时候,服务恢复需要的时间就越短,可用性就越高。