MySQL-主从复制:概述、原理、同步数据一致性问题、搭建流程

主从复制

1. 主从复制概述

1.1 如何提升数据库并发能力

一般应用对数据库而言都是“读多写少”,也就说对数据库读取数据的压力比较大,有一个思路就是采用数据库集群的方案,做主从架构、进行读写分离,这样同样可以提升数据库的并发处理能力。但并不是所有的应用都需要对数据库进行主从架构的设置,毕竟设置架构本身是有成本的。

如果我们的目的在于提升数据库高并发访问的效率,那么首先考虑的是如何优化SQL和索引,这种方式简单有效;其次才是采用缓存的策略,比如使用 Redis将热点数据保存在内存数据库中,提升读取的效率;最后才是对数据库采用主从架构,进行读写分离。

1.2 主从复制的作用

第1个作用:读写分离。

第2个作用就是数据备份。

第3个作用是具有高可用性。

2. 主从复制的原理

2.1 原理剖析

在这里插入图片描述

三个线程

实际上主从同步的原理就是基于 binlog 进行数据同步的。在主从复制过程中,会基于3 个线程来操作,一个主库线程,两个从库线程。

二进制日志转储线程(Binlog dump thread)是一个主库线程。当从库线程连接的时候, 主库可以将二进制日志发送给从库,当主库读取事件(Event)的时候,会在 Binlog 上加锁,读取完成之后,再将锁释放掉。

从库 I/O 线程会连接到主库,向主库发送请求更新 Binlog。这时从库的 I/O 线程就可以读取到主库的二进制日志转储线程发送的 Binlog 更新部分,并且拷贝到本地的中继日志 (Relay log)。

从库 SQL 线程会读取从库中的中继日志,并且执行日志中的事件,将从库中的数据与主库保持同步。

复制三步骤

步骤1:Master将写操作记录到二进制日志(binlog)。

步骤2:SlaveMaster的binary log events拷贝到它的中继日志(relay log);

步骤3:Slave重做中继日志中的事件,将改变应用到自己的数据库中。 MySQL复制是异步的且串行化的,而且重启后从接入点开始复制。

复制的问题

复制的最大问题:延时

2.2 复制的基本原则

  • 每个Slave只有一个Master

  • 每个Slave只能有一个唯一的服务器ID

  • 每个Master可以有多个Slave

3. 同步数据一致性问题

主从同步的要求:

  • 读库和写库的数据一致(最终一致);

  • 写数据必须写到写库;

  • 读数据必须到读库(不一定);

3.1 理解主从延迟问题

进行主从同步的内容是二进制日志,它是一个文件,在进行网络传输的过程中就一定会存在主从延迟(比如 500ms),这样就可能造成用户在从库上读取的数据不是最新的数据,也就是主从同步中的数据不一致性问题。

3.2 主从延迟问题原因

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

主备延迟最直接的表现是,从库消费中继日志(relay log)的速度,比主库生产binlog的速度要慢。造成原因:

1、从库的机器性能比主库要差

2、从库的压力大

3、大事务的执行

3.3 如何减少主从延迟

若想要减少主从延迟的时间,可以采取下面的办法:

  1. 降低多线程大事务并发的概率,优化业务逻辑

  2. 优化SQL,避免慢SQL,减少批量操作,建议写脚本以update-sleep这样的形式完成。

  3. 提高从库机器的配置,减少主库写binlog和从库读binlog的效率差。

  4. 尽量采用短的链路,也就是主库和从库服务器的距离尽量要短,提升端口带宽,减少binlog传输的网络延时。

  5. 实时性要求的业务读强制走主库,从库只做灾备,备份。

3.4 如何解决一致性问题

读写分离情况下,解决主从同步中数据不一致的问题, 就是解决主从之间 数据复制方式 的问题,如果按照数据一致性 从弱到强 来进行划分,有以下 3 种复制方式。

方法 1:异步复制

MVSQL默认的复制方式,在异步复制的方式中主库在执行完事务操作以后,会立刻给客户端返回。他不需要关心从库是否完成该事务的执行。

