MySQL的主从

article/2025/9/27 8:46:01

前言

金三银四面试的时候,面试官经常会问MySQL主从。今天就跟大家聊聊MySQL的主从。

  • 数据库主从概念、优点、用途

  • 数据库主从复制原理

  • 主主、主从、主备的区别

  • MySQL是怎么保证主从一致的

  • 数据库主从延迟的原因与解决方案

  • 聊聊数据库的高可用方案

1. 数据库主从概念、优点、用途

主从数据库是什么意思呢,主是主库的意思,从是从库的意思。数据库主库对外提供读写的操作,从库对外提供读的操作。

数据库为什么需要主从架构呢?

  • 高可用,实时灾备,用于故障切换。比如主库挂了,可以切从库。

  • 读写分离,提供查询服务,减少主库压力,提升性能

  • 备份数据,避免影响业务。

2. 数据库主从复制原理

主从复制原理,简言之,分三步曲进行:

  • 主数据库有个bin log二进制文件,纪录了所有增删改SQL语句。(binlog线程)

  • 从数据库把主数据库的bin log文件的SQL 语句复制到自己的中继日志 relay log(io线程)

  • 从数据库的relay log重做日志文件,再执行一次这些sql语句。(Sql执行线程)

详细的主从复制过程如图:

上图主从复制过程分了五个步骤进行:

  1. 主库的更新SQL(update、insert、delete)被写到binlog

  2. 从库发起连接,连接到主库。

  3. 此时主库创建一个binlog dump thread,把bin log的内容发送到从库。

  4. 从库启动之后,创建一个I/O线程,读取主库传过来的bin log内容并写入到relay log

  5. 从库还会创建一个SQL线程,从relay log里面读取内容,从ExecMasterLog_Pos位置开始执行读取到的更新事件,将更新内容写入到slave的db

3. 主主、主从、主备的区别

数据库主主:两台都是主数据库,同时对外提供读写操作。客户端访问任意一台。数据存在双向同步。

数据库主从:一台是主数据库,同时对外提供读写操作。一台是从数据库,对外提供读的操作。数据从主库同步到从库。

数据库主备:一台是主数据库,同时对外提供读写操作。一台是备库,只作为备份作用,不对外提供读写,主机挂了它就取而代之。数据从主库同步到备库。

从库和备库,就是slave库功能不同因此叫法才不一样而已。一般slave库都会对外提供读的功能的,因此,大家日常听得比较多就是主从

4. MySQL是怎么保证主从一致的

我们学习数据库的主从复制原理后,了解到从库拿到并执行主库的binlog日志,就可以保持数据与主库一致了。这是为什么呢?哪些情况会导致不一致呢?

4.1 长链接

主库和从库在同步数据的过程中断怎么办呢,数据不就会丢失了嘛。因此主库与从库之间维持了一个长链接,主库内部有一个线程,专门服务于从库的这个长链接的。

4.2 binlog格式

binlog 日志有三种格式,分别是statement,row和mixed

如果是statement格式,binlog记录的是SQL的原文,如果主库和从库选的索引不一致,可能会导致主库不一致。我们来分析一下。假设主库执行删除这个SQL(其中a和create_time都有索引)如下:

delete from t where a > '666' and create_time<'2022-03-01' limit 1;

我们知道,数据库选择了a索引和选择create_time索引,最后limit 1出来的数据一般是不一样的。所以就会存在这种情况:在binlog = statement格式时,主库在执行这条SQL时,使用的是索引a,而从库在执行这条SQL时,使用了索引create_time。最后主从数据不一致了。

如何解决这个问题呢?

可以把binlog格式修改为rowrow格式的binlog日志,记录的不是SQL原文,而是两个event:Table_map 和 Delete_rows。Table_map event说明要操作的表,Delete_rows event用于定义要删除的行为,记录删除的具体行数。row格式的binlog记录的就是要删除的主键ID信息,因此不会出现主从不一致的问题。

