• 最终一致性:正常情况下,只要主库执行更新生成的所有 binlog 都可以传到备库并被正确地执行,备库就能达到跟主库一致的状态
  • 从库和备库概念上差不多,把会在「HA」过程中被选成新主库的称为备库
  • HA:高可用(MySQL HA Solution)

主动切换的场景

  1. 主库 A 执行完成一个事务,写入 binlog,我们把这个时刻记为 T1;
  2. 之后传给备库 B,我们把备库 B 接收完这个 binlog 的时刻记为 T2(这一步很快);
  3. 备库 B 执行完成这个事务,我们把这个时刻记为 T3

主备延迟

  • T3 减 T1 的时间
  • 在备库执行 show slave status 命令,返回结果的 seconds_behind_master 表示当前备库延迟了多少秒
    • 1 每个事务的 binlog 都有一个记录主库上写入的时间的时间字段
    • 2 备库取出当前正在执行的事务的时间字段的值,计算与当前「系统时间」的差值
      • 计算完之后手动修改备库时间,不会自动修正
  • 备库在连接到主库的时候会通过 SELECT UNIX_TIMASTAMP() 函数获得当前主库的系统时间
    • 如果主库时间跟自己时间不一样,会在计算时自动扣掉这个差值

延迟原因

  • 备库比主库所在的机器性能差

    • 这种情况可以设置备库非双 1
  • 备库压力大

    • 比如一些不适合在主库跑的大查询放在了备库上,此时压力来到备库
    • 可以多接几个从库分担压力
    • 通过 binlog 输出到外部系统,比如 Hadoop 或 es,让外部系统提供统计类查询的能力
    • 工具可以了解下 canal
  • 大事务

    • 如果一个语句在主库执行了 10 分钟,那在备库上也要执行很久
      • ⚠️ 不要一次性修改、删除太多数据
    • 大表 DDL
      • 计划内的 DDL 建议用 gh-ost 方案
  • 备库的并行复制能力(在下一篇)

主备切换策略

可靠性优先

  1. 判断备库 B 现在的 seconds_behind_master,持续重试,如果小于某个值才进入下一步
  2. 把主库 A 改成只读状态
  3. 判断备库 B 的 seconds_behind_master 的值是否为 0,持续重试
  4. 把备库 B 改成可读写状态
  5. 把业务请求切到备库 B

一般由专门的 HA 系统完成此流程

可用性优先

  • 把 4、5 调整到最开始执行
  • 可能会出现数据不一致
  • 适用场景之一
    • 一个专门负责操作日志的库,数据不一致可以通过 binlog 修补,短暂的不一致也不会引发业务问题同时,业务系统依赖于这个日志写入逻辑,如果这个库不可写,会导致线上的业务操作无法执行

思考题

  • 什么原因导致的?

    • image.png

    • 一种是大事务(包括大表 DDL、一个事务操作很多行);

    • 还有一种情况比较隐蔽,备库起了一个长事务,比如 begin; select * from t limit 1; 然后就不动了

  • 怎么确认?

    • 看一下备库当前执行的命令