这种方式会导致一个问题,那就是当主库出现故障时,主库虽然事务执行完了但是可能还没来得及把数据同步给从库,就挂了。那么当从库升级为主库之后,他会丢失了这次事务的变更内容。

方法 2:半同步复制

半同步复制是介于全同步复制和异步复制之间的一种方案。他再执行完一个事务之后,也不会立刻给客户端反馈,但是也不会等所有从库都完成事务,而是等其中一个从库完成接收到事件之后,再反馈给客户端。
在半同步复制这个方案中,会在事务提交的2阶段都完成之后,等待从库接收到binlog,然后再返回成功。

方法 3:组复制

​ 首先我们将多个节点共同组成一个复制组,在执行读写(RW)事务的时候,需要通过一致性协议层(Consensus 层)的同意,也就是读写事务想要进行提交,必须要经过组里“大多数人”(对应 Node 节点)的同意,大多数指的是同意的节点数量需要大于 (N/2+1),这样才可以进行提交,而不是原发起方一个说了算。而针对只读(RO)事务则不需要经过组内同意,直接 COMMIT 即可。

方法 4:全同步复制

全同步复制的这个方式中,当主库执行完一个事务之后,他会等待所有的从库完成数据复制之后,才会给客户端反馈。这种方式安全性可以保障了,但是性能很差。如果从库比较多的话,会导致整个过程更加长。

4、主从复制-搭建流程

4.1 环境准备

一主一从,默认安装好了MySQL了,需要安装,可以参考

节点ip数据库角色
节点1192.168.3.131Mysql主j节点
节点2192.168.3.137Mysql从节点

4.2 主节点配置

主节点需要做的工作就是创建用户并赋予权限,然后开启binlog日志。

首先创建给从节点登录用的账号和密码,如下

#查看主节点的登录名账号,没有用于从节点登录的账号密码
select Host,User from user;
create user 'slave01'@'192.168.3.137' identified by '123456';
select Host,User from user;

在这里插入图片描述

授予从节点登录主节点验证的权限

由于MySQL的版本问题,我这个是8.0版本的,在授权语句后面加上identified by '123456'会报错,所以,我此处,没加

grant replication slave on *.* to 'slave01'@'192.168.157.137';

在这里插入图片描述

显示确认一下授予权限的情况

show grants for 'slave01'@'192.168.3.137';

在这里插入图片描述

修改mysql配置文件

vim /etc/my.cnf
#主从复制配置
log-bin=mysql-bin
server-id=131	#和从节点不一样即可

在这里插入图片描述

4.3 从节点配置

从服务器需要做的工作就是配置同步日志,指定主节点的ip,端口,用户,密码等,然后启动从节点

修改mysql配置文件

#主从复制配置
log-bin=mysql-bin
server-id=137

在这里插入图片描述

重启从节点mysql

在这里插入图片描述

先在主节点mysql上查看master信息

show master status;

在这里插入图片描述

在从节点的MySQL上指定主节点信息

change master to master_host='192.168.3.131',master_user='slave01',master_password='123456',master_log_file='master-a-bin.000001',master_log_pos=156;

在这里插入图片描述

  • master_host 是主节点ip
  • master_user 和 master_password 是主节点创建给从节点的账号和密码
  • master_log_file 和master_log_pos 根据上一步查询出来的File和Position值自行更换。

启动从节点

start slave;

最终这两个参数都是yes就搭建完成了,但是也要注意是否有报错信息

判断是否成功主要看 Slave_IO_Running 和 Slave_SQL_Running 是否都为YES。

在这里插入图片描述

上面的两个yes,笔者也走过很多弯路,才走到的,并不是一下子就成功的,下面我归纳一下,我搭建过程中遇到的问题

4.4 遇到报错解决

情况1:Slave_IO_Running为No

由于有些同学为了方便,服务器都是克隆的,所以就会造成安装目录auto.cnf文件里对比server-uuid是一样的,可以自行排查一下

