看完这篇还不懂 MySQL 主从复制,可以回家躺平了
wptr33 2025-07-01 23:42 21 浏览
我们在平时工作中,使用最多的数据库就是 MySQL 了,随着业务的增加,如果单单靠一台服务器的话,负载过重,就容易造成宕机。
这样我们保存在 MySQL 数据库的数据就会丢失,那么该怎么解决呢?
其实在 MySQL 本身就自带有一个主从复制的功能,可以帮助我们实现负载均衡和读写分离。
对于主服务器(Master)来说,主要负责写,从服务器(Slave)主要负责读,这样的话,就会大大减轻压力,从而提高效率。
接下来,跟着小羽一起来看看它都有哪些核心知识点呢:
简介
随着业务的增长,一台数据服务器已经满足不了需求了,负载过重。这个时候就需要减压了,实现负载均衡读写分离,一主一丛或一主多从。
主服务器只负责写,而从服务器只负责读,从而提高了效率减轻压力。
主从复制可以分为:
- 主从同步:当用户写数据主服务器必须和从服务器同步了才告诉用户写入成功,等待时间比较长。
- 主从异步:只要用户访问写数据主服务器,立即返回给用户。
- 主从半同步:当用户访问写数据主服务器写入并同步其中一个从服务器就返回给用户成功。
形式
一主一从
一主一从
一主多从
一主多从
一主一从和一主多从是我们现在见的最多的主从架构,使用起来简单有效,不仅可以实现 HA,而且还能读写分离,进而提升集群的并发能力。
多主一从
多主一从
多主一从可以将多个 MySQL 数据库备份到一台存储性能比较好的服务器上。
双主复制
双主复制
双主复制,也就是可以互做主从复制,每个 master 既是 master,又是另外一台服务器的 salve。这样任何一方所做的变更,都会通过复制应用到另外一方的数据库中。
级联复制
级联复制
级联复制模式下,部分 slave 的数据同步不连接主节点,而是连接从节点。
因为如果主节点有太多的从节点,就会损耗一部分性能用于 replication ,那么我们可以让 3~5 个从节点连接主节点,其它从节点作为二级或者三级与从节点连接,这样不仅可以缓解主节点的压力,并且对数据一致性没有负面影响。
原理
MySQL 主从复制是基于主服务器在二进制日志跟踪所有对数据库的更改。因此,要进行复制,必须在主服务器上启用二进制日志。
每个从服务器从主服务器接收已经记录到日志的数据。当一个从服务器连接到主服务器时,它通知主服务器从服务器日志中读取最后一个更新成功的位置。
从服务器接收从那时发生起的任何更新,并在主机上执行相同的更新。然后封锁等待主服务器通知的更新。
从服务器执行备份不会干扰主服务器,在备份过程中主服务器可以继续处理更新。
过程
工作过程
MySQL 的主从复制工作过程大致如下:
- 从库生成两个线程,一个 I/O 线程,一个 SQL 线程;
- I/O 线程去请求主库的 binlog,并将得到的 binlog 日志写到 relay log(中继日志) 文件中;
- 主库会生成一个 log dump 线程,用来给从库 I/O 线程传 binlog;
- SQL 线程会读取 relay log 文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致;
工作过程
请求流程
MySQL 建立请求的主从的详细流程如下:
- 当从服务器连接主服务器时,主服务器会创建一个 log dump 线程,用于发送 binlog 的内容。在读取 binlog 的内容的操作中,会对象主节点上的 binlog 加锁,当读取完成并发送给从服务器后解锁。
- 当从节点上执行 start slave 命令之后,从节点会创建一个 IO 线程用来连接主节点,请求主库中更新 binlog。IO 线程接收主节点 binlog dump 进程发来的更新之后,保存到 relay-log 中。
- 从节点 SQL 线程负责读取 realy-log 中的内容,解析成具体的操作执行,最终保证主从数据的一致性。
类型
异步复制
一个主库,一个或多个从库,数据异步同步到从库。
异步复制
这种模式下,主节点不会主动推送数据到从节点,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理。
这样就会有一个问题,主节点如果崩溃掉了,此时主节点上已经提交的事务可能并没有传到从节点上,如果此时,强行将从提升为主,可能导致新主节点上的数据不完整。
同步复制
在 MySQL cluster 中特有的复制方式。
当主库执行完一个事务,然后所有的从库都复制了该事务并成功执行完才返回成功信息给客户端。
因为需要等待所有从库执行完该事务才能返回成功信息,所以全同步复制的性能必然会收到严重的影响。
半同步复制
在异步复制的基础上,确保任何一个主库上的事物在提交之前至少有一个从库已经收到该事物并日志记录下来。
半同步复制
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到 relay log 中才返回成功信息给客户端(只能保证主库的 Binlog 至少传输到了一个从节点上),否则需要等待直到超时时间然后切换成异步模式再提交。
相对于异步复制,半同步复制提高了数据的安全性,一定程度的保证了数据能成功备份到从库,同时它也造成了一定程度的延迟,但是比全同步模式延迟要低,这个延迟最少是一个 TCP/IP 往返的时间。所以,半同步复制最好在低延时的网络中使用。
半同步模式不是 MySQL 内置的,从 MySQL 5.5 开始集成,需要 master 和 slave 安装插件开启半同步模式。
延迟复制
在异步复制的基础上,人为设定主库和从库的数据同步延迟时间,即保证数据延迟至少是这个参数。
方式
MySQL 主从复制支持两种不同的日志格式,这两种日志格式也对应了各自的复制方式。当然也有二者相结合的混合类型复制。
语句复制
基于语句的复制相当于逻辑复制,即二进制日志中记录了操作的语句,通过这些语句在从数据库中重放来实现复制。
这种方式简单,二进制文件小,传输带宽占用小。但是基于语句更新依赖于其它因素,比如插入数据时利用了时间戳。
因此在开发当中,我们应该尽量将业务逻辑逻辑放在代码层,而不应该放在 MySQL 中,不易拓展。
特点:
- 传输效率高,减少延迟。
- 在从库更新不存在的记录时,语句赋值不会失败。而行复制会导致失败,从而更早发现主从之间的不一致。
- 设表里有一百万条数据,一条sql更新了所有表,基于语句的复制仅需要发送一条sql,而基于行的复制需要发送一百万条更新记录
行数据复制
基于行的复制相当于物理复制,即二进制日志中记录的实际更新数据的每一行。
这样导致复制的压力比较大,日志占用的空间大,传输带宽占用大。但是这种方式比基于语句的复制要更加精确。
特点:
- 不需要执行查询计划。
- 不知道执行的到底是什么语句。
- 例如一条更新用户总积分的语句,需要统计用户的所有积分再写入用户表。如果是基于语句复制的话,从库需要再一次统计用户的积分,而基于行复制就直接更新记录,无需再统计用户积分。
混合类型的复制
一般情况下,默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。
配置
配置主要要点如下:
# 如果在双主复制结构中没有设置ID的话就会导致循环同步问题
server_id=1
# 即日志中记录的是语句还是行更新或者是混合
binlog_format=mixed
# 在进行n次事务提交以后,Mysql将执行一次fsync的磁盘同步指令。将缓冲区数据刷新到磁盘。
# 为0的话由Mysql自己控制频率。
sync_binlog=n
# 为0的话,log buffer将每秒一次地写入log file中并且刷新到磁盘。
mysqld进程崩溃会丢失一秒内的所有事务。
# 为1的话,每次事务log buffer会写入log file并刷新到磁盘。(较为安全)
# 在崩溃的时候,仅会丢失一个事务。
# 为2的话,每次事务log buffer会写入log file,但一秒一次刷新到磁盘
innodb_flush_logs_at_trx_commit=0
# 阻止从库崩溃后自动启动复制,给一些时间来修复可能的问题,
# 崩溃后再自动复制可能会导致更多的问题。并且本身就是不一致的
skip_slave_start=1
# 是否将从库同步的事件也记录到从库自身的bin-log中
# 允许备库将重放的事件也记录到自身的二进制日志中去,可以将备库当做另外一台主库的从库
log_slave_update
# 日志过期删除时间,延迟严重的话会导致日志文件占用磁盘
expire_logs_days=7
问题
延迟
当主库的 TPS 并发较高的时候,由于主库上面是多线程写入的,而从库的SQL线程是单线程的,导致从库SQL可能会跟不上主库的处理速度。
解决方法:
- 网络方面:尽量保证主库和从库之间的网络稳定,延迟较小;
- 硬件方面:从库配置更好的硬件,提升随机写的性能;
- 配置方面:尽量使 MySQL 的操作在内存中完成,减少磁盘操作。或升级 MySQL5.7 版本使用并行复制;
- 建构方面:在事务中尽量对主库读写,其它非事务的读在从库。消除一部分延迟带来的数据库不一致。增加缓存降低一些从库的负载。
数据丢失
当主库宕机后,数据可能丢失。
解决方法:
使用半同步复制,可以解决数据丢失的问题。
注意事项
MySQL 需要注意以下事项:
- MySQL 主从复制是 MySQL 高可用性,高性能(负载均衡)的基础;
- 简单,灵活,部署方式多样,可以根据不同业务场景部署不同复制结构;
- 复制过程中应该时刻监控复制状态,复制出错或延时可能给系统造成影响;
- MySQL 主从复制目前也存在一些问题,可以根据需要部署
复制增强功能。
作用
主从复制带来了很多好处,当我们的主服务器出现问题,可以切换到从服务器;可以进行数据库层面的读写分离;可以在从数据库上进行日常备份。还可以保证:
- 数据更安全:做了数据冗余,不会因为单台服务器的宕机而丢失数据;
- 性能大大提升:一主多从,不同用户从不同数据库读取,性能提升;
- 扩展性更优:流量增大时,可以方便的增加从服务器,不影响系统使用;
- 负载均衡:一主多从相当于分担了主机任务,做了负载均衡。
应用场景
MySQL 主从复制集群功能使得 MySQL 数据库支持大规模高并发读写成为可能,同时有效地保护了物理服务器宕机场景的数据备份。
横向扩展
将工作负载分发到各 Slave 节点上,从而提高系统性能。
在这个场景下,所有的写(write)和更新(update)操作都在 Master 节点上完成;所有的读( read)操作都在 Slave 节点上完成。通过增加更多的 Slave 节点,便能提高系统的读取速度。
数据安全
数据从 Master 节点复制到 Slave 节点上,在 Slave 节点上可以暂停复制进程。可以在 Slave 节点上备份与 Master 节点对应的数据,而不用影响 Master 节点的运行。
数据分析
实时数据可以在 Master 节点上创建,而分析这些数据可以在 Slave 节点上进行,并且不会对 Master 节点的性能产生影响。
远距离数据分布
可以利用复制在远程主机上创建一份本地数据的副本,而不用持久的与Master节点连接。
拆分访问
可以把几个不同的从服务器,根据公司的业务进行拆分。通过拆分可以帮助减轻主服务器的压力,还可以使数据库对外部用户浏览、内部用户业务处理及 DBA 人员的备份等互不影响。
相关推荐
- MySQL进阶五之自动读写分离mysql-proxy
-
自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...
- 3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?
-
引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...
- 一文由浅入深带你完全掌握MySQL的锁机制原理与应用
-
本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...
- 验证Mysql中联合索引的最左匹配原则
-
后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...
- MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)
-
目录1.索引基础...
- 你会看 MySQL 的执行计划(EXPLAIN)吗?
-
SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...
- MySQL 从入门到精通(四)之索引结构
-
索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...
- mysql总结——面试中最常问到的知识点
-
mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...
- mysql总结——面试中最常问到的知识点(2)
-
首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...
- MySQL基础全知全解!超详细无废话!轻松上手~
-
本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...
- 深入剖析 MySQL 中的锁机制原理_mysql 锁详解
-
在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...
- Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析
-
引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...
- MySQL基础篇:DQL数据查询操作_mysql 查
-
一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...
- MySql:索引的基本使用_mysql索引的使用和原理
-
一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
程序员的开源月刊《HelloGitHub》第 71 期
-
详细介绍一下Redis的Watch机制,可以利用Watch机制来做什么?
-
假如有100W个用户抢一张票,除了负载均衡办法,怎么支持高并发?
-
Java面试必考问题:什么是乐观锁与悲观锁
-
如何将AI助手接入微信(打开ai手机助手)
-
redission YYDS spring boot redission 使用
-
SparkSQL——DataFrame的创建与使用
-
一文带你了解Redis与Memcached? redis与memcached的区别
-
如何利用Redis进行事务处理呢? 如何利用redis进行事务处理呢英文
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)