MySQL原理简介—12.MySQL主从同步

news/2024/11/27 21:14:51/文章来源:https://www.cnblogs.com/mjunz/p/18573126

大纲

1.异步复制为MySQL搭建一套主从复制架构

2.半同步复制为MySQL搭建一套主从复制架构

3.GTID为MySQL搭建一套主从复制架构

4.并行复制降低主从同步延迟或强制读主库

 

1.异步复制为MySQL搭建一套主从复制架构

(1)MySQL主从复制的原理

(2)搭建主从复制架构的配置

 

(1)MySQL主从复制的原理

一.MySQL主从复制的架构

主库接收增删改操作,把增删改操作BinLog写入本地文件。然后从库发送请求给主库,从主库中拉取BinLog。接着从库会重新执行一遍BinLog的操作,还原出一样的数据。

 

以MySQL一主两从架构为例,即一个Master节点下有两个Slave节点。其中写请求统一交给Master节点处理,读请求统一交给Slave节点处理。为了保证Slave节点和Master节点的数据一致性,Master节点在写入数据后,同时会把数据复制一份到各个Slave节点上。

 

在复制过程中一共会使用到三个线程:一个是Binlog Dump线程,位于Master节点上;另外两个线程分别是IO线程和SQL线程,它们都分别位于Slave节点上。如下图示:

二.MySQL主从复制的核心流程

步骤一:当Master节点接收到一个写请求时,该写请求可能是增删改操作。此时会把写请求的操作都记录到BinLog日志中。

 

步骤二:然后Master节点会把数据复制给Slave节点。这个过程首先要每个Slave节点连接到Master节点上。当Slave节点连接到Master节点上时,Master节点会为每一个Slave节点分别创建一个BinLog Dump线程,每个BinLog Dump线程用于向各个Slave节点发送BinLog日志。

 

步骤三:BinLog Dump线程会读取Master节点上的BinLog日志,并将BinLog日志发送给Slave节点上的IO线程。

 

步骤四:Slave节点上的IO线程接收到BinLog日志后,会将BinLog日志先写入到本地的RelayLog中。所以Slave节点的RelayLog日志中就保存了,Master节点的BinLog Dump线程发送过来的BinLog日志。

 

步骤五:Slave节点上的SQL线程就会来读取RelayLog中的BinLog日志,将其解析成具体的增删改操作。然后把这些在Master节点上进行过的操作,重新在Slave节点上也重做一遍,达到数据还原的效果,这样就可以保证Master节点和Slave节点的数据一致性了。

 

(2)搭建主从复制架构的配置

搭建时需要两台机器的,一台机器放主库,一台机器放从库。至于主库和从库如何安装和启动,这里不介绍MySQL安装步骤,这里就主要介绍搭建主从复制架构要做的一些配置。

 

首先要确保主库和从库的server-id是不同的。其次主库必须打开BinLog功能,这样主库才会写BinLog到本地磁盘。接着就可以按如下步骤在主库上执行一通操作了。

 

步骤一:在主库上创建用于主从复制的账号

mysql> create user 'backup_user'@'192.168.31.%' identified by 'backup_123';
mysql> grant replication slave on *.* to 'backup_user'@'192.168.31.%';
mysql> flush privileges;

步骤二:接着要考虑一个问题,假设主库都跑了一段时间。现在要加一个从库,那从库总不能把主库从0开始的所有binlog都拉一遍。此时应在低峰期让系统对外不可用,对主库和从库进行数据备份和导入。可以使用如下mysqldump工具把主库在这个时刻的数据做一个全量备份,但此时一定不能允许系统操作主库,因为主库的数据此时是不能有变动的。

$ /usr/local/mysql/bin/mysqldump --single-transaction -uroot -proot --master-data=2 -A > backup.sql

注意,mysqldump工具就在MySQL安装目录的bin目录下。然后用上述命令就可以对主库所有的数据都做一个备份,备份会以SQL语句的方式进入指定的backup.sql文件。只要执行这个backup.sql文件,就可以恢复出来跟主库一样的数据。至于上面命令里的--master-data=2,就是为主从复制做准备的,意思是在备份SQL文件里,要记录此时主库的BinLog文件和position号。

 

