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

news2024/9/25 7:21:54

以下内容出自《MySQL 实战 45 讲》 https://time.geekbang.org/column/article/76446

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

MySQL 主备的基本原理

如图所示就是基本的主备切换流程。(M-S结构)

img

节点 A 到 B 这条线的内部流程是什么样的 ?

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

img

备库 B 跟主库 A 之间维持了一个长连接。主库 A 内部有一个线程,专门用于服务备库 B 的这个长连接。一个事务日志同步的完整过程是这样的:

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

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

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

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

5、sql_thread 读取中转日志,解析出日志里的命令,并执行。(后续 sql_thread 演化成为了多个线程)

binlog 的三种格式对比

Statement(Statement-Based Replication,SBR):每一条会修改数据的 SQL 都会记录在 binlog 中。

Row(Row-Based Replication,RBR):不记录 SQL 语句上下文信息,仅保存哪条记录被修改。

Mixed(Mixed-Based Replication,MBR):Statement 和 Row 的混合体。

log_bin = on 时,代表 binlog 开启。

show variables like 'log_bin'

常见 binlog 操作

修改 binglog_format

  • 当前会话生效:set binlog_format = 'MIXED';
  • 全局生效,但 MySQL 重启失效:set global binlog_format = 'MIXED';
  • 一劳永李修改生效:修改 mysql 的配置文件, 在 mysqld 下加配置 binlog_format=MIXED

查看所有 binlog 日志

 show binary logs;
 show master logs;

在这里插入图片描述

查看 master 状态

show master status ;

在这里插入图片描述

刷新 binlog

正常来说,一个 binlog 写满之后,会自动切换到下一个 binlog 开始写,不过我们也可以执行一个 flush logs 命令来手动刷新 binlog,手动刷新 binlog 之后,就会产生一个新的 binlog 日志文件,接下来所有的 binlog 日志都将记录到新的文件中。

image-20230710221713179

重置 binlog

reset master 可以重置 binlog 日志文件,让日志重新从 000001 开始记录,不过如果当前主机有一个或者多个从机在运行,那么该命令就运行不了(因为从机是通过 binlog 来实现数据库同步的,主机把 binlog 清空了,从机会报找不到 binlog 的错误)。

image-20230710221841263

查看 binlog

mysqlbinlog 命令

mysqlbinlog命令使用时报错 unknown variable ‘default-character-set=utf8mb4’ 的解决办法_aben_sky的博客-CSDN博客

image-20230710222206818

show binlog events

image-20230710222426300

show binlog events : 只看第一个 binlog 文件内容

show binlog events in ‘binlog_name’: 查看指定 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');

执行下面的删除语句


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

当 binlog_format = statement

show master status ;
show binlog events in 'binlog.000004';

image-20230710223248845

  • 第一行 SET @@SESSION.GTID_NEXT='ANONYMOUS’你可以先忽略,后面文章我们会在介绍主备切换的时候再提到;
  • 第二行是一个 BEGIN,跟第四行的 commit 对应,表示中间是一个事务;
  • 第三行就是真实执行的语句了。可以看到,在真实执行的 delete 命令之前,还有一个“use ‘test’”命令。这条命令不是我们主动执行的,而是 MySQL 根据当前要操作的表所在的数据库,自行添加的。这样做可以保证日志传到备库去执行的时候,不论当前的工作线程在哪个库里,都能够正确地更新到 test 库的表 t。use 'test’命令之后的 delete 语句,就是我们输入的 SQL 原文了。可以看到,binlog“忠实”地记录了 SQL 命令,甚至连注释也一并记录了。
  • 最后一行是一个 COMMIT。你可以看到里面写着 xid=2791。

XID 是用来联系 bin log 和 redo log 的。比如 redo log 里面有一个事务是 prepare 状态,但是不知道是不是 commit 状态,那就可以用 XID 去 bin log 里面查询该事务到底有没有提交。有提交则是 commit 状态,若没有提交则回滚该事务。

同时,执行命令 show warnings 命令。可能会看到下面的返回;

img

原因:当前 binlog 设置的是 statement 格式,并且语句中有 limit,所以这个命令可能是 unsafe 的。

可能会出现主备数据不一致的情况。

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

当 binlog_foramt = row

image-20230710224050470

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

  • Table_map event,用于说明接下来要操作的表是 test 库的表 t;
  • Delete_rows event,用于定义删除的行为。

用 mysqlbinlog 查看和解析 binlog 的内容,上图中显示,事务是从 2885 这个位置开启的,用 start-position 参数来指定从这个位置的日志开始解析。

image-20230710224427532

  • server id 1,表示这个事务是在 server_id=1 的这个库上执行的。
  • 每个 event 都有 CRC32 的值,参数 binlog_checksum,用于校验 binlog 的完整性。
  • Table_map: test.t mapped to number 162: 显示了接下来要打开的表,map 到数字 162。
  • 参数 binlog_row_image 的默认配置是 FULL, 因此 Delete event 包含了删掉的行的所有字段的值。如果把 binlog_row_image 设置为 MINIMAL,则只会记录必要的信息,在这个例子里,就是只会记录 id=5 这个信息。
  • 最后的 Xid event,用于表示事务被正确地提交了。