解决办法:
首先安装目录auto.cnf文件里对比server-uuid 是否一样,如果一样修改了不一样就行,或者删了文件重启mysql服务。

cat /var/lib/mysql/auto.cnf

在这里插入图片描述

保持server-uuid不一样即可

情况2:Slave_IO_Running为Connecting

发生Slave_IO_Running为Connecting的情况很多,大家可以参考这篇文章:花开城南,这篇文章基本归纳了出现Connecting的情况但是,我的遇到问题还不是这里面的

在这里插入图片描述

查看报错信息

在这里插入图片描述

发现是密码的认证方式有问题,上网查了一下,该博主 周杰伦的稻香的解决方法可以我采用的是第一种方法,但是每次重启服务器或者MySQL服务,都需要现在从服务器节点的MySQL上,登录一下主节点的MySQL,请求服务器公钥

mysql -u slave01 -p -h 192.168.3.131 -P3306 --get-server-public-key

在这里插入图片描述

在这种情况下,服务器将RSA公钥发送给客户端,后者使用它来加密密码并将结果返回给服务器。插件使用服务器端的RSA私钥解密密码,并根据密码是否正确来接受或拒绝连接。

  • 主从节点都重新停止主从复制,清空之前的主从复制配置信息
  • 在从库配置change masrer to并且start slave,复制可以正常启动:
#主从节点都停止主从复制,在两个MySQL客户端中分别执行
#清空之前的主从复制配置信息
stop slave;
reset master;#从新配置主从复制
change master to master_host='192.168.3.131',master_user='slave01',master_password='123456',master_log_file='master-a-bin.000001',master_log_pos=156;

情况3:Slave_IO_Running为Connecting,报错:could not find first log file name in binary log index file

在这里插入图片描述

解决方法:

stop slave;
reset slave;
start slave;

在这里插入图片描述

情况4:主从服务器的MySQL的master状态不一致

重启过,配置信息会发生变化

在这里插入图片描述

因为之前已经创建过主节点服务器,需停掉之前的配置 再重新配置

stop slave;
reset master;

需要重新指定主节点服务器信息

change master to master_host='192.168.3.131',master_user='slave01',master_password='123456',master_log_file='master-a-bin.000002',master_log_pos=156;

在这里插入图片描述

主节点数据库备份操作

使用mysqldump命令,将test数据库备份下来

mysqldump -uroot -p'123456' -B test > /backup/mysql_bak.$(date +%F).sql.gz

在这里插入图片描述

远程发送到从节点上

scp /backup/mysql_bak.2024-04-01.sql.gz 192.168.3.137:/backup/

在这里插入图片描述

在这里插入图片描述

从库数据库还原操作

先创建数据库,否则没有数据库名,会报错

在这里插入图片描述

mysqldump -uroot -p'123456' -B test < /backup/mysql_bak.$(date +%F).sql.gz

在这里插入图片描述

从库已备份到主库的数据库

4.5 主从复制测试

在主节点创建数据库,名称为配置文件里需要同步的数据库名称,例如

create database db_test;

查看从节点,已经同步

在这里插入图片描述

创建一个表

CREATE TABLE `departments` (`department_id` int NOT NULL DEFAULT '0',`department_name` varchar(30) NOT NULL,`manager_id` int DEFAULT NULL,`location_id` int DEFAULT NULL,PRIMARY KEY (`department_id`),UNIQUE KEY `dept_id_pk` (`department_id`),KEY `dept_loc_fk` (`location_id`),KEY `dept_mgr_fk` (`manager_id`)
) 

可以看到,从节点也已经同步。

在这里插入图片描述

插入数据

INSERT INTO `departments` VALUES ('10', 'Administration', '200', '1700');

可以看到,数据也已经同步。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【引子】C++从介绍到HelloWorld

C从介绍到HelloWorld 一、C的介绍1. 简介2. 应用场景3. C的标准![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e3efb0f207f647729b92c0b5bcd4b330.png)4. C的运行过程 二、Visual Studio的安装1. 什么是Visual Studio2. Visual Studio的安装 三、完成HelloWorld1.…

