MySQL主从复制(二):高可用

news2024/10/5 16:22:04

正常情况下, 只要主库执行更新生成的所有binlog, 都可以传到备库并被正确地执行, 备库就能达到跟主库一致的状态, 这就是最终一致性。

但是, MySQL要提供高可用能力, 只有最终一致性是不够的。

双M结构的主备切换流程图如下:

主备延迟


与数据同步有关的时间点主要包括以下三个:

1)主库A执行完成一个事务, 写入binlog, 我们把这个时刻记为T1。

2)之后传给备库B, 我们把备库B接收完这个binlog的时刻记为T2。

3)备库B执行完成这个事务, 我们把这个时刻记为T3。

所谓主备延迟, 就是同一个事务, 在备库执行完成的时间和主库执行完成的时间之间的差值, 也就是T3-T1(这个值的时间精度是秒)。

可以在备库上执行show slave status命令, 它的返回结果里面会显示seconds_behind_master, 用于表示当前备库延迟了多少秒。

seconds_behind_master的计算方法是这样的:

1)每个事务的binlog 里面都有一个时间字段, 用于记录主库上写入的时间。

2)备库取出当前正在执行的事务的时间字段的值, 计算它与当前系统时间的差值, 得到seconds_behind_master。

问:如果主备机器的系统时间设置不一致,会不会导致主备延迟的值不准?

答:不会。因为, 备库连接到主库的时候, 会通过执行SELECTUNIX_TIMESTAMP()函数来获得当前主库的系统时间。 如果这时候发现主库的系统时间与自己不一致, 备库在执行seconds_behind_master计算的时候会自动扣掉这个差值。

注:在网络正常的时候, 日志从主库传给备库所需的时间是很短的, 即T2-T1的值是非常小的。 也就是说, 网络正常情况下, 主备延迟的主要来源是备库接收完binlog和执行完这个事务之间的时间差。

主备延迟的来源


场景一:备库机器性能略差

一般情况下,在部署主从时,都会有这么一个想法:反正备库没有请求, 所以可以用差一点儿的机器。 或者, 他们会把20个主库放在4台机器上, 而把备库集中在一台机器上。而且这种部署一般都会将备库设置为“非双一”的模式。

但实际上,备库更新过程中也会触发大量的读操作。所以,当备库主机上的多个备库都在争抢资源的时候,就可能导致主备延迟了。

当然,这种部署现在出现的比较少了。因为主备可能发生切换,备库随时可能变成主库,所以主备库选用相同规格的机器,并做对称部署,这是现在比较常见的情况。

场景二:备库压力大

问1:即便做了对称部署,还是会有可能出现延迟,为什么?

答:备库压力过大。

一般情况下,主库既然提供了写能力,那么备库可以提供一些读能力或者一些运营后台需要的分析语句,。因为不能影响正常业务, 所以只能在备库上跑。

由于主库直接影响业务, 大家使用起来会比较克制, 反而忽视了备库的压力控制。 结果就是, 备库上的查询耗费了大量的CPU资源, 影响了同步速度, 造成主备延迟。

问2:如何解决备库压力大问题?

1)一主多从。 除了备库外, 可以多接几个从库, 让这些从库来分担读的压力。(常用方式)

2)通过binlog输出到外部系统, 比如Hadoop这类系统, 让外部系统提供统计类查询的能力。

注:备库和从库其实是一个概念,在这里把能够主备切换的称为备库,以和其它从库进行区分。

场景三:大事务

问:采用一主多从,保证备库的压力不会超过主库, 还有什么情况可能导致主备延迟吗?

答:大事务。

因为主库上必须等事务执行完成才会写入binlog, 再传给备库。 所以, 如果一个主库上的语句执行10分钟, 那这个事务很可能就会导致从库延迟10分钟。

这也正是为什么不要一次性地用delete语句删除太多数据,其实这就是一个典型的大事务场景。

比如, 一些归档类的数据, 平时没有注意删除历史数据, 等到空间快满了, 业务开发人员要一次性地删掉大量历史数据。(为了减少大事务导致的主从延迟,需要控制每个事务删除的数据量,分成多次删除)

另一种典型的大事务场景, 就是大表DDL。

