京东一面:MySQL 主备延迟有哪些坑?主备切换策略

Posted 微观技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了京东一面:MySQL 主备延迟有哪些坑?主备切换策略相关的知识,希望对你有一定的参考价值。

大家好,我是Tom哥

作为一名开发同学,大家对 mysql 一定不陌生,像常见的 事务特性隔离级别索引等也都是老生常谈。

今天,我们就来聊个深度话题,关于 MySQL 的 高可用

命令

seconds_behind_master,表示当前备库延迟了多少秒

心细的同学会有疑问了, t3 和 t1 分属于两台机器,如果时钟不一致怎么办?

初始化时,备库连接到主库,会执行 SELECT UNIX_TIMESTAMP() 来获得当前主库的系统时间。

如果发现主库的系统时间与备库不一致,备库在计算 seconds_behind_master 会自动减掉这个差值。

注意:

binlog 数据传输的时间(t2 - t1)非常短,可以忽略。主要延迟花费在备库执行binlog日志

是否小于设定的阈值(比如 4 秒),如果满足条件
  • 将 A库 改为只读状态,将 readonly 设置为 true。断掉 A 库的写入操作,保证不会有新的写流量进来
  • 判断 B库的  seconds_behind_master ,直到为 0
  • 修改 B库 为 读、写状态
  • 客户端的请求打到 B库
  • 此时,主备切换完成。

    优点:

    数据不会丢失,所以我们称为可靠性高

    缺点:

    中间有个阶段,A库和B库都是只读状态,此时系统对外不能提供写服务。

    2、可用优先

    当然我们也可以不用等主备数据同步完成,在一开始时就直接将流量切到备库。

    这样备库的流量就可能有两个来源:

  • 主库之前的剩余流量 binlog
  • 客户端新请求进来的流量
  • 两部分流量冲击,会对 数据一致性 造成一些影响。

    我们来做个实验:

    首次创建一个用户表:

    或者 mixed

    按照 SQL 原始语句同步 binlog,可以看到,数据条数不会少,但是主键id会出现混乱。

    3、结论

    本着 "攘外必先安内" ,保证内部的数据的正确性是我们的首选。所以,一般建议大家选择 可靠优先

    但是可靠优先可能会导致一定时间内,数据库不可用。这个时间值取决于主备延迟的时间大小。

    所以,我们应尽可能缩短主备库的延迟时间大小,这样一旦主库发生故障,备库才会更快的同步完数据,主备切换才能完成,服务才能更快恢复。



    目前微信群已开放,想进交流群的小伙伴请添加Tom哥微信,暗号「进群」,唠嗑聊天, 技术交流,围观朋友圈,人生打怪不再寂寞



    推荐阅读

    MySQL 切换有哪些策略

    主备延迟

    怎么在备库查看主备延迟

    在备库执行show slave status, 结果的seconds_behind_master 就是当前备库延迟了多少秒。

    主备延迟的原因

    1. 从库的机器配置比较差
    2. 备库执行了统计类型的SQL,导致压力大
    3. 主库正在执行大事务。如果一个主库上的语句执行 10 分钟,那这个事务很可能就会导致从库延迟 10 分钟。
    4. 大表DDL

    主备切换策略

    由于主备延迟的存在,所以在主备切换的时候,就相应的有不同的策略。

    可靠性优先策略

    可靠性优先策略,可以最大程度的保证数据一致性。关键点是当seconds_behind_master小于某个阈值时,将主库设置为 readonly, 当备库的赶上主库的进度,即seconds_bind_master=0时,将备库改为可读写状态,将业务请求切到备库B。

    可用性优先策略

    指的是,直接将备库设置为可读写然后把业务流量切到备库。但是在这个过程中,可能出现数据不一致的情况。

    比如biinlog 格式为statement,主库写入 c=4, id=4, 然后就进行了主备切换,新主库还没执行c=4, id=4, 就插入c=5的记录,此时结果为c=5 id=4, 然后执行c=4, id=5 的记录。这主要是statement格式没记录主键,插入的记录自己生成了主键。

    如果出现循环复制怎么办

    出现循环复制,一种情况是 A 与 B 是双M结构,然后进行迁移,A与A1 组成双M的过程中,来自B的binlog 在A与A1形成了循环复制,因为binlog的server_id 为 B的,A,A1判断不是自己产生的binlog就会执行,然后传给对方

    在 任意库执行

    stop slave;
    CHANGE MASTER TO IGNORE_SERVER_IDS=(server_id_of_B);
    start slave;
    

    将产生循环赋值的server_id忽略掉

    stop slave;
    CHANGE MASTER TO IGNORE_SERVER_IDS=();
    start slave;
    

    然后再改回来

    以上是关于京东一面:MySQL 主备延迟有哪些坑?主备切换策略的主要内容,如果未能解决你的问题,请参考以下文章

    MySQL 切换有哪些策略

    聊聊MySQL主从延迟

    MySQL实战第二十八讲-读写分离有哪些坑?

    林晓斌MySQL实战第二十八讲-读写分离有哪些坑?

    mysql怎么保证高可用

    Mysql(23)—数据库主从复制的基本原理和步骤