步骤三:接着可以通过scp之类的命令把这个backup.sql文件拷贝到从库服务器上。

 

步骤四:接着转移到从库上去执行,在从库上执行如下命令。把backup.sql文件里的语句都执行一遍,把主库所有的数据还原到从库。接着在从库上执行下面的命令去指定从主库进行复制。

mysql> CHANGE MASTER TO MASTER_HOST='192.168.31.229', MASTER_USER='backup_user',MASTER_PASSWORD='backup_123',MASTER_LOG_FILE='mysql-bin.000015',MASTER_LOG_POS=1689;

上面的Master机器的IP地址、用于执行复制的用户名和密码都容易知道,但是Master的BinLog文件和position是怎么知道的?这其实就是之前mysqldump导出的backup.sql里的。在执行上述命令前,打开那个backup.sql就可以看到如下内容:

MASTER_LOG_FILE='mysql-bin.000015',MASTER_LOG_POS=1689

然后就把上述内容写入到主从复制的命令里去了。

 

步骤五:接着执行一个开始进行主从复制的命令:start slave,再用show slave status查看一下主从复制的状态,看到Slave_IO_Running和Slave_SQL_Running都是Yes就说明一切正常了,此时主从开始就复制了。

 

步骤六:最后就可以在主库插入一条数据,然后在从库查询这条数据。只要能够在从库查到这条数据,就说明主从复制已经成功了。

 

以上步骤便是最简单的一种主从复制——异步复制。从库异步拉取BinLog来同步,所以会出现短暂的主从不一致问题。比如在主库刚插入数据,结果在从库马上查询,可能是查不到的。

 

2.半同步复制为MySQL搭建一套主从复制架构

只要搭建出来主从复制架构,就可以实现读写分离了。比如可以用MyCat或者ShardingSphere之类的中间件,就能实现系统写入主库,从从库去读取。

 

(1)异步复制存在的问题

但是现在搭建出来的主从复制架构有一个问题,就是之前那种搭建方式默认是一种异步的复制方式。

 

主库把日志写入BinLog文件,接着就提交事务返回,它不会管从库到底收到日志没有。万一此时主库的BinLog还没同步到从库,结果主库宕机,数据就丢失了。即使做了高可用自动切换,从库切换为主库,里面也没有刚写入的数据。所以这种方式是有问题的。

 

(2)半同步复制可以让数据不丢失

因此一般来说搭建主从复制,都是采取半同步复制方式的。这个半同步的意思:就是主库写入数据,日志进入BinLog后,起码得确保BinLog日志复制到从库了,再告诉客户端本次写入事务成功。这样起码主库突然崩了,之前写入成功的数据的BinLog日志都到从库了。从库切换为主库,数据也不会丢的,这就是所谓的半同步的意思。

 

(3)半同步复制的方式

这个半同步复制是MySQL 5.7默认的方式。首先主库会写入日志到BinLog,然后主库将BinLog复制到从库,接着主库等待从库返回一个成功的响应再提交事务,最后主库返回提交事务成功的响应给客户端。

 

这种方式可保证每个事务提交成功前,BinLog日志一定都复制到从库。所以只要事务提交成功,就可以认为数据在从库也有一份了。那么主库崩溃,已经提交的事务的数据绝对不会丢失的。

 

(4)半同步复制的搭建

在之前搭建好异步复制的基础之上,安装一下半同步复制插件就可以了。先在主库中安装半同步复制插件,同时还得开启半同步复制功能:

mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
mysql> set global rpl_semi_sync_master_enabled=on;
mysql> show plugins;

可以看到安装了这个插件即可,接着在从库也是安装这个插件以及开启半同步复制功能:

mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
mysql> set global rpl_semi_sync_slave_enabled=on;
mysql> show plugins;

接着要重启从库的IO线程:

mysql> stop slave io_thread; 
mysql> start slave io_thread;

然后在主库上检查一下半同步复制是否正常运行:

mysql> show global status like '%semi%';