场景四:备库的并行复制能力

可靠性优先策略


双M结构的主备切换流程图如下:

主备切换的详细过程如下:

1)判断备库B现在的seconds_behind_master, 如果小于某个值(比如5秒,即保证主从复制在延迟较小的情况下切换) 继续下一步, 否则持续重试这一步。

2)把主库A改成只读状态, 即把readonly设置为true。

3)判断备库B的seconds_behind_master的值, 直到这个值变成0为止。

4)把备库B改成可读写状态, 也就是把readonly设置为false。

5)把业务请求切到备库B。

这个切换流程, 一般是由专门的HA系统来完成的, 我们暂时称之为可靠性优先流程。

可靠性优先主备切换流程:

可以看到, 这个切换流程中是有不可用时间的。 因为在步骤2之后, 主库A和备库B都处于readonly状态, 也就是说这时系统处于不可写状态, 直到步骤5完成后才能恢复。

在这个不可用状态中, 比较耗费时间的是步骤3, 可能需要耗费好几秒的时间。 这也是为什么需要在步骤1先做判断, 确保seconds_behind_master的值足够小。

如果一开始主备延迟就长达30分钟, 而不先做判断直接切换的话, 系统的不可用时间就会长达30分钟, 这种情况一般业务都是不可接受的。

注1: 图中的SBM, 是seconds_behind_master参数的简写。

注2:系统的不可用时间,是由这个数据可靠性优先的策略决定的。可以选择可用性优先策略,来把这个不可用时间几乎降为0。

可用性优先策略


可用性优先策略切换流程:强行把步骤4、 5调整到最开始执行, 也就是说不等主备数据同步, 直接把连接切到备库B, 并且让备库B可以读写, 那么系统几乎就没有不可用时间了。

注:这个切换流程的代价,就是可能出现数据不一致的情况。

下面来看一个可用性优先导致数据不一致的案例,假设有一个表t:

CREATE TABLE `t` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `c` int(11) unsigned DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB;
insert into t(c) values(1),(2),(3);

接下来, 业务人员要继续在表t上执行两条插入语句的命令, 依次是:

insert into t(c) values(4);
insert into t(c) values(5);

假设, 现在主库上其他的数据表有大量的更新, 导致主备延迟达到5秒。 在插入一条c=4的语句后, 发起了主备切换。

下图是可用性优先策略,且binlog_format=mixed时的切换流程和数据结果:

切换流程分析:

1)步骤2中, 主库A执行完insert语句, 插入了一行数据(4,4) , 之后开始进行主备切换。

2)步骤3中, 由于主备之间有5秒的延迟, 所以备库B还没来得及应用“插入c=4”这个中转日志,就开始接收客户端“插入 c=5”的命令。

3)步骤4中, 备库B插入了一行数据(4,5) , 并且把这个binlog发给主库A。

4)步骤5中, 备库B执行“插入c=4”这个中转日志, 插入了一行数据(5,4) 。 而直接在备库B执行的“插入c=5”这个语句, 传到主库A, 就插入了一行新数据(5,5) 。

最后的结果就是, 主库A和备库B上出现了两行不一致的数据。 可以看到, 这个数据不一致, 是由可用性优先流程导致的。

问1:如果还是使用可用性优先策略,但是设置binlog_format=row, 情况又会怎样呢?

因为row格式在记录binlog的时候, 会记录新插入的行的所有字段值, 所以最后只会有一行不一致。 而且, 两边的主备同步的应用线程会报错duplicate keyerror并停止。 也就是说, 这种情况下, 备库B的(5,4)和主库A的(5,5)这两行数据, 都不会被对方执行。

可用性优先策略,row格式binlog主备切换流程:

从上面的分析中, 可以看到一些结论:

1)使用row格式的binlog时, 数据不一致的问题更容易被发现。 而使用mixed或者statement格式的binlog时, 数据很可能悄悄地就不一致了。 如果你过了很久才发现数据不一致的问题,很可能这时的数据不一致已经不可查, 或者连带造成了更多的数据逻辑不一致。

2)由于可用性优先策略会导致数据不一致问题,因此在大多数情况下,都建议使用可靠性优先策略。即数据的可靠性要优于可用性。