当 binlog_format 使用 row 格式的时候,binlog 里面记录了真实删除行的主键 id,这样 binlog 传到备库去的时候,就肯定会删除 id=4 的行,不会有主备删除不同行的问题。

为什么会有 mixed 格式的 binlog?

推论:

  • 有些 statement 格式的 binlog 可能会导致主备不一致,所以要使用 row 格式。
  • row 格式的缺点是,很占空间。比如你用一个 delete 语句删掉 10 万行数据,用 statement 的话就是一个 SQL 语句被记录到 binlog 中,占用几十个字节的空间。但如果用 row 格式的 binlog,就要把这 10 万条记录都写到 binlog 中。这样做,不仅会占用更大的空间,同时写 binlog 也要耗费 IO 资源,影响执行速度。
  • MySQL 就取了个折中方案,也就是有了 mixed 格式的 binlog。mixed 格式的意思是,MySQL 自己会判断这条 SQL 语句是否可能引起主备不一致,如果有可能,就用 row 格式,否则就用 statement 格式。

但是,mixed 格式的 binlog 用的不多,大多数场景中,还是设置为 row,好处就是 恢复数据

循环复制问题

实际生产中,使用比较多的是双 M 结构。

img

节点 A 和 B 之间总是互为主备关系。这样在切换的时候就不用再修改主备关系。

双 M 结构的问题:在节点 A 上更新了一条语句,再把 binlog 发给 B,节点 B 执行后也会生成 binlog,如果节点 A 同时是节点 B 的备库,那么 A B 之间,会不断循环执行,也就是循环复制。

可以用下面的逻辑,来解决两个节点间的循环复制的问题:

  • 规定两个库的 server id 必须不同,如果相同,则它们之间不能设定为主备关系;

  • 一个备库接到 binlog 并在重放的过程中,生成与原 binlog 的 server id 相同的新的 binlog;

  • 每个库在收到从自己的主库发过来的日志后,先判断 server id,如果跟自己的相同,表示这个日志是自己生成的,就直接丢弃这个日志。

按照这个逻辑,如果我们设置了双 M 结构,日志的执行流就会变成这样:

  • 从节点 A 更新的事务,binlog 里面记的都是 A 的 server id;
  • 传到节点 B 执行一次以后,节点 B 生成的 binlog 的 server id 也是 A 的 server id;
  • 再传回给节点 A,A 判断到这个 server id 与自己的相同,就不会再处理这个日志。所以,死循环在这里就断掉了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DEVICENET转ETHERNET/IP网关devicenet怎么读

远创智控YC-EIP-DNT&#xff0c;你听说过吗&#xff1f;这是一款自主研发的ETHERNET/IP从站功能的通讯网关&#xff0c;它能够连接DEVICENET总线和ETHERNET/IP网络&#xff0c;从而解决生产管理系统中协议不同造成的数据交换互通问题。 这款产品在工业自动化领域可谓是一大利…

微调预训练的 NLP 模型

动动发财的小手&#xff0c;点个赞吧&#xff01; 针对任何领域微调预训练 NLP 模型的分步指南 简介 在当今世界&#xff0c;预训练 NLP 模型的可用性极大地简化了使用深度学习技术对文本数据的解释。然而&#xff0c;虽然这些模型在一般任务中表现出色&#xff0c;但它们往往缺…

vue进阶----路由

目录 前端路由的概念与原理 什么是路由 SPA 与前端路由 前端路由 前端路由的工作方式 实现简易的前端路由 vue-router 的基本用法 vue-router vue-router 安装和配置的步骤 声明路由的匹配规则 vue-router 的常见用法 1、路由重定向 2、嵌套路由 3、动态路由匹配 …

Stable Diffusion高阶技能(1)-掌握这些,你也能绘出惊艳画作

开篇 初踏入AI作画的世界,你可能会对如何制造出惊艳的艺术作品而困惑。作为一个前沿技术的探索者,我在这一篇文章中,会和你一同揭秘如何用正确的提示词操控AI的“透视”,将最美的画面展现在你眼前。 技能一、提高图片质量的高阶手法 在数量众多的元素中,我们如何做出最…

Vue组件库Element-常见组件-Form表单

Form表单 Form 表单&#xff1a;由输入框、选择器、单选框、多选框等控件组成&#xff0c;用以收集、检验、提交数据 具体关键代码如下&#xff1a; <template><div><el-row><!-- button 按钮 --><el-button>默认按钮</el-button><e…

DDPM 知识点

Generative Modeling by Estimating Gradients of the Data Distribution | Yang Song Score Matching 系列 (一) Non-normalized 模型估計 | 棒棒生

基于单片机智能饮水机加热系统的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;LCD1602液晶显示当前水温&#xff0c;定时提醒&#xff0c;水量变化DS18B20检测当前水体温度&#xff1b;水位传感器检测当前水位&#xff1b;继电器驱动加热片进行水温加热&#xff1b;定时提醒喝水&#xff0c;蜂鸣器报警&#x…