如果看到了rpl_semi_sync_master_status的状态是ON,那么就代表正常运行了,到此半同步复制就开启成功了。其实一般来说主从复制都建议做成半同步复制 + 配合高可用切换机制,这样就可以保证数据库有一个在线的从库热备份主库的数据了。只要主库宕机,从库马上切换为主库,数据不丢失,数据库还高可用。

 

3.GTID为MySQL搭建一套主从复制架构

MySQL传统的主从复制搭建方式,一般都会采用半同步的复制模式。但除了传统搭建方式外,还有一种更加简便的搭建方式—GTID搭建方式。下面介绍GTID的搭建方式。

 

(1)步骤一

首先在主库进行配置:

mysql> gtid_mode=on
mysql> enforce_gtid_consistency=on
mysql> log_bin=on
mysql> server_id=单独设置一个
mysql> binlog_format=row

(2)步骤二

接着在从库进行配置:

mysql> gtid_mode=on
mysql> enforce_gtid_consistency=on
mysql> log_slave_updates=1
mysql> server_id=单独设置一个

(3)步骤三

在主库dump出来一份数据,在从库里导入这份数据,利用mysqldump备份工具进行导出。

 

(4)步骤四

其余步骤跟之前类似的,最后执行一下show master status。可以看到executed_gtid_set,里面记录的是执行过的GTID。接着执行SQL:select * from gtid_executed,进行对比。如果发现对应上了,那么此时就说明开始GTID复制了。

 

4.并行复制降低主从同步延迟或强制读主库

主从复制架构的搭建其实并不难,但比较关键的是,主从复制可能会有较大的延迟。比如主库可能都写入了100条数据了,结果从库才复制过去50条数据。那么从库就比主库落后了50条数据,这就是所谓的主从同步延迟问题。

 

(1)为什么会产生主从延迟问题

因为主库是多线程并发写入数据,所以主库写入数据的速度是很快的。但从库是单线程缓慢拉取数据,所以才导致从库复制数据的速度比较慢。

 

(2)主从之间到底延迟了多少时间

这个可以用一个工具来进行监控,比较推荐的是percona-toolkit工具集里的pt-heartbeat工具。这个工具会在主库里创建一个heartbeat表,然后会有一个线程定时更新这个表里的时间戳字段,从库会有一个monitor线程检查主库同步过来的heartbeat表的时间戳,把时间戳跟当前时间戳进行比较,就知道主从同步落后了多长时间了。总之,主从之间延迟了多长时间,实际上是可以看到的。

 

(3)主从同步延迟会导致什么问题

如果做了读写分离架构,写都往主库写,读都从从库读。那么会不会系统刚写入一条数据到主库,接着立即就在从库里读。可能此时从库复制有延迟,导致读不到刚写入的数据,这是经常会遇到的一个问题。

 

另外就是从库同步数据太慢了,导致从库读取的数据都是落后和过期的,也可能会导致系统产生一定的业务上的bug。

 

所以针对主从同步延迟的问题,首先应该做的是尽可能缩小主从同步的延迟时间,就是让从库也用多线程并行复制数据就可以了。这样从库复制数据的速度快了,延迟就会很低了。

 

MySQL 5.7就已经支持并行复制了。可以在从库里设置slave_parallel_workers>0,然后把slave_parallel_type设置为LOGICAL_CLOCK即可。

 

另外如果要求刚写入的数据强制一定读到,那么此时可以使用一个办法:就是类似MyCat或ShardingSphere等中间件设置强制读写都通过主库。这样写入主库的数据,强制从主库里读取,一定可以立即读到的。

 

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

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

相关文章

java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)

java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)@目录说明:基础工具类MsgPageResultResponseBusinessDomainEnum(枚举)EsDocumentConstants(常量)本人其他文章链接 说明:基础工具类Msg package com.geespace.microservices.data.computing.model.…

[MYSQL] MYSQL 时间与时区