问2:按照可靠性优先的思路,异常切换会是什么效果?

假设, 主库A和备库B间的主备延迟是30分钟, 这时候主库A掉电了, HA系统要切换B作为主库。 我们在主动切换的时候, 可以等到主备延迟小于5秒的时候再启动切换, 但这时候已经别无选择了。

而如果直接切换到备库B,由于中转日志还没有应用完成,这时客户端查不到之前主库A执行完的事务,会认为有“数据丢失”。

虽然随着中转日志的继续应用, 这些数据会恢复回来, 但是对于一些业务来说, 查询到“暂时丢失数据的状态”也是不能被接受的。

结论:MySQL高可用系统的可用性,是依赖于主备延迟的。延迟的时间越小,在主库故障的时候,服务恢复需要的时间就越短,可用性就越高。

小结:思考题


一般现在的数据库运维系统都有备库延迟监控, 其实就是在备库上执行 show slave status, 采集seconds_behind_master的值。

思考:假设, 现在你看到你维护的一个备库, 它延迟监控的图像类似下图,是一个45°斜向上的线段,你觉得可能是什么原因导致的?又如何去确认这个原因呢?

答:备库的同步在这段时间完全被堵住了。产生这种现象典型的场景主要包括两种:

1)大事务,包括:大表DDL、一个事务操作很多行。

2)从库在进行备份操作,锁住更新。

3)备库磁盘空间不足,无法写入数据。

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

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

相关文章

2024年甘肃特岗教师招聘报名流程,速速查收哦!

2024年甘肃特岗教师招聘报名流程,速速查收哦!

WXML模板语法-事件绑定

一、 1.事件 事件是渲染层到逻辑层的通讯方式,通过事件可以将用户在渲染层产生的行为,反馈到逻辑层进行业务的处理 2.小程序中常用的事件 3.事件对象的属性列表 当事件回调触发的时候,会收到一个事件对象event,其属性为&#x…

Mysql之基本架构

1.Mysql简介 mysql是一种关系型数据库,由表结构来存储数据与数据之间的关系,同时为sql(结构化查询语句)来进行数据操作。 sql语句进行操作又分为几个重要的操作类型 DQL: Data Query Language 数据查询语句 DML: Data Manipulation Language 添加、删…

axios案例应用

1、Spring概述 Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control: 反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC 和持久层。Spring JDBC 以及业务层事务管理等众多…

C++进阶:C++11(列表初始化、右值引用与移动构造移动赋值、可变参数模版...Args、lambda表达式、function包装器)

C进阶:C11(列表初始化、右值引用与移动构造移动赋值、可变参数模版…Args、lambda表达式、function包装器) 今天接着进行语法方面知识点的讲解 文章目录 1.统一的列表初始化1.1{}初始化1.2 initializer_listpair的补充 2.声明相关关键字2.1a…

STM32——DAC篇(基于f103)

技术笔记! 一、DAC简介(了解) 1.1 DAC概念 传感器信号采集改变电信号,通过ADC转换成单片机可以处理的数字信号,处理后,通过DAC转换成电信号,进而实现对系统的控制。 1.2 DAC的特性参数 1.3…

amis-editor 低代码可视化编辑器开发 和 使用说明

1.amis-editor可视化编辑器 React版本(推荐): GitHub - aisuda/amis-editor-demo: amis 可视化编辑器示例 https://aisuda.github.io/amis-editor-demo 建议使用react版本,好维护,升级版本更新package.json中对应版本…

Property xxx does not exist on type ‘Window typeof globalThis‘ 解决方法

问题现象 出现以上typescript警告,是因为代码使用了window的非标准属性,即原生 window 对象上不存在该属性。 解决办法 在项目 根目录 或者 src目录 下新建 xxx.d.ts 文件,然后进行对该 属性 进行声明即可。 注意:假如xxx.d.ts文…

【vue】封装的天气展示卡片,在线获取天气信息

源码 <template><div class"sen_weather_wrapper"><div class"sen_top_box"><div class"sen_left_box"><div class"sen_top"><div class"sen_city">山东</div><qctc-time cl…

【Text2SQL 经典模型】X-SQL

