Mysql主备一致性保证

news/2024/5/2 23:41:33/文章来源:https://blog.csdn.net/weixin_46935110/article/details/130019924

大家知道 bin log 既可以用来归档,又可以用来做主备同步。有人可能会问,为什么备库执行了 bin log 就可以跟主库保持一致了呢?bin log的内容是什么样的呢?今天我们就来聊聊它。

在最开始,Mysql 是以容易学习和方便的高可用架构,备受开发人员青睐的。而它所有的高可用架构都是依赖于bin log。虽然这些高可用架构日益复杂,但都是从基本的一主一备演化而来的。今天,就来介绍下主备的基本原理,重点是学习这种设计思想。

Mysql主备基本原理

在这里插入图片描述

在状态1中,客户端的读写都是直接访问节点A,节点B是节点A的备库,只是将节点A的更新同步过来,达到与节点A数据同步。当需要切换的时候,就变成了状态2,此时节点A就成了节点B的备库。
在上述状态中,备库虽然没有被直接访问,但建议将其设置为只读(Read only)模式,考虑如下:

  1. 一些运营类的查询语句会放到备库去查,可以防止误操作;
  2. 防止主备切换过程中的双写,造成主备不一致;
  3. 可以判断节点的角色。

因为,Read only模式对Super权限用户是没用的。所以,即使备库设置为只读模式,也能执行同步主库的数据。
接下来我们来看看,节点A到节点B的内部执行的流程是什么样的。
在这里插入图片描述
流程里包含了redo log和bin log的写入流程,忘记的同学可以翻看我之前的文章查看。
备库 B 和主库 A 之间维持着一个长链接。主库 A 中有一个专门的线程,专门服务于备库B的长链接。一个事务日志的同步完整流程如下:

  1. 在备库上执行 change master 命令,设置主库 A 的 IP、端口、用户名、密码,以及要从主库 A 的那个哪个位置开始请求 bin log,这个位置包含 bin log 文件名和偏移量;
  2. 在备库上执行 start slave 命令,这时候备库 B上会启动两个线程,分别是图中的 io_thread 和 sql_thread。其中,io_thread 负责和主库 A建立连接。
  3. 主库 A 校验完用户名、密码后,开始从备库 B 要求的位置,从本地读取 bin log 发送给备库B;
  4. 备库B 拿到 bin log 文件后,写到本地文件,也就是图中的 relay log;
  5. sql_thread 读取 relay log,解析出日志中的命令并执行。

说明,随着多线程复制的引入,sql_thread 被优化为多个线程,这个后面在展开讨论。分析完这个长链接的逻辑,我们接下来看看 bin log 里面有什么,为什么备库拿过去可以直接执行?

bin log 的三种格式对比

在Mysql中,bin log 有三种格式,分别为:statement、row 和 mixed。其中,mixed格式就是前面两种格式的混合。为了方便描述三种格式的区别,我们先创建一张表:

mysql> 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');

如果我们要删除一行数据的话,我们来看看 bin log 是怎么记录的,注意一下语句包含注释,如果你用Mysql 客户端来做这个实现的话,记得加 -c 参数,否则客户端会自动去掉注释:

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

当 binlog_format=statement 的时候,binlog里面记录的就是语句原文。可以用以下命令查看 bin log 的内容:mysql> show binlog events in ‘master.000001’;
statement 格式 bin log 示例
我们来看下bin log 里都有什么:

  • 第一行的 SET @@SESSION.GTID_NEXT='ANONYMOUS’ 可以先忽略,后面我们将主备切换的时候再细说;
  • 第二行的 begin 和第四行的 commit,表示中间是一个事务;
  • 第三行就是真实执行的语句了,可以看到,在实行delete 之前,还有个use ‘test’,这条命令是Mysql 根据当前需要操作的表,自动添加的。这样做,可以保证日志在传到备库执行时候,无论工作线程在哪个库执行,都可以准确的更新到 test 库的表 t。use ‘test’之后就是,就是我们要执行的语句原文了。