突破编程_前端_SVG(概述)

1 什么是 SVG SVG&#xff0c;全称可缩放矢量图形&#xff08;Scalable Vector Graphics&#xff09;&#xff0c;是一种基于 XML&#xff08;可扩展标记语言&#xff09;的矢量图像格式。这种图像格式的主要特点是它描述的是矢量图形&#xff0c;而不是基于像素的位图图像。因…

RabbitMQ的交换机与队列

一、流程 首先先介绍一个简单的一个消息推送到接收的流程&#xff0c;提供一个简单的图 黄色的圈圈就是我们的消息推送服务&#xff0c;将消息推送到 中间方框里面也就是 rabbitMq的服务器&#xff0c;然后经过服务器里面的交换机、队列等各种关系&#xff08;后面会详细讲&am…

Java初始——IDEA-web的启动

Tomcat 文件夹作用 bin 启动 关闭的脚本文件 conf 配置 lib 依赖的jar包 logs 日志 temp 临时文件 webapps 存放的网站 Maven 1.在javaweb中&#xff0c;需要使用大量的jar包&#xff0c;手动导入 2.Maven 架构管理工具 核心&#xff1a;约定大于配置 必须按照规则 web idea-we…

蓝桥杯考前复习三

1.约数个数 由乘法原理可以得出&#xff1a; import java.util.*; public class Main{static int mod (int)1e9 7;public static void main(String[] args){Map<Integer,Integer> map new HashMap<>(); //创建一个哈希表Scanner scan new Scanner(System.in);i…

【Figma】安装指南及基础操作

先前做UI设计一直都是用PS等绘图软件设计&#xff0c;但发现在纠结像素和排版问题上会花很多时间&#xff0c;再加上AI没来得及上手&#xff0c;就需要迅速出成图&#xff0c;此时通过论坛发现了figma&#xff0c;基本上可以满足足够的需求&#xff0c;并且可以在windows系统上…

绿联 安装Redis内存数据库

绿联 安装Redis内存数据库 1、镜像 redis:latest 2、安装 2.1、基础设置 重启策略&#xff1a;容器退出时总是重启容器。 2.2、网络 桥接即可。 2.3、命令 命令说明 redis-server 启动服务用&#xff0c;不可删除&#xff1b; /etc/redis/redis.conf 添加此命令启用自定…

免费SSL通配符证书/SSL泛域名证书获取教程

我们先基本了解什么是SSL证书以及其作用。SSL证书是一种数字证书&#xff0c;它通过为网站提供身份验证和数据加密服务&#xff0c;从而保护网站的用户信息安全。当我们在浏览器的地址栏看到“https”和绿色锁标志时&#xff0c;就表示该网站使用了SSL证书。 那么什么又是通配…

【4036】基于小程序+ssm实现的软件学院会议室管理系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;ssm 【…

Python开发笔试、面试及简历复盘:全面指南

Python开发面试总结复盘 最近跳槽了&#xff0c;趁着清明假期&#xff0c;把自己最近的跳槽面试经历做个总结复盘一下。 时间准备:23年12月底&#xff0c;总计两个月的准备&#xff0c;包括简历修改、笔试准备以及项目和话术的知识储备。 开始时间:24年2月底&#xff0c;总计两…

Java单链表和LinkedList的实现

一、单链表的实现 无头单向非循环链表 定义异常用于判断所给位置是否合法 public class IndexNotLegal extends RuntimeException{public IndexNotLegal(){}public IndexNotLegal(String smg){super(smg);} } class ListNode中包含当前节点的值和下一个节点指向 实现链表的…

ES入门十四:分词器

我们存储到ES中数据大致分为以下两种&#xff1a; 全文本&#xff0c;例如文章内容、通知内容精确值&#xff0c;如实体Id 在对这两类值进行查询的时候&#xff0c;精确值类型会比较它们的二进制&#xff0c;其结果只有相等或者不想等。而对全文本类型进行等值比较是不太实现…