主备同步的数据延迟:
同步的三个时间点:
1)主库 A 执行完成一个事务,主库写入 binlog,把这个时刻记为 T1;
2)传给备库 B,备库接收完这个 binlog 的时刻记为 T2;
3)备库执行完这个事务,这个时刻记为 T3。
主备延迟,就是同一个事务,在备库执行完成的时间和主库执行完成的时间之间的差值,也就是 T3-T1。
1)每个事务的 binlog 里面记录主库上写入的时间;
2)备库取出当前正在执行的事务的时间字段的值,计算它与当前系统时间的差值,得到 seconds_behind_master。
3)在备库上执行 show slave status 命令,显示当前备库延迟了多少秒。
备库连接到主库的时候,会通过执行 SELECT UNIX_TIMESTAMP() 函数来获得当前主库的系统时间。如果发现主库的系统时间与自己不一致,备库在执行 seconds_behind_master 计算的时候会自动扣掉这个差值。
网络正常情况下,主备延迟的主要来源是备库接收完 binlog 和执行完这个事务之间的时间差。主备延迟最直接的表现是,备库消费中转日志(relay log)的速度,比主库生产 binlog 的速度要慢。
主备延迟主要原因:
1,备库机器的性能比主库差,但是目前大都是主备一致的配置
2,备库的压力较大,比如备库上跑了很多运营分析的功能
3,大事务,如果一个主库上的语句执行 10 分钟,执行完传给从库,那这个事务就会导致从库延迟 10 分钟。(所以要尽量避免大事务)
4,备库的并行复制能力
针对第二种情况,建议
1)一主多从,分散从库的压力
2)binlog 输出到外部系统,比如 Hadoop,让外部系统提供统计类查询的能力
可靠性优先策略
双M架构下,主备切换的流程:
1)判断备库 B 现在的 seconds_behind_master,如果小于某个值(比如 5 秒)继续下一步,否则持续重试这一步
2)把主库 A 改成只读状态,即把 readonly 设置为 true;
3)判断备库 B 的 seconds_behind_master 的值,直到这个值变成 0 为止;
4)把备库 B 改成可读写状态,也就是把 readonly 设置为 false;
5)把业务请求切到备库 B。
这个切换流程中是有不可用时间的。在步骤 2 之后,主库 A 和备库 B 都处于 readonly 状态,也就是说这时系统处于不可写状态,直到步骤 5 完成后才能恢复。比较耗费时间的是步骤 3,可能需要耗费好几秒的时间。这也是为什么需要在步骤 1 先做判断,确保 seconds_behind_master 的值足够小。
可用性优先策略
把步骤 4、5 调整到最开始执行,不等主备数据同步,直接把连接切到备库 B,并且让备库 B 可以读写,那么系统几乎就没有不可用时间了。但是可能出现数据不一致的情况。
如果binlog_format=mixed 或者statement的话,或导致切换后备库先执行后一条语句,而原主库同步过来的数据后执行,导致数据不一致。
如果设置 binlog_format=row,row 格式在记录 binlog 的时候,会记录新插入的行的所有字段值,所以最后只会有一行不一致,而且主备过程中执行同步语句执行可能会发生报错,也能及时发现不一致情况。
在满足数据可靠性的前提下,MySQL 高可用系统的可用性,是依赖于主备延迟的。延迟的时间越小,在主库故障的时候,服务恢复需要的时间就越短,可用性就越高。