为了说明 statement 和 row 格式的区别,我们来看看这条delete 语句的执行效果:
在这里插入图片描述
可以看到,这条delete 命令产生了一条 warning,原因是当前bing log 的格式为statement 并且语句中有 limit,所以这条命令是 unsafe 的。为什么这么说呢?因为delete + limit 可能造成主备数据的不一致。比如,上面这个例子:

  • 如果这条delete 命令走的是索引a,那么会找到满足条件的第一行,也就是说删除的是 a=4 这行数据;
  • 如果走的是索引t_modified,那么删除的就是 t_modified=‘2018-11-09’ ,也就是 a=5 这行数据。

这样的话,因为 bin log 格式是 statement,记录的是原文。在主库上,走的是索引 a,而在传到备库,走的是索引 t_modified ,就造成了数据不一致。因此,Mysql 认为这么写是有风险的。

那既然statement 格式是不安全的,如果我们改成 row 格式呢?在回答这个问题之前,我们先来看看 row 格式的bin log 长什么样吧。
在这里插入图片描述
可以看到,相较于 statement 格式的 bin log,row格式只是在 begin 和 commit 之间的记录有区别,没有原文的sql语句,变成了两个 event:Table_map 和 Delete_rows。说明:

  • Table_map 说明操作的是哪个库的哪个表;
  • Delete_rows 定义删除行为。这里还看不到删除了哪一行,需要借助 mysqlbinlog 工具。

可以用以下命令查看更详细的日志内容。因为上图显示, 这个事务的binlog 是从master.000001文件且字节偏移位置为8900的位置开始的,所以命令如下:

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

在这里插入图片描述
从图中我们可以看到:

  • server id 1 ,表示这个事务是在 server_id=1 的库上执行的;
  • Table_map 和 Delete_rows 两个event 和 statement 一样,显示了接下来要打开的表,map到数字226。这条语句只涉及到了一张表,如果涉及到多张表,每一个表都会有一个对应的Table_map event,都会map到一个单独的数字,用于不同表的区分。
  • -vv 参数是为了看到每个字段的值
  • Xid event 用于表示事务被正确的提交了。

可以看到,row 格式的binlog 记录了真实的被删除的数据记录,这样传到备库执行,删除的一定是相同的行。不会有主备删除不同行的问题。

为什么会有 mixed 格式的binlog

  1. statement 格式的binlog 可能会导致主备不一致;
  2. row 格式的binlog 会记录操作的真实的数据记录,缺点是:占空间 和 占用 IO 资源。假如你要删除10w行记录,用statement 格式的 binlog 就一条语句,但是,row 格式会把这10w 条记录都写到binlog。不仅站空间,写 binlog 还会占用IO 资源,影响执行速度。
  3. 所以,Mysql 就采取了折中的方案:mixed 。 Mysql 会自己判断,当前执行的sql 是否安全,从而选用statement 还是 row 格式的binlog。

Row 格式binlog的优势

用于恢复数据。insert、delete、update 都很容易恢复。逆操作即可。

双M架构的循环复制问题

文章开始,我们学习了M-S架构,用的多的还是双M架构。
在这里插入图片描述

双 M 结构和 M-S 结构,其实区别只是多了一条线,即:节点 A 和 B 之间总是互为主备关系。这样在切换的时候就不用再修改主备关系。

业务逻辑在节点A上执行了一条更新,然后把生成的binlog 发到节点B 执行,节点B 执行完又会生成binlog。思考:如果节点A也是节点B的备库,节点B生成的binlog 又会传到节点A 再次执行,这样形成循环复制。怎么解决呢?

  1. 规定两个库的 server_id 必须不同,如果相同不能设定为主备关系;
  2. 一个备库在收到binlog 并重放的过程中,生成与原binlog 的 server_id 相同的 binlog;
  3. 每个库在收到来的binlog后,先判断跟自己的server_id不相同才执行,如果相同,表明是自己生成的binlog,直接丢弃。

笔记参考于极客时间《MySQL实战45讲》

