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

24 | MySQL是怎么保证主备一致的?

MySQL group replication
半同步
多节点
高可用方案
数据恢复
双M结构
M-S结构
mixed
row
statement
思考题
binlog的应用
循环复制问题
主备切换流程
格式
MySQL binlog

该思维导图由 AI 生成,仅供参考

在前面的文章中,我不止一次地和你提到了 binlog,大家知道 binlog 可以用来归档,也可以用来做主备同步,但它的内容是什么样的呢?为什么备库执行了 binlog 就可以跟主库保持一致了呢?今天我就正式地和你介绍一下它。
毫不夸张地说,MySQL 能够成为现下最流行的开源数据库,binlog 功不可没。
在最开始,MySQL 是以容易学习和方便的高可用架构,被开发人员青睐的。而它的几乎所有的高可用架构,都直接依赖于 binlog。虽然这些高可用架构已经呈现出越来越复杂的趋势,但都是从最基本的一主一备演化过来的。
今天这篇文章我主要为你介绍主备的基本原理。理解了背后的设计原理,你也可以从业务开发的角度,来借鉴这些设计思想。

MySQL 主备的基本原理

如图 1 所示就是基本的主备切换流程。
图 1 MySQL 主备切换流程
在状态 1 中,客户端的读写都直接访问节点 A,而节点 B 是 A 的备库,只是将 A 的更新都同步过来,到本地执行。这样可以保持节点 B 和 A 的数据是相同的。
当需要切换的时候,就切成状态 2。这时候客户端读写访问的都是节点 B,而节点 A 是 B 的备库。
在状态 1 中,虽然节点 B 没有被直接访问,但是我依然建议你把节点 B(也就是备库)设置成只读(readonly)模式。这样做,有以下几个考虑:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了MySQL主备同步的基本原理和技术细节,重点围绕binlog内容、备库执行binlog与主库保持一致的原理展开。详细解释了主备切换流程、节点间的同步更新流程以及binlog的三种格式的特点和应用场景。此外,还讨论了mixed格式的binlog存在的场景和优势,以及循环复制问题的解决方案。通过本文,读者可以深入了解MySQL主备同步的基本原理和技术细节,以及在业务开发中应用这些设计思想的重要性。文章内容涵盖了MySQL高可用方案的基础知识,对读者进行了全面的技术指导,为后续的系统开发提供了重要背景知识。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《MySQL 实战 45 讲》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(122)

  • 最新
  • 精选
  • geraltlaush
    置顶
    老师,我想问下双M架构下,主从复制,是不是一方判断自己的数据比对方少就从对方复制,判断依据是什么

    作者回复: 好问题。 一开始创建主备关系的时候, 是由备库指定的。 比如基于位点的主备关系,备库说“我要从binlog文件A的位置P”开始同步, 主库就从这个指定的位置开始往后发。 而主备复制关系搭建完成以后,是主库来决定“要发数据给备库”的。 所以主库有生成新的日志,就会发给备库。

    2019-01-25
    12
    128
  • Sinyo
    置顶
    主库 A 从本地读取 binlog,发给从库 B; 老师,请问这里的本地是指文件系统的 page cache还是disk呢?

    作者回复: 好问题, 是这样的,对于A的线程来说,就是“读文件”, 1. 如果这个文件现在还在 page cache中,那就最好了,直接读走; 2. 如果不在page cache里,就只好去磁盘读 这个行为是文件系统控制的,MySQL只是执行“读文件”这个操作

    2019-01-21
    4
    184
  • Joker
    老师您好,读到您关于binlog的文章之后,我有个疑问。 我之前理解是,mysql 每执行一条事务所产生的binlog准备写到 binlog file时,都会先判断当前文件写入这条binlog之后是否会超过设置的max_binlog_size值。 如果超过,则rotate 自动生成下个binlog flie 来记录这条binlog信息。 那如果 事务所有产生的binlog 大于 max_binlog_size 值呢? 那不是永久地rotate吗? mysql是如何处理的? 谢谢。

    作者回复: 好问题 一个事务的binlog日志不会被拆到两个binlog文件,所以会等到这个事务的日志写完再rotate,所以你会看见超过配置大小上限的binlog 文件

    2019-03-06
    3
    124
  • 观弈道人
    老师你好,问个备份问题,假如周日23点做了备份,周二20点需要恢复数据,那么在用binlog恢复时,如何恰好定位到周日23点的binlog,谢谢。

    作者回复: Mysqlbinlog有个参数—stop-datetime

    2019-01-07
    2
    79
  • 妥妥
    老师,我想问下,如果一张表并没有主键,插入的一条数据和这张表原有的一条数据所有字段都是一样的,然后对插入的这条数据做恢复,会不会把原有的那条数据删除?不知道在没有主键的情况下binlog会不会也记录数据库为其生成的主键id

    作者回复: 好问题, 会删除一条,但确实可能删除到之前的那条。 主要就是因为,没有主键的时候,binlog里面就不会记录主键字段。

    2019-02-28
    10
    62
  • HuaMax
    课后题。如果在同步的过程中修改了server id,那用原server id 生成的log被两个M认为都不是自己的而被循环执行,不知这种情况会不会发生

    作者回复: 是的,会

    2019-01-07
    8
    58
  • 一大只😴
    死循环第二种情况: 双主,log_slave_updates=on,binlog_format=statement 配置文件里写成statement格式,然后两个master都重启 (从row格式改成statement试了几次没有成功,因为binlog中记录格式还是row) 测试: 表t (id ,c,d) 主键id,有一条数据(1,2,1); M1执行 stop slave; update t set c=c+1 ;或 update t set c=c+1 where id=1; set global server_id=new_server_id; start slave; 然后就能看到c的值在不断变大,想停止就把server_id改回原来的就可以了。

    作者回复: 赞

    2019-01-07
    3
    46
  • hua168
    大神,我前些天去面试,面试官问了一题: mysql做主从,一段时间后发现从库在高峰期会发生一两条条数据丢失(不记得是查询行空白还是查询不到了),主从正常,怎么判断? 1.我问他是不是所以从库都是一样,他说不一样 2.我说低峰期重做新的从库观察,查看日志有没有报错?他好像不满意这个答案。 二、他还问主库挂了怎么办? 1. mysql主从+keepalived/heartbeat 有脑裂,还是有前面丢数据问题 2. 用MMM或HMA之类 3.用ZK之类 三、写的压力大怎么办? 我回答,分库,分表 感觉整天他都不怎么满意,果然没让我复试了,我郁闷呀,我就面试运维的,问数据这么详细。😂 大神,能说下我哪里有问题吗?现在我都想不明白😂

    作者回复: 运维现在要求也挺高的 第一个问题其实我也没看懂,“高峰期丢数据”是指主备延迟查不到数据,还是真的丢了,得先问清楚下 不过你回答的第二点不太好,低峰期重做这个大家都知道要这么做,而且只是修复动作,没办法用来定位原因,面试官是要问你分析问题的方法(方向错误) 重搭从库错误日志里面什么都没有的(这个比较可惜,暴露了对字节不够了解,一般不了解的方法在面试的时候是不如不说的) 第二个问题三点都是你回答的吗?那还算回答得可以的,但是不能只讲名词,要找个你熟悉细节的方案展开一下 三方向也是对的 我估计就是第一个问题减分比较厉害

    2019-01-08
    7
    43
  • 三木禾
    老师,双M可能会造成数据不一致的情况么? 比如,A B同时更新同一条数据?

    作者回复: 一般说双M是只AB之间设置为互为主备,不过任何时刻只有一个节点在接受更新的

    2019-03-31
    4
    41
  • 汪炜
    老师,问个问题,希望能被回答: mmysql不是双一设置的时候,破坏了二阶段提交,事务已提交,redo没有及时刷盘,binlog刷盘了,这种情况,mysql是怎么恢复的,这个事务到底算不算提交?

    作者回复: 如果”redo没有及时刷盘,binlog刷盘了”之后瞬间数据库所在主机掉电, 主机重启,MySQL重启以后,这个事务会丢失;这里确实会引起日志和数据不一致, 这个就是我们说要默认设置为双1的原因之一哈

    2019-01-23
    7
    38
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部