但是如果SQL删除10万行数据,使用row格式就会很占空间的,10万条数据都在binlog里面,写binlog的时候也很耗IO。但是statement格式的binlog可能会导致数据不一致,因此设计MySQL的大叔想了一个折中的方案,mixed格式的binlog。所谓的mixed格式其实就是rowstatement格式混合使用,当MySQL判断可能数据不一致时,就用row格式,否则使用就用statement格式。

5. 数据库主从延迟的原因与解决方案

主从延迟是怎么定义的呢?与主从数据同步相关的时间点有三个

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

  2. 主库同步数据给从库,从库接收完这个binlog的时刻,记录为T2

  3. 从库执行完这个事务,这个时刻记录为T3

所谓主从延迟,其实就是指同一个事务,在从库执行完的时间和在主库执行完的时间差值,即T3-T1

哪些情况会导致主从延迟呢?

  1. 如果从库所在的机器比主库的机器性能差,会导致主从延迟,这种情况比较好解决,只需选择主从库一样规格的机器就好。

  2. 如果从库的压力大,也会导致主从延迟。比如主库直接影响业务的,大家可能使用会比较克制,因此一般查询都打到从库了,结果导致从库查询消耗大量CPU,影响同步速度,最后导致主从延迟。这种情况的话,可以搞了一主多从的架构,即多接几个从库分摊读的压力。另外,还可以把binlog接入到Hadoop这类系统,让它们提供查询的能力。

  3. 大事务也会导致主从延迟。如果一个事务执行就要10分钟,那么主库执行完后,给到从库执行,最后这个事务可能就会导致从库延迟10分钟啦。日常开发中,我们为什么特别强调,不要一次性delete太多SQL,需要分批进行,其实也是为了避免大事务。另外,大表的DDL语句,也会导致大事务,大家日常开发关注一下哈。

  4. 网络延迟也会导致主从延迟,这种情况你只能优化你的网络啦,比如带宽20M升级到100M类似意思等。

  5. 如果从数据库过多也会导致主从延迟,因此要避免复制的从节点数量过多。从库数据一般以3-5个为宜。

  6. 低版本的MySQL只支持单线程复制,如果主库并发高,来不及传送到从库,就会导致延迟。可以换用更高版本的Mysql,可以支持多线程复制。

6. 聊聊数据的库高可用方案

  • 双机主备

  • 一主一从

  • 一主多从

  • MariaDB同步多主机

  • 数据库中间件

6.1 双机主备高可用

  • 架构描述:两台机器A和B,A为主库,负责读写,B为备库,只备份数据。如果A库发生故障,B库成为主库负责读写。修复故障后,A成为备库,主库B同步数据到备库A

  • 优点:一个机器故障了可以自动切换,操作比较简单。

  • 缺点:只有一个库在工作,读写压力大,未能实现读写分离,并发也有一定限制

6.2 一主一从

  • 架构描述: 两台机器A和B,A为主库,负责读写,B为从库,负责读数据。如果A库发生故障,B库成为主库负责读写。修复故障后,A成为从库,主库B同步数据到从库A。

  • 优点:从库支持读,分担了主库的压力,提升了并发度。一个机器故障了可以自动切换,操作比较简单。

  • 缺点:一台从库,并发支持还是不够,并且一共两台机器,还是存在同时故障的机率,不够高可用

6.3 一主多从

  • 架构描述: 一台主库多台从库,A为主库,负责读写,B、C、D为从库,负责读数据。如果A库发生故障,B库成为主库负责读写,C、D负责读。修复故障后,A也成为从库,主库B同步数据到从库A。

  • 优点:多个从库支持读,分担了主库的压力,明显提升了读的并发度。

  • 缺点:只有台主机写,因此写的并发度不高

6.4 MariaDB同步多主机集群

  • 架构描述:有代理层实现负载均衡,多个数据库可以同时进行读写操作;各个数据库之间可以通过Galera Replication方法进行数据同步,每个库理论上数据是完全一致的。

  • 优点:读写的并发度都明显提升,可以任意节点读写,可以自动剔除故障节点,具有较高的可靠性。

  • 缺点:数据量不支持特别大。要避免大事务卡死,如果集群节点一个变慢,其他节点也会跟着变慢。