推荐一个零声学院免费教程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_283283.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JDK1.8下载与安装完整教程

目录 一、获取安装资源 1、百度网盘共享 2、官方网站下载(百度网盘文件下载下来有问题情况下) 2.1、搜索jdk官方网站 2.2、进到官网下拉找到Java8&#xff0c;选择Windows 2.3、下载安装程序(下载要登录&#xff0c;没有账号就注册就行) 二、正式安装 1、先在D盘(不在C…

【模型复现】Network in Network,将1*1卷积引入网络设计,运用全局平均池化替代全连接层。模块化设计网络

《Network In Network》是一篇比较老的文章了&#xff08;2014年ICLR的一篇paper&#xff09;&#xff0c;是当时比较厉害的一篇论文&#xff0c;同时在现在看来也是一篇非常经典并且影响深远的论文&#xff0c;后续很多创新都有这篇文章的影子。[1312.4400] Network In Networ…

蓝桥杯刷题冲刺 | 倒计时1天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;蓝桥杯加油&#xff0c;大家一定可以&#x1f43e; 文章目录我是菜菜&#xff0c;最近容易我犯的错误总结 一些tips 各位蓝桥杯加油加油 当输入输出数据不超过 1e6 时&#xff0c;scanf printf 和…

elasticsearch基础6——head插件安装和web页面查询操作使用、ik分词器

文章目录一、基本了解1.1 插件分类1.2 插件管理命令二、分析插件2.1 es中的分析插件2.1.1 官方核心分析插件2.1.2 社区提供分析插件2.2 API扩展插件三、Head 插件3.1 安装3.2 web页面使用3.2.1 概览页3.2.1.1 unassigned问题解决3.2.2 索引页3.2.3 数据浏览页3.2.4 基本查询页3…

微服务+springcloud+springcloud alibaba学习笔记(1/9)

1.微服务简介 什么是微服务呢&#xff1f; 就是将一个大的应用&#xff0c;拆分成多个小的模块&#xff0c;每个模块都有自己的功能和职责&#xff0c;每个模块可以 进行交互&#xff0c;这就是微服务 简而言之&#xff0c;微服务架构的风格&#xff0c;就是将单一程序开发成…

项目管理案例分析有哪些?

项目管控中遇到的问题有哪些&#xff1f;这些问题是如何解决的&#xff1f; 在项目管理领域&#xff0c;案例分析是一种常见的方法来学习和理解项目管理实践&#xff0c;下面就来介绍几个成功案例&#xff0c;希望能给大家带来一些参考。 1、第六空间&#xff1a;快速响应个性…

1669_MIT 6.828 xv6代码的获取以及编译启动

全部学习汇总&#xff1a; GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 6.828的学习的资料从开始基本信息的讲解&#xff0c;逐步往unix的一个特殊版本xv6过度了。这样&#xff0c;先得熟悉一下这个OS的基本代码以及环境。 在课程中其实…

最短路径算法及Python实现

最短路径问题 在图论中&#xff0c;最短路径问题是指在一个有向或无向的加权图中找到从一个起点到一个终点的最短路径。这个问题是计算机科学中的一个经典问题&#xff0c;也是许多实际问题的基础&#xff0c;例如路线规划、通信网络设计和交通流量优化等。在这个问题中&#…

Downloader工具配置参数并烧录到flash中

1 Downloader工具介绍 Downloader工具可以用来烧录固件到设备中&#xff0c;固件格式默认为*dcf。该工具还可以用来在线调试EQ或者进行系统设置。 2 配置参数 2.1 作用 当有一个dcf文件时&#xff0c;配合不同的配置文件*.setting&#xff0c;在不进行编译的情况下&#xff…

【毕业设计】ESP32通过MQTT协议连接服务器(二)

文章目录0 前期教程1 前言2 配置SSL证书3 配置用户名和密码4 配置客户端id&#xff08;client_id&#xff09;5 conf文件理解6 websocket配置7 其他资料0 前期教程 【毕业设计】ESP32通过MQTT协议连接服务器&#xff08;一&#xff09; 1 前言 上一篇教程简单讲述了怎么在虚拟…