一键报警终端怎么样

一键报警终端是一种便携式设备&#xff0c;用于紧急情况下的一键求救。通过一键报警终端&#xff0c;用户可以发送紧急求助信号给预设的联系人或报警中心&#xff0c;以便及时获得救援。一键报警终端的主要功能和特点如下&#xff1a;1. 便携式设计&#xff1a;一键报警终端通常…

【Android studio】学号及姓名的输入保存页面

一、设计需求 设计一个页面有两个编辑框&#xff0c;分别输入学号和姓名。有两个按钮&#xff0c;一个是修改按钮&#xff0c;当按下修改按钮&#xff0c;编辑框可以进行编辑&#xff1b;一个是保存按钮&#xff0c;当按下保存按钮&#xff0c;使编辑框显示当前的内容并且编辑…

在线性能分析工具Arthas基于Springboot安装配置使用和Arthas Tunnel安装配置使用

概要 Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断&#xff0c;包括查看方法调用的出入参、异常&#xff0c;监测方法执行耗时&#xff0c;类加…

Python Web开发入门教程(非常详细)

Python是一种非常流行的编程语言&#xff0c;被广泛应用于数据科学、Web开发、人工智能、机器学习等领域。Python语言易学易用&#xff0c;是许多初学者进入编程世界的入门选择。然而&#xff0c;学习Python并不是一件简单的事情&#xff0c;尤其是对于初学者而言。在本文中&am…

深度学习——优化器Optimizer

代码以及详细注释&#xff1a; import torch import torch.utils.data as Data import torch.nn.functional as F import matplotlib.pyplot as plt# torch.manual_seed(1) # reproducible """超参数 """ # 学习率 LR 0.01 # 批大小 BATCH_…

API测试之Postman使用完全指南

前言 Postman是一个可扩展的API开发和测试协同平台工具&#xff0c;可以快速集成到CI/CD管道中。旨在简化测试和开发中的API工作流。 Postman 工具有 Chrome 扩展和独立客户端&#xff0c;推荐安装独立客户端。 Postman 有个 workspace 的概念&#xff0c;workspace 分 pers…

16、Python读取气象数据的正确姿势

文章目录 一、气象数据格式&#xff08;常用&#xff09;二、单个文件读取1. 常规格式2. CSV格式3. NetCDF格式4. GRIB格式 一、气象数据格式&#xff08;常用&#xff09; 常规格式&#xff08;Plain Text&#xff09;&#xff1a;气象数据可以使用纯文本格式进行存储&#xf…

漏洞复现 || 某友文件上传

免责声明 技术文章仅供参考&#xff0c;任何个人和组织使用网络应当遵守宪法法律&#xff0c;遵守公共秩序&#xff0c;尊重社会公德&#xff0c;不得利用网络从事危害国家安全、荣誉和利益&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此…

HarmonyOS学习路之开发篇—流转(跨端迁移 一)

跨端迁移开发 场景介绍 开发者在应用FA中通过调用流转任务管理服务、分布式任务调度的接口&#xff0c;实现跨端迁移。 1. 设备A上的应用FA向流转任务管理服务注册一个流转回调&#xff1a; Alt1-系统推荐流转&#xff1a;系统感知周边有可用设备后&#xff0c;主动为用户提…

网络版本的计算器

文章目录 1. TCP协议通讯流程2. 应用层2.1 再谈 "协议" 3. 网络版计算器3.1 服务器提供服务3.1.1 提取有效载荷3.1.2 服务器的反序列化3.1.3 计算服务3.1.4 服务器的序列化3.1.5 添加序列化后的长度 3.2 客户端发送请求3.2.1 填充客户端请求3.2.2 客户端进行序列化3.…

为什么我挖不倒sql注入啊!

为什么我挖不倒sql注入啊&#xff01; 背景一句话讲原理小白速挖注入 背景 不知道是不是初学安全的小伙伴都和我一样&#xff0c;刚开始学的时候&#xff0c;诶挺简单啊&#xff01;我咋这么聪明一学就会&#xff0c;靶场轻轻松松过关&#xff0c;到了实战根本挖不出来&#x…

【C++】float / double 与 0 值比较

【C】float / double 与 0 值比较 文章目录 【C】float / double 与 0 值比较1. 概述不同1.1 - float 与 double 实际存储1.2 - C 语言与 C 中不同 2. 比较方法2.1 - C 风格比较2.2 - 使用 limits 函数 3. 参考链接 References 1. 概述不同 当然使用普通的比较没有问题&#xf…

项目管理中,WBS与项目计划有什么区别?

为了成功完成项目并控制成本&#xff0c;我们有必要采取科学的项目管理方法。实现这一目标的工具是项目计划和工作分解结构&#xff08;WBS&#xff09;。 WBS 与项目计划是项目管理中必不可少的工具&#xff0c;但两者有不同的用途。WBS精确描述了项目工作和可交付成果&#…