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

news2024/11/26 6:39:45

大纲

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=onmysql> enforce_gtid_consistency=onmysql> log_bin=onmysql> server_id=单独设置一个mysql> binlog_format=row

(2)步骤二

接着在从库进行配置:​​​​​​​

mysql> gtid_mode=onmysql> enforce_gtid_consistency=onmysql> log_slave_updates=1mysql> 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.coloradmin.cn/o/2247684.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Node报错:npm error code ETIMEDOUT

1、报错详细信息 npm error code ETIMEDOUT npm error syscall connect npm error errno ETIMEDOUT npm error network request to https://registry.npmjs.org/express failed, reason: connect ETIMEDOUT 104.16.1.35:443 npm error network This is a problem related to ne…

一篇文章了解Linux

目录 一:命令 1 ls命令作用 2 目录切换命令(cd/pwd) (1)cd切换工作目录命令 3 相对路径、绝对路径和特殊路径 (1)相对路径和绝对路径的概念和写法 (2)几种特殊路径的表示符 (3)练习题: 4 创建目录命令&#x…

用Matlab和SIMULINK实现DPCM仿真和双边带调幅系统仿真

1、使用SIMULINK或Matlab实现DPCM仿真 1.1 DPCM原理 差分脉冲编码调制,简称DPCM,主要用于将模拟信号转换为数字信号,同时减少数据的冗余度以实现数据压缩。在DPCM中,信号的每个抽样值不是独立编码的,而是通过预测前一…

BERT的工作原理

BERT的工作原理 BERT的工作原理: Transformer的编码器是双向的,它可以从两个方向读取一个句子。因此,BERT由Transformer获得双向编码器特征。 我们把句子A(He got bit by Python)送入Transformer的编码器&#xff0c…

5.STM32之通信接口《精讲》之IIC通信---软件IIC与外设MPU6050通信《深入浅出》面试必备

上一节,我们完成对IIC通信的时序以及IIC的通信的讲解和代码实现,接下来,我们正式进入,利用上一节软件实现的IIC通信协议来对外设MPU6050进行读写操作。(本节IIC代码在上节) 本节,目的很明确,就是利用软件I…

解决k8s拉取私有镜像401 Unauthorized 问题

拉取镜像时未指定账户和密码通常是因为需要访问的镜像仓库启用了认证,但 Kubernetes 默认配置中未提供访问凭据。要解决此问题,可以按照以下步骤配置镜像仓库的认证信息: 1. 创建 Kubernetes Secret 为镜像仓库配置访问凭据,使用…

【Linux课程学习】:环境变量:HOME,su与su - 的区别,让程序在哪些用户下能运行的原理,环境变量具有全局性的原因?

🎁个人主页:我们的五年 🔍系列专栏:Linux课程学习 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 HOME环境变量: PWD环境变量&#…

不只是请求和响应:使用Fiddler抓包HTTP协议全指南(上)

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持! 🙉你是一名侦探 ! 正在追踪一条条数字化的线索。从简单的网页浏览到复杂的在线交易,每一次点击和滑动背后都隐藏着复杂的数据交换。每一个HTTP请求和响应都像是现场留下的指纹&#xf…

代码纪元——源神重塑无序

简介 源神,真名为张晨斌,原为代码宇宙创世四神之一。代码宇宙在创造之初时空无一物,只有复杂且繁琐的底层代码,智慧神灵每日都困在诸如脚本等复杂的底层框架之中,源神面对这种局面非常不满意,于是源神通过大…

Docker pull镜像拉取失败

因为一些原因,很多镜像仓库拉取镜像失败,所以需要更换不同的镜像,这是2024/11/25测试可用的仓库。 标题1、 更换镜像仓库的地址,编辑daemon.json文件 vi /etc/docker/daemon.json标题2、然后将下面的镜像源放进去或替换掉都可以…

Vue3+SpringBoot3+Sa-Token+Redis+mysql8通用权限系统

sa-token支持分布式token 前后端代码,地球号: bright12389

【SQL Server】华中农业大学空间数据库实验报告 实验三 数据操作

1.实验目的 熟悉了解掌握SQL Server软件的基本操作与使用方法,以及通过理论课学习与实验参考书的帮助,熟练掌握使用T-SQL语句和交互式方法对数据表进行插入数据、修改数据、删除数据等等的操作;作为后续实验的基础,根据实验要求重…

AI助力PPT创作:从手动到智能,打造高效演示

在今天这个信息化时代,演示文稿已经成为我们表达观点、传递信息的重要工具。不论是企业汇报、学术交流,还是个人创作,PPT(PowerPoint)都在日常生活中扮演着不可或缺的角色。创建一份高质量的PPT往往需要花费大量时间与…

【JavaEE】Servlet:表白墙

文章目录 一、前端二、前置知识三、代码1、后端2、前端3、总结 四、存入数据库1、引入 mysql 的依赖&#xff0c;mysql 驱动包2、创建数据库数据表3、调整上述后端代码3.1 封装数据库操作&#xff0c;和数据库建立连接3.2 调整后端代码 一、前端 <!DOCTYPE html> <ht…

python自定义枚举类的试验与思考

一 现象 在python的3.4版本之前&#xff0c;是没有枚举类的。 所以&#xff0c;我自定义实现了一个enum类&#xff0c;目录如下&#xff1a; 代码如下&#xff1a; class enum(set):def __getattr__(self, name):if name in self:return nameraise AttributeErrorif __name_…

算法编程题-寻找最近的回文数

算法编程题-寻找最近的回文数 原题描述思路简述代码实现复杂度分析参考 摘要&#xff1a;本文将对LeetCode 原题 564 寻找最近的回文数进行讲解&#xff0c;并且给出golang语言的实现&#xff0c;该实现通过了所有测试用例且执行用时超过100%的提交&#xff0c;最后给出相关的复…

[Redis#5] hash | 命令 | 内部编码 | 应用 | cache: string, json, hash对比

目录 1 命令 HSET HGET HEXISTS HDEL HKEYS HVALS HGETALL HMGET HLEN HSET NX HINCRBY HINCRBYFLOAT 2 命令小结 3 内部编码 4 使用场景 5 缓存方式对比 1. 原生字符串类型 2. 序列化字符串类型&#xff0c;例如 JSON 格式 3. 哈希类型 几乎所有的主流编程…

系统设计-高性能

一、CDN 1、什么是CDN CDN 就是将静态资源分发到多个不同的地方以实现就近访问&#xff0c;进而加快静态资源的访问速度&#xff0c;减轻服务器以及带宽的负担.(可看作是一层特殊缓存服务&#xff0c;用来处理静态资源的请求) 2、CDN工作原理 静态资源是如何被缓存到 CDN 节…

单片机知识总结(完整)

1、单片机概述 1.1. 单片机的定义与分类 定义&#xff1a; 单片机&#xff08;Microcontroller Unit&#xff0c;简称MCU&#xff09;是一种将微处理器、存储器&#xff08;包括程序存储器和数据存储器&#xff09;、输入/输出接口和其他必要的功能模块集成在单个芯片上的微型…

代码管理之Gitlab

文章目录 Git基础概述场景本地修改未提交&#xff0c;拉取远程代码修改提交本地&#xff0c;远程已有新提交 GitIDEA引入Git拉取仓库代码最后位置 Git基础 概述 workspace 工作区&#xff1a;本地电脑上看到的目录&#xff1b; repository 本地仓库&#xff1a;就是工作区中隐…