6.5 数据库中间件

  • 架构描述:mycat分片存储,每个分片配置一主多从的集群。

  • 优点:解决高并发高数据量的高可用方案

  • 缺点:维护成本比较大。


http://chatgpt.dhexx.cn/article/PkLuGZin.shtml

相关文章

主从原理,一主多从架构

主从架构总结 主从原理 用binlog做主从&#xff0c;redolog只支持innodb 过程 ①start slave后从库启动io线程连接主库&#xff0c;请求读日志②dump线程根据请求信息读取指定位置后的日志③完成后就响应成功&#xff0c;没有确认机制④IO线程收到信息&#xff0c;将受到的日…

主从复制:主从复制的概述、一主一从架构搭建主从复制的原理、同步数据一致性问题

文章目录 1. 主从复制的概述1.1 如何提升数据库的并发能力1.2 主从复制的作用 2. 主从复制的原理2.1 原理剖析2.2 复制的最大问题2.3 复制的基本原则 3. 一主一从架构搭建3.1 准备工作3.2 主机配置文件3.3 从机配置文件3.4 建立账户并授权3.5 配置需要复制的主机3.6 测试3.7 停…

c/c++经典面试题(高频考点)

一、数据结构及算法&#xff08;快排、归并、堆排等&#xff09; 十大排序算法 数据结构(c/c版)-严蔚敏 数据结构与算法(思维导图&#xff09; E:\学习\4.数据结构(C语言版)].严蔚敏_吴伟民.扫描版.pdf 数据结构分为8类有:数组、栈、队列、链表、树、散列表、堆、图 1.快速排…

吐血整理 | 最常见的 C/C++ 面试题(含答案)

大家好&#xff0c;我是 K 哥&#xff01; 最近群里有小伙伴想跳槽&#xff0c;问我有没有常见的 C/C 面试题。这不正好&#xff0c;K 哥之前整理了一份 PDF&#xff0c;里面包含了各种经典的 C/C 题目&#xff0c;当然更重要的是还附带了非常详细的答案。 K 哥不仅面试之前会反…

2018秋招C/C++面试题总结

博主从8月中旬开始大大小小面试了十几家公司&#xff0c;至今也许是告一段落吧&#xff0c;希望后面会有好结果&#xff0c;因此总结记录一些C/C方向常见的问题。和大家一起学习&#xff01; 参考了互联网的各种资源&#xff0c;自己尝试归类整理&#xff0c;谢谢~ 一、C和C的区…

C++面试题总结,一篇就够了

C面试题汇总 1. C基础1.1 内存模型1.1.0 内存四区1.1.1 简述C、C程序编译的内存分配情况1.1.2 分配函数与释放函数1.1.2.1 malloc / free1.1.2.2 new / delete1.1.2.3 new/delete 与 malloc/free 区别1.1.2.5 calloc 、realloc1.1.2.6 在C中&#xff0c;使用malloc申请的内存能…

C面试题--汇总

目录 一、C语言基础面试题1. gcc编译器编译的完整流程&#xff0c;分别有什么作用&#xff1f;2.什么是回调函数&#xff1f;3.地址能否使用 printf函数中的 %u形式打印&#xff1f;4.结构体与共用体&#xff08;联合体&#xff09;的区别5. static、const、volatile关键字有什…

C/C++ 最常见50道面试题

C/C经典面试题 面试题 1&#xff1a;变量的声明和定义有什么区别 为变量分配地址和存储空间的称为定义&#xff0c;不分配地址的称为声明。一个变量可以在多个地方声明&#xff0c; 但是只在一个地方定义。加入 extern 修饰的是变量的声明&#xff0c;说明此变量将在文件以外或…

C语言经典面试题学习

1. 请填写bool , float, 指针变量 与“零值”比较的if 语句。 提示&#xff1a;这里“零值”可以是0, 0.0 , FALSE 或者“空指针” 。例如int 变量n 与“零值”比较的if 语句为&#xff1a; if ( n 0 ) if ( n ! 0 ) 以此类推。 &#xff08;1&#xff09;请写出bool flag 与“…

