MySQL 的主从架构

article/2025/9/27 8:28:19

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

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

在这里插入图片描述

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

  • 高可用,实时灾备,用于故障切换。比如主库挂了,可以切从库
  • 读写分离,提供查询服务,减少主库压力,提升性能
  • 备份数据,避免影响业务

数据库主从复制原理

  1. 主数据库有个 binlog 二进制文件,记录了所有增删改的 SQL 语句(binlog 线程)
  2. 从数据库把主数据库的 binlog 文件的 SQL 语句复制到自己的中继日志 relay log 中(I/O 线程)
  3. 从数据库的 relay log 重做日志文件,再执行一次这些 SQL 语句(SQL 执行线程)

在这里插入图片描述

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

  1. 主库的更新 SQL(update、insert、delete)被写到 binlog
  2. 从库发起连接,连接到主库
  3. 此时主库创建一个 binlog dump thread,把 binlog 的内容发送到从库
  4. 从库启动之后,创建一个 I/O 线程,读取主库传过来的 binlog 内容并写入到 relay log
  5. 从库还会创建一个 SQL 线程,从 relay log 里面读取内容,从 ExecMasterLog_Pos 位置开始执行读取到的更新事件,将更新内容写入 slave 的 db 中

主主、主从、主备的区别?

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

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

我们学习数据库的主从复制原理后,了解到从库在拿到并执行主库的 binlog 日志后,就可以保持与主库数据一致了。

这是为什么呢?哪些情况下又会导致数据不一致呢?

长连接

主库和从库在同步数据的过程中为了防止中断导致数据丢失,主库与从库之间维持了一个长连接,主库内部有一个线程,专门服务于从库的这个长连接。

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;

我们知道,MySQL 选择 a 索引和选择 create_time 索引,最后 limit 1 出来的数据有可能是不一样的。

所以就会存在这种情况:在 statement 格式下,主库在执行这条 SQL 语句时,使用的是索引 a,而从库在执行这条 SQL 语句时,使用的是索引 create_time,最后主从数据就不一致了。

那么如何解决这个问题呢?

可以把 binlog 日志格式修改为 row。

row 格式下的 binlog 日志,记录的不是 SQL 原文,而是两个 event:Table_map 和 Delete_rows。

Table_map event 说明要操作的表;Delete_rows event 用于定义要删除的行为,记录删除的具体行数。row 格式的 binlog 记录的就是要删除的主键 id 信息,因此不会出现主从不一致的问题。

如果 SQL 语句要删除 10 万行的数据呢?

使用 row 格式就会很占空间,况且 10 万条数据都在 binlog 里面,写 binlog 的时候也很耗 I/O,但是 statement 格式的 binlog 又有可能会导致数据的不一致。

因此 MySQL 提供了一个折中的方案,mixed 格式的 binlog。所谓 mixed 格式其实就是 row 和 statement 格式的混合使用,当 MySQL 判断可能会出现数据不一致时,就使用 row 格式,否则就使用 statement 格式。

数据库主从延迟的原因以及解决方案

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

  • 主库执行完一个事务,写入 binlog,我们把这个时刻记为 T1
  • 主库同步数据给从库,从库接收完这个 binlog 的时刻,记录为 T2
  • 从库执行完这个事务,这个时刻记录为T3

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

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

  • 如果从库所在的机器比主库的机器性能差,就会导致主从延迟,这种情况比较好解决,只需让主从库选择一样规格的机器就好
  • 如果从库的压力大,也会导致主从延迟。比如因为主库是直接影响业务的,大家可能使用会比较克制,因此一般查询都直接打到从库上了,结果导致从库查询会消耗大量的 CPU,影响同步速度,最后导致主从延迟。这种情况,可以搞一主多从的架构,即多接几个从库分摊读的压力。另外,还可以把 binlog 接入到 Hadoop 这类系统,让它们提供查询的能力
  • 大事务也会导致主从延迟。如果一个事务执行就要 10 分钟,那么主库执行完后,给到从库执行,最后这个事务可能就会导致从库延迟 10 分钟。所以在日常开发中,我们特别强调不要一次性执行太多 SQL 语句,需要分批进行,其实也是为了避免大事务。另外,大表的 DDL 语句也会导致大事务
  • 网络延迟也会导致主从延迟,这种情况只能优化网络,比如将 20M 带宽升级到 100M 等
  • 如果从数据库过多也会导致主从延迟,因此要避免复制的从节点数量过多。从数据库一般以 3~5 个为宜
  • 低版本的 MySQL 只支持单线程复制,如果主库并发高,来不及传送到从库,就会导致延迟。可以换用更高版本的 MySQL ,使用多线程复制

