MySQL主备一致基本原理

在状态1中,客户端的读写都直接访问节点A,而节点B是A的备库,只是将A的更新都同步过来,到本地执行。这样可以保持节点B和A的数据是相同的。当需要切换的时候,就切成状态2。

在状态1中,虽然节点B没有被直接访问,但是依然建议把节点B(备库)设置成只读(readonly)模式,有以下几个考虑:

  1. 有时候一些运营类的查询语句会被放到备库上去查,设置为只读可以防止误操作;

  2. 防止切换逻辑有bug,比如切换过程中出现双写,造成主备不一致;

  3. 可以用readonly状态,来判断节点的角色。

因为readonly设置对超级(super)权限用户是无效的,而用于同步更新的线程,就拥有超级权限,所以可以和主库保持同步更新

2 节点A到B这条线的内部流程

=============================================================================

图2是一个update语句在节点A执行,然后同步到节点B的完整流程图。

在这里插入图片描述

图2 主备流程图(包含binlog和redo log的写入机制相关的内容)

主库接收到客户端的更新请求后,执行内部事务的更新逻辑,同时写binlog。

备库B跟主库A之间维持了一个长连接。主库A内部有一个线程,专门用于服务备库B的这个长连接。

一个事务日志同步的完整过程如下:

  1. 在备库B上通过change master命令,设置主库A的IP、端口、用户名、密码,以及要从哪个位置开始请求binlog,这个位置包含文件名和日志偏移量。

  2. 在备库B上执行start slave命令,这时候备库会启动两个线程,就是图中的io_threadsql_thread。其中io_thread负责与主库建立连接。

  3. 主库A校验完用户名、密码后,开始按照备库B传过来的位置,从本地读取binlog,发给B。

  4. 备库B拿到binlog后,写到本地文件,称为中转日志(relay log)。

  5. sql_thread读取中转日志,解析出日志里的命令,并执行。

3 binlog的三种格式对比

=============================================================================

CREATE TABLE t (

id int(11) NOT NULL,

a int(11) DEFAULT NULL,

t_modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,

PRIMARY KEY (id),

KEY a (a),

KEY t_modified(t_modified)

) ENGINE=InnoDB;

insert into t values(1,1,‘2018-11-13’);

insert into t values(2,2,‘2018-11-12’);

insert into t values(3,3,‘2018-11-11’);

insert into t values(4,4,‘2018-11-10’);

insert into t values(5,5,‘2018-11-09’);

使用下面的语句删除一行数据:

delete from t /comment/ where a>=4 and t_modified<=‘2018-11-10’ limit 1;

3.1 statement


binlog_format=statement时,binlog里面记录的就是SQL语句的原文。

show binlog events in ‘master.000001’;

查看binlog中的内容。

在这里插入图片描述

图3 statement格式binlog 示例

  • 第一行SET @@SESSION.GTID_NEXT='ANONYMOUS'与主备切换有关,先忽略;

  • 第二行是一个BEGIN,跟第四行的commit对应,表示中间是一个事务;

  • 第三行是真实执行的语句。在真实执行的delete命令之前,还有一个use 'test'命令。这条命令是MySQL根据当前要操作的表所在的数据库,自行添加的。这样做可以保证日志传到备库去执行的时候,不论当前的工作线程在哪个库里,都能够正确地更新到test库的表t。

  • use 'test'命令之后的delete 语句,就是SQL原文。binlog甚至连注释也一并记录了。

  • 最后一行是一个COMMIT。xid=61。

在这里插入图片描述

图4 delete执行warnings

运行这条delete命令产生了一个warning,原因是当前binlog设置的是statement格式,并且语句中有limit,所以这个命令可能是unsafe的。

  1. 如果delete语句使用的是索引a,那么会根据索引a找到第一个满足条件的行,也就是a=4这一行;

  2. 如果使用的是索引t_modified,那么删除的就是 t_modified='2018-11-09'也就是a=5这一行。

由于statement格式下,记录到binlog里的是语句原文,因此可能会出现这样一种情况:在主库执行这条SQL语句的时候,用的是索引a;而在备库执行这条SQL语句的时候,却使用了索引t_modified。因此,MySQL认为这样写是有风险的。

3.2 row


binlog_format=‘row’

在这里插入图片描述

图5 row格式binlog 示例

与statement格式的binlog相比,前后的BEGIN和COMMIT是一样的。但row格式的binlog里没有了SQL语句的原文,而是替换成了两个event:

  • Table_map event:用于说明接下来要操作的表是test库的表t;

  • Delete_rows event:用于定义删除这个行为。

可以借助mysqlbinlog工具,用下面这个命令解析和查看binlog中详细内容。因为图5中的信息显示,这个事务的binlog是从8900这个位置开始的,所以可以用start-position参数来指定从这个位置的日志开始解析。

mysqlbinlog -vv data/master.000001 --start-position=8900;

在这里插入图片描述

图6 row格式binlog 示例的详细信息

  • server id 1,表示这个事务是在server_id=1的这个库上执行的。

  • 每个event都有CRC32的值,因为把参数binlog_checksum设置成了CRC32。

  • Table_map event跟在图5中看到的相同,显示了要打开的表,map到数字226。如果要操作多张表的话,每个表都有一个对应的Table_map event、都会map到一个单独的数字,用于区分对不同表的操作。

  • 在mysqlbinlog的命令中,使用了-vv参数是为了把内容都解析出来,所以从结果里面可以看到各个字段的值(比如,@1=4、 @2=4这些值)。

先自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以扫码领取!

img

最后

分享一些系统的面试题,大家可以拿去刷一刷,准备面试涨薪。

这些面试题相对应的技术点:

  • JVM
  • MySQL
  • Mybatis
  • MongoDB
  • Redis
  • Spring
  • Spring boot
  • Spring cloud
  • Kafka
  • RabbitMQ
  • Nginx

大类就是:

  • Java基础
  • 数据结构与算法
  • 并发编程
  • 数据库
  • 设计模式
  • 微服务
  • 消息中间件

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?
pBlYlq-1711404302062)]

[外链图片转存中…(img-LCmJjJsD-1711404302062)]

[外链图片转存中…(img-bUCVbRyH-1711404302063)]

[外链图片转存中…(img-V8RPSePB-1711404302063)]

[外链图片转存中…(img-zfBIYUTn-1711404302063)]

[外链图片转存中…(img-y2Rv6w0t-1711404302063)]

[外链图片转存中…(img-rvDwxYEi-1711404302063)]

[外链图片转存中…(img-2JpOy4S7-1711404302063)]
需要更多Java资料的小伙伴可以帮忙点赞+关注,点击传送门,即可免费领取!

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值