mysql(六)——高可用

主备

  • binlog实现。

主备同步

双M结构

  • 201117.ms1.png
  • 备库设成readonly(对super用户无效,比如同步更新的线程):
    • 取数等放在备库,可以防止误操作。
    • 防止切换过程的bug,造成双写主备不一致。
    • readonly属性可以用来判断节点角色。
  • server id解决循环复制问题。
    • binlog中记录业务操作的mysql的sever id。
    • 每个库收到binlog后,丢弃和自己server id相同的binlog。

同步流程

  • 201117.ms2.png
  • 流程:
    • 备库使用change master,设置主库的参数和开始请求binlog的位置。
    • 备库执行start slave, 启动io_thread建立和主库连接,启动sql_thread读取日志并执行。
    • 主库校验用户,从请求的位置开始读本地binlog,发送给备库。
    • 备库接收binlog之后写本地中转日志relay log
    • sql_thread解析中转日志并执行。
  • 默认异步复制,如果需要保证不丢数据,可使用半同步
    • master commit之后等待一个备库ack,再返回客户端。

并行复制

  • 备库并行回放binlog。
  • 原则
    • 同一行的两个事务分发到一个worker中。防止更新覆盖。
    • 同一个事务分发到一个worker中。防止破坏事务隔离性。
  • mysql 5.6支持按db维度分发。对一个实例一个db的场景无效。
  • MariaDB利用组提交中的事务可并行的特点,备库模拟主库并发度。
    • 能在一组提交的事务(处于commit),一定不会修改同一行,将相同的commit_id计入binlog。
    • 主库可并行执行,备库也可并行执行。相同commit_id的事务可以分发到不同的worker。
  • mysql 5.7 优化mariadb的并发度,同时处于redolog prepare阶段和处于commit阶段的事务备库可以并行。
    • binlog组提交参数增加处于Prepare阶段的事务,提高并发度。

主备延迟

定义

  • 主备同步关键时刻:
    • 主库执行完事务,写binlog,T1.
    • 备库接收到binlog,T2.
    • 备库执行完事务,T3.
  • 主备延迟:主备执行完事务的时间差,即T3-T1.

来源

  • 备库配置低于主库。
  • 备库压力大,承担过多的查询任务,消耗过多cpu。
  • 大事务。比如一次性delete过多,大表DDL。
  • 备库并行复制能力不足。

主备切换

  • 可靠性优先:
    201117.realiable.png
    • 备库seconds_behind_master(sql_thread执行的event的timestamp和io_thread复制好的 event的timestamp差值)较小时,主库改成只读。
    • 等待备库 seconds_behind_master = 0,备库改成可读写。
    • 请求切到备库。
  • 可用性优先。

主从

主备切换逻辑

  • 201119.mbs.png
  • GTID=server_uuid:gno 。
    • gno初始值为1,提交事务时分配给事务并自增,事务回滚不分配。
    • 每个MySQL实例都维护了一个 GTID 集合标识:这个实例执行过的所有事务
  • 新备库在主备切换时使用GTID寻找的和从库的同步位点,从库执行start slave的逻辑:
    • 从库建立和新主库的连接。
    • 从库把自身GTID集合发给新主库。
    • 新主库计算比从库多的GTID
      • 如果这些GTID对应的本地binlog已经删除,异常。
      • 如果全部包含,从第一个多出来的binlog开始顺序发给从库。
  • 指定GTID执行空事务,可以不执行事务但是保存对应GTID的binlog。

过期读处理方案

  • 强制走主库。放弃扩展性。
  • sleep。延迟时间不确定,仍然可能过期读。
  • 判断主备无延迟。根据从库GTID等,判断收到的binlog都执行,但是可能有些binlog还未传输,仍然过期读。
  • 半同步+确认无延迟。一个从库ack binlog之后返回,多从场景仍然可能过期读。
  • 等待位点或GTID。等待从库执行到指定的位点再查询,超时则查主库。
  • 详细

可用性检测

外部检测

  • select 1。连通性检查。
  • mysql> select * from mysql.health_check。检查并发线程数过多的情况。
  • mysql> update mysql.health_check set t_modified=now()。检查磁盘爆满的情况。

随机性、滞后性性。

内部检测

  • performance_schema库file_summary_by_event_name表,统计语句执行时间。
  • 其他检查方法

相关

猜你喜欢

转载自blog.csdn.net/qq_40369829/article/details/110413780
今日推荐