数据库高可用方案

  • 双机主备高可用
  • 一主一从
  • 一主多从
  • MariaDB 同步多主机集群
  • 数据库中间件

双机主备高可用

在这里插入图片描述

  • 架构描述:两台机器 A 和 B,A 为主库,负责读写,B 为备库,只备份数据。如果 A 库发生故障,B 库成为主库负责读写。故障修复后,A 成为备库,主库 B 同步数据到备库 A
  • 优点:一个机器故障了可以自动切换,操作比较简单
  • 缺点:只有一个库在工作,读写压力大,不能实现读写分离,并发也有一定限制

一主一从

在这里插入图片描述

  • 架构描述:两台机器 A 和 B,A 为主库,负责读写,B 为从库,负责读数据。如果 A 库发生故障,B 库成为主库负责读写。故障修复后,A 成为从库,主库 B 同步数据到从库 A
  • 优点:从库支持读,分担了主库的压力,提升了并发度。一个机器故障了可以自动切换,操作比较简单
  • 缺点:一台从库,并发支持还是不够,并且一共只有两台机器,还是存在同时故障的几率,不够高可用

一主多从

在这里插入图片描述

  • 架构描述:一台主库多台从库,A 为主库,负责读写,B、C、D 为从库,负责读数据。如果 A 库发生故障,B 库成为主库负责读写,C、D 负责读。故障修复后,A 也成为从库,主库 B 同步数据到从库 A
  • 优点:多个从库支持读,分担了主库的压力,明显提升了并发读
  • 缺点:只有一台主机写,因此并发写不高

MariaDB 同步多主机集群

在这里插入图片描述

  • 架构描述:由代理层实现负载均衡,多个数据库可以同时进行读写操作。各个数据库之间可以通过 Galera Replication 方法进行数据同步,理论上每个库的数据是完全一致的
  • 优点:读写的并发度都得到明显提升,可以实现任意节点读写,可以自动剔除故障节点,具有较高的可靠性
  • 缺点:数据量不支持特别大。要避免大事务卡死。如果集群节点中有一个变慢,其他节点也会跟着变慢

数据库中间件

在这里插入图片描述

  • 架构描述:Mycat 分片存储,每个分片配置一主多从的集群
  • 优点:解决高并发高数据量的高可用方案
  • 缺点:维护成本比较大

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

相关文章

MySQL主从同步(一主一从、一主多从、主从从)等结构的概述与配置

前言&#xff1a;前面我们了解了MySQL数据库的基础知识&#xff0c;今天及接下来的五天时间里我会给大家带来MySQL进阶方面的一些学习总结&#xff0c;如有不足&#xff0c;还请大家留言指出&#xff1b;下面我们就开始今天的内容。 ** 部署mysql主从同步结构 **  主从同步…

MySQL的主从

前言 金三银四面试的时候&#xff0c;面试官经常会问MySQL主从。今天就跟大家聊聊MySQL的主从。 数据库主从概念、优点、用途 数据库主从复制原理 主主、主从、主备的区别 MySQL是怎么保证主从一致的 数据库主从延迟的原因与解决方案 聊聊数据库的高可用方案 1. 数据库…

主从原理,一主多从架构

主从架构总结 主从原理 用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; //这是菱形边长…