MYSQL 版本:MYSQL 5.7.38-221001-logMYSQL 时间与时区概述 GMT(格林尼治标准时间、世界时间) 与 UTC(协调世界时间)‌GMT(Greenwich Mean Time,格林威治标准时间)‌:GMT是基于地球自转和对恒星的观测来定义的时间标准,将地球划分为24个时区。它以英国伦敦郊区的格林尼治天文…

51单片机入门:数码管(3)

数码管简介数码管每段其本质就是个LED灯,只需要控制特定的LED灯亮就能显示数据。普中开发版所使用的是两个并在一起共阴极连接的“4位数码管”,可以同时显示8个数字。数码管的显示可以分成静态显示和动态显示,这里先介绍最简单的静态显示。数码管分为共阴极连接和共阳极连接…

使用java在未知表字段情况下通过sql查询信息

使用java在未知表字段情况下通过sql查询信息场景 在只知道表名,不知道表包含哪些字段情况下,查询该表信息的场景 解决方案 @Testpublic void test() {Connection connection;String DB_URL = "jdbc:mysql://192.168.20.75:9950/geespace_bd_platform_dev?characterEnco…

WnRAR将rar后缀格式文件转成zip后缀格式

前言全局说明使用 winRAR 自带的转换功能,可以最大程度的保留原始信息, 比如: 打包时间、CRC32值等一、说明 环境: Windows 11 家庭版 23H2 22631.3737 WinRAR 6.00(32位)二、rar 转 zip 2.12.2 选择要转换的文件 右边可以根据类型筛选2.3 选择要转成的格式 zip2.4 选择转成输…

opensuse系统下QtCreator中文输入法失效解决,亲测有效

首先安装QTCreator,这里不再详细赘述。克隆fcitx-qt5仓库,然后在该目录下新建build文件 克隆命令如下git clone https://gitcode.com/gh_mirrors/fc/fcitx-qt5.git安装cmakezypper install cmake进入到build目录 运行命令cmake ..报错如下 解决办法 运行如下指令 sudo zypper…

数值分析:线性方程组的直接解法(上)

提纲背景介绍 三角方程组 Gauss消去法 附录一、背景介绍 1.1 线性方程组的相关概念 线性方程组在解决现实师姐问题中直接产生,最小二乘数据拟合、微分方程边值问题和初边值问题的数值解产生了大量的线性方程组。 线性方程组系数矩阵的类型分别有稠密型(dense):几乎所有元素都…

第十三次作业

1、MS08-067、MS10-018漏洞复现,对比bind和reverse攻击模式的区别 MS08-067: 输入msfconsole进入msf终端查找ms08-067漏洞利用模块使用查找出来的攻击模块查看该攻击模块下所需的配置信息设置攻击payload查看并设置靶机地址查看targets选择攻击目标再次检查配置信息关闭目标地…

TIA下SCL做交通灯控制程序完善

和前一篇一样,我希望在没有点击停止按钮时,多次点击开始按钮不要中断当前流程。 在FB程序变量的static组添加BOOL类型running变量。修改SCL程序如下 IF #stopbtn=1 THEN   #CurrentState := 4;   #Running := 0;END_IF; IF (#Running = 0) AND (#startbrn=1) THEN …

【随手记录】IDEA里面pom文件被忽略,变灰、画横线处理

在setting --> Build -->Build Tools --> Maven 下找到ignored files选项,去掉pom文件的勾选框,重新加载项目即可!

大模型问答的工作流程

从问题输入到输出经历五个步骤文本分词: 大模型会将输入文本转化成单词,词语,词组,符号 分词向量化: 将分词转化成向量为了让计算机更好的理解 大模型推理: 推理时大模型会根据输入计算出下一个输出的分词的集合 分词输出: 从推理出来的集合中选择一个分词,将新的结果再进行大模…

[75] (NOIP集训) NOIP2024 加赛 8

A.flandre 我的做法是,所有数离散化之后扔进桶里,去枚举选择 \([i,+\infty)\) 内的数的贡献,在所有的 \(i\) 里取一个最大值作为答案 lbtl 指出可能存在最优答案是选择 \([i+1,+\infty)\) 内的所有数与值为 \(i\) 的部分数的数据 和 lbtl 交涉后尝试构造一组相同元素只选后一…