MySQL 实战 45 讲
林晓斌
网名丁奇,前腾讯云数据库负责人
220459 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
实践篇 (37讲)
特别放送 (1讲)
结课测试 (1讲)
MySQL 实战 45 讲
15
15
1.0x
00:00/00:00
登录|注册

27 | 主库出问题了,从库怎么办?

在前面的第242526篇文章中,我和你介绍了 MySQL 主备复制的基础结构,但这些都是一主一备的结构。
大多数的互联网应用场景都是读多写少,因此你负责的业务,在发展过程中很可能先会遇到读性能的问题。而在数据库层解决读性能问题,就要涉及到接下来两篇文章要讨论的架构:一主多从。
今天这篇文章,我们就先聊聊一主多从的切换正确性。然后,我们在下一篇文章中再聊聊解决一主多从的查询逻辑正确性的方法。
如图 1 所示,就是一个基本的一主多从结构。
图 1 一主多从基本结构
图中,虚线箭头表示的是主备关系,也就是 A 和 A’互为主备, 从库 B、C、D 指向的是主库 A。一主多从的设置,一般用于读写分离,主库负责所有的写入和一部分读,其他的读请求则由从库分担。
今天我们要讨论的就是,在一主多从架构下,主库故障后的主备切换问题。
如图 2 所示,就是主库发生故障,主备切换后的结果。
图 2 一主多从基本结构 -- 主备切换
相比于一主一备的切换流程,一主多从结构在切换完成后,A’会成为新的主库,从库 B、C、D 也要改接到 A’。正是由于多了从库 B、C、D 重新指向的这个过程,所以主备切换的复杂性也相应增加了。
接下来,我们再一起看看一个切换系统会怎么完成一主多从的主备切换过程。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《MySQL 实战 45 讲》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(74)

  • 最新
  • 精选
  • Mr.Strive.Z.H.L
    置顶
    老师您好: 在实际工作中,主从备份似乎是mysql用的最多的高可用方案。 但是个人认为主从备份这个方案的问题实在太多了: 1. binlog数据传输前,主库宕机,导致提交了的事务数据丢失。 2. 一主多从,即使采用半同步,也只能保证binlog至少在两台机器上,没有一个机制能够选出拥有最完整binlog的从库作为新的主库。 3. 主从切换涉及到 人为操作,而不是全自动化的。即使在使用GTID的情况下,也会有binlog被删除,需要重新做从库的情况。 4. 互为主备,如果互为主备的两个实例全部宕机,mysql直接不可用。 mysql应该有更强大更完备的高可用方案(类似于zab协议或者raft协议这种),而在实际环境下,为什么主从备份用得最多呢?

    作者回复: 3 这个应该是可以做到自动化的。 4 这个概率比较小,其实即使是别的三节点的方案,也架不住挂两个实例,所以这个不是MySQL主备的锅。 前面两点提得很对哈。 其实MySQL到现在,还是提供了很多方案可选的。很多是业务权衡的结果。 比如说,异步复制,在主库异常掉电的时候可能会丢数据。 这个大家知道以后,有一些就改成semi-sync了,但是还是有一些就留着异步复制的模式,因为semi-sync有性能影响(一开始35%,现在好点15%左右,看具体环境),而可能这些业务认为丢一两行,可以从应用层日志去补。 就保留了异步复制模式。 最后,为什么主从备份用得最多,我觉得有历史原因。多年前MySQL刚要开始火的时候,大家发现这个主备模式好方便,就都用了。 而基于其他协议的方案,都是后来出现的,并且还是陆陆续续出点bug。 涉及到线上服务,大家使用新方案的热情总是局限在测试环境的多。 semi-sync也是近几年才开始稳定并被一些公司开始作为默认配置。 新技术的推广,在数据库上,确实比其他领域更需要谨慎些,也算是业务决定的吧^_^ 好问题👍 以上仅一家之言哈😆

    8
    63
  • 某、人
    置顶
    1.如果业务允许主从不一致的情况那么可以在主上先show global variables like 'gtid_purged';然后在从上执行set global gtid_purged =' '.指定从库从哪个gtid开始同步,binlog缺失那一部分,数据在从库上会丢失,就会造成主从不一致 2.需要主从数据一致的话,最好还是通过重新搭建从库来做。 3.如果有其它的从库保留有全量的binlog的话,可以把从库指定为保留了全量binlog的从库为主库(级联复制) 4.如果binlog有备份的情况,可以先在从库上应用缺失的binlog,然后在start slave

    作者回复: 非常好👍

    7
    103
  • 七七
    置顶
    看过上篇后想到一个问题: 级联复制A->B->C结构下, 从库C的Seconds_Behind_Master的时间计算问题. 假定当前主库A仅有一个DDL要进行变更,耗时1分钟.那么从库C的SBM值最大应该是多少时间? 是1分钟, 2分钟, 还是3分钟呢 ? 带着疑问看了一下测试从库C的binlog文件中的时间戳,得出结论应该是3分钟. 打破之前认知 🤦‍♀️ . 请老师解惑 , 谢谢 !

    作者回复: 是的,因为算的是:当前执行时间,跟*日志时间*的差距 而这个日志时间,是在A上执行出来的。 好问题,很好的验证过程。

    10
    27
  • 张永志
    今天问题回答: GTID主从同步设置时,主库A发现需同步的GTID日志有删掉的,那么A就会报错。 解决办法: 从库B在启动同步前需要设置 gtid_purged,指定GTID同步的起点,使用备份搭建从库时需要这样设置。 如果在从库上执行了单独的操作,导致主库上缺少GTID,那么可以在主库上模拟一个与从库B上GTID一样的空事务,这样主从同步就不会报错了。

    作者回复: 你已经理解GTID的机制啦👍

    6
    37
  • Mr.Strive.Z.H.L
    老师您好: 之前讲过 互为主备 的场景下,会出现循环复制的问题,今天这节讲了GTID。 如果使用GTID,那么 循环复制 的问题自然而然就解决了呀??!!

    作者回复: 哈哈,you got it

    34
  • mgxian
    老师我有一个问题 如果数据库已经有完成了很多事务 实例 A’的 GTID集合和 实例 B的 GTID集合 是不是很大,这个GTID是从binglog里一点一点的解析出来所有的事务的吗?这样是不是会很慢 ?在所有binlog里定位某个GTID是不是效率也很低

    作者回复: 好问题,👍 在binlog文件开头,有一个Previous_gtids, 用于记录 “生成这个binlog的时候,实例的Executed_gtid_set”, 所以启动的时候只需要解析最后一个文件; 同样的,由于有这个Previous_gtids,可以快速地定位GTID在哪个文件里。

    22
  • Lukia
    对于老师之前对其他他同学的回答还有一点疑问需要请教一下: Master A上的binlog时间不是在事物commit之前写binlog的时间吗,那么在从节点C上的SBM最大值不应该是2分钟吗?(按3分钟的答案来说,Master A上执行的1分钟为啥要算进去呢?) 看过上篇后想到一个问题: 级联复制A->B->C结构下, 从库C的Seconds_Behind_Master的时间计算问题. 假定当前主库A仅有一个DDL要进行变更,耗时1分钟.那么从库C的SBM值最大应该是多少时间? 是1分钟, 2分钟, 还是3分钟呢 ? 带着疑问看了一下测试从库C的binlog文件中的时间戳,得出结论应该是3分钟. 打破之前认知 🤦‍♀️ . 请老师解惑 , 谢谢 ! 作者回复: 是的,因为算的是:当前执行时间,跟*日志时间*的差距 而这个日志时间,是在A上执行出来的。 好问题,很好的验证过程。

    作者回复: 嗯,多一跳确实是应该多1分钟,在c的最长延迟时间应该是2分钟

    3
    20
  • 时隐时现
    其实基于gtid复制有个大坑,在主库上千万不要执行reset master,否则从库不会报错,只会跳过gno < current_no的事务,造成一个现象就是主库复制没有中断,但是主库上的数据无法同步到从库。

    作者回复: 是的, 不过reset master这种语句。。就算是基于position的协议,谁在线上主库上执行,也是直接当做删数据论处的了😅

    2
    17
  • fuyu
    seta 和 setb 里的集合大小不会很大?

    作者回复: 大没关系呀,是分段的,比如 server_uuid_of_a:1-1000000,就一个段

    2
    17
  • PengfeiWang
    老师,您好: 文中对于sql_slave_skip_counter=1的理解似乎有偏差,官方文档中的解释是: When you use SET GLOBAL sql_slave_skip_counter to skip events and the result is in the middle of a group, the slave continues to skip events until it reaches the end of the group. Execution then starts with the next event group. 按照官方文档的解释,命令sql_slave_skip_counter=1 应该是跳过一个事务中的1个event,除非这个事务是有单个event组成的,才会跳过一个事务。

    作者回复: 你这个是好问题, 确实只是跳过一个event,不过文档中说了呀 “the slave continues to skip events until it reaches the end of the group. ”, 所以效果上等效于跳过一个事务哦

    11
收起评论
显示
设置
留言
74
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部