【调试】ftrace(三)trace-cmd和kernelshark

之前使用ftrace的时候需要一系列的配置&#xff0c;使用起来有点繁琐&#xff0c;这里推荐一个ftrace的一个前端工具&#xff0c;它就是trace-cmd trace-cmd安装教程 安装trace-cmd及其依赖库 git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ c…

【Ruby学习笔记】19.Ruby 连接 Mysql - MySql2

Ruby 连接 Mysql - MySql2 前面一章节我们介绍了 Ruby DBI 的使用。这章节我们技术 Ruby 连接 Mysql 更高效的驱动 mysql2&#xff0c;目前也推荐使用这种方式连接 MySql。 安装 mysql2 驱动&#xff1a; gem install mysql2你需要使用 –with-mysql-config 配置 mysql_conf…

【DevOps】GitOps 初识(下) - 让DevOps变得更好

实践GitOps的五大难题 上一篇文章中&#xff0c;我们介绍了GitOps能为我们带来许多的好处&#xff0c;然而&#xff0c;任何新的探索都将不会是一帆风顺的。在开始之前&#xff0c;如果能了解实践GitOps通常会遇到的挑战&#xff0c;并对此作出合适的应对&#xff0c;可能会使…

数据结构和算法(一):复杂度、数组、链表、栈、队列

从广义上来讲&#xff1a;数据结构就是一组数据的存储结构 &#xff0c; 算法就是操作数据的方法 数据结构是为算法服务的&#xff0c;算法是要作用在特定的数据结构上的。 10个最常用的数据结构&#xff1a;数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie树 10…

StorageManagerService.java中的mVold.mount

android源码&#xff1a;android-11.0.0_r21&#xff08;网址&#xff1a;Search (aospxref.com)&#xff09; 一、问题 2243行mVold.mount执行的是哪个mount函数&#xff1f; 2239 private void mount(VolumeInfo vol) { 2240 try { 2241 // TOD…

【LeetCode】-- 108. 将有序数组转换为二叉搜索树

1. 题目 108. 将有序数组转换为二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 nums &#xff0c;其中元素已经按升序排列&#xff0c;请你将其转换为一棵高度平衡二叉搜索树。高度平衡二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 …

mysql在CentOS7.x环境安装

查看当前环境的yum源 ls -l /etc/yum.repos.d/ 可以看到当前环境是没有下载mysql对应的yum源的, 所以需要去官网下载对应的yum源. 找mysql的yum源并安装 http://repo.mysql.com/ 在选择对应yum源之前, 需要看一下自己系统的版本: 进入官网后, 鼠标右击进入查看页面源代码, 因为…

Leetcode.463 岛屿的周长

题目链接 Leetcode.463 岛屿的周长 easy 题目描述 给定一个 row x col的二维网格地图 grid&#xff0c;其中&#xff1a;grid[i][j] 1表示陆地&#xff0c; grid[i][j] 0表示水域。 网格中的格子 水平和垂直 方向相连&#xff08;对角线方向不相连&#xff09;。整个网格被…

如何从功能测试转型到自动化测试:我三年的学习经历

前言 在软件测试的领域里&#xff0c;自动化测试已经成为了不可或缺的一部分。 与传统的手工测试相比&#xff0c;自动化测试具有更高的效率和精确度&#xff0c;能够有效地减少测试时间和成本&#xff0c;同时提高测试质量。作为一个从事软件测试的人员&#xff0c;如果你想…

Oracle JDK 和 OpenJDK 有什么区别?

可能在看这个问题之前很多人和我一样并没有接触和使用过 OpenJDK 。那么 Oracle JDK 和 OpenJDK 之间是否存在重大差异&#xff1f;下面我通过收集到的一些资料&#xff0c;为你解答这个被很多人忽视的问题。 首先&#xff0c;2006 年 SUN 公司将 Java 开源&#xff0c;也就有…