C语言面试题目大全

http://blog.chinaunix.net/uid-12077574-id-145080.html 1.求下面函数的返回值&#xff08;微软&#xff09; int func(x) { int countx 0; while(x) { countx ; x x&(x-1); } return countx; } 假定x 9999。 答案&#xff1a;8 思路&#xff1a;将x转化为2进制&am…

C语言常见面试题汇总

文章目录 gcc的编译过程&#xff1f;static关键字变量/函数的声明和定义之间有什么区别各种指针指针常量与常量指针“引用”与指针的区别是什么&#xff1f;C语言参数传递方式&#xff1a;结构体的浅拷⻉与深拷⻉#include<> 与#include ""的区别&#xff1f;宏…

c语言打印菱形图案

1.打印空心菱形 #include<stdio.h> int main() {int n,i,m,j,k;scanf("%d", &n);m (n 1) / 2;for (i 1; i < n; i) //一行一行的循环打印{if (i < m) //分两种情况&#xff0c;上半部分和下半部分{for (j m - i; j > 0; j--)pri…

菱形的打印

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 菱形的打印 前言菱形的打印是对于初学者对for循环结构嵌套的考察&#xff0c;学会了菱形的打印基本也就掌握了for循环结构的嵌套&#xff0c;下面让我们一起看看吧~ 一、如何…

打印菱形的两种方法

1.利用字符串数组输出图案 思路&#xff1a; 用字符串数组来输出&#xff0c;第一次循环向这个字符串数组中填 ‘ * ’&#xff0c;i 从中间向左(⬅️)&#xff0c;j 从中间向右(➡️)。 第二次循环填 ‘ ’&#xff0c;i 从左向右(➡️)&#xff0c;j 从右向左(⬅️)。 char s…

JavaScript打印菱形

<!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><script type"text/javascript">// 请打印出菱形//1 3 5 7 9 7 5 3 1 九行 //1 2 3 4 5 6 7 8 9// 首先我们实现…

打印菱形图案

题目&#xff1a; 打印菱形 题目内容&#xff1a; 用C语言在屏幕上输出以下图案&#xff1a; 思路&#xff1a; 这道题的解决办法有很多&#xff0c;大多都是拆分法&#xff0c;这里捡一种我觉得最方便的方法作以介绍&#xff1a;首先我们需要明白&#xff0c;这种图案形式打…

【C】 打印菱形图案

使用VS2019 ISO C14 标准 (/std:c14) 打印菱形图案 打印出如下图案&#xff08;菱形&#xff09;。 ********* **************** 代码&#xff1a; //打印菱形图案 #include<stdio.h> int main() {//分析&#xff0c;菱形图案由空格和*号组成//声明函数void print(in…

打印菱形图案C语言详解

这是菱形图案 这是完整代码 #include<stdio.h> int main() {while(1)//这一步目的可以打印多次菱形{int i0,j0,k0,t0,n0,x0; scanf("%d",&n); //n的含义是菱形的长对角线的长度,因此n必须是奇数,也可以说是菱形竖着放时的高度x(n1)/2; //这是菱形边长…

打印菱形(两种思路)

一、输入的行数等于上半部分的金字塔行数 思路&#xff1a; 仔细观察图形&#xff0c;可以发现&#xff0c;此图形中是由空格和*按照不同个数的输出组成的。 上三角&#xff1a;先输出空格&#xff0c;后输出*&#xff0c;每行中空格&#xff1a;从上往下&#xff0c;一行减少一…

C语言实现——打印菱形

目录 前言 如何实现 代码实现 定义一个变量line来接收输入的行数 实现上半部分 实现下半部分 代码汇总 前言 输入一个数&#xff0c;打印对应的菱形 该菱形表现为&#xff1a; 从第一行到中间行的行数为输入的数&#xff0c; 从中间行到结束行的行数为输入的数。 如…