论文&#xff1a;X-SQL: reinforce schema representation with context ⭐⭐⭐⭐ Microsoft, arXiv:1908.08113 X-SQL 与 SQLova 类似&#xff0c;使用 BERT style 的 PLM 来获得 representation&#xff0c;只是融合 NL question 和 table schema 的信息的方式不太一样&#…

Keil MDK map文件学习笔记

Keil MDK map文件学习笔记 map文件组成1.Section Cross References段交叉引用2.Removing Unused input sections from the image移除无用的段3.Image Symbol Table镜像符号表局部符号表全局符号表 4.Memory Map of the image镜像存储器映射ROM区执行域RAM区执行域 5. Image com…

C#学习指南:重要内容与实用技巧

学习C#编程是一段充满挑战但又非常充实的旅程。以下是我在学习过程中积累的一些经验&#xff0c;希望能对大家有所帮助。 一、掌握基础概念 类及其成员 C#中的类是编程的基础模块。理解类的结构、属性、方法和构造函数是至关重要的。每个类都有其特定的功能&#xff0c;学会如…

Milvus 使用过程中的常见问题集锦

引言 在使用Milvus的过程中&#xff0c;可能会遇到一些常见问题。这些问题可能涉及到配置、查询、数据同步等方面。 常见问题 以下是一些可能遇到的常见问题及其解决方法&#xff1a; 查询结果不正确&#xff1a; 可能原因&#xff1a;Milvus内部缓存与数据不一致&#xff0…

【数据结构】哈夫曼树和哈夫曼编码

一、哈夫曼树 1.1 哈夫曼树的概念 给定一个序列&#xff0c;将序列中的所有元素作为叶子节点构建一棵二叉树&#xff0c;并使这棵树的带权路径长度最小&#xff0c;那么我们就得到了一棵哈夫曼树&#xff08;又称最优二叉树&#xff09; 接下来是名词解释&#xff1a; 权&a…

APISIX-简单使用

APISIX-简单使用 这个工具还是很不错的&#xff0c;可视化的配置很清晰 &#xff0c; 想用NGINX的配置模式也是可以的&#xff0c;就是要去修改配置文件了。 APISIX&#xff0c;一个很不错的可视化工具&#xff0c;用来代替Nginx相当不错&#xff0c;可作为Nginx的平替方案&…

Leecode热题100---45:跳跃游戏②

题目&#xff1a; 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。 返回到达 nums[n - 1] 的最小跳跃次数。 思路&#xff1a; 如果某一个作为 起跳点 的格子可以跳跃的距离是 3&#xff0c;那么表示后面…

解耦:哪些方法可以用来解耦代码

目录 1.引用 2.为何解耦如此重要 3.如何判断代码是否需要解耦 4.如何给代码解耦 5.思考题 1.引用 前面我们曾经讲到&#xff0c;重构可以分为大型重构和小型重构。小型重构的主要目的是提高代码的可读性&#xff0c;大型重构的主要目的是解耦。本节讲解如何对代码进行解耦…

用python为目录下的文件生成索引

好久没写文章了。 有一个需求&#xff1a; 我的一个目录下有很多的.html文件&#xff0c; 每个html会包含一些image &#xff0c;但都在各自的目录中。 .html特别多&#xff0c;有好几百个&#xff0c;我需要一个index.hmtl把这些html全部索引起来&#xff0c;使得我一个点击&a…

计算机如何将输入文字显示出来的?渲染Image rendering

1.文字渲染的简单理解 渲染图像&#xff0c;可以理解为用cpu/gpu构造出原本不存在的图像。比如输入计算机的英文字符都是ASCII码&#xff0c;而我们在屏幕上看到显示的字符对应的应该是RGB/YUV的像素。计算机把ASCII字符转化成像素的过程就是文字渲染。又比如我们GPU用多个2D图…

全同态加密生态项目盘点:FHE技术的崛起以及应用

撰文&#xff1a;Chris&#xff0c;Techub News 在当今数字化的时代&#xff0c;隐私保护已成为一个全球性的焦点话题&#xff0c;特别是在加密货币和区块链技术快速发展的背景下。虽然当前的隐私技术在保护数据安全方面多有欠缺&#xff0c;引发了广泛的关注和批评&#xff0c…