Mysql-主从架构篇(一主多从,半同步案例搭建)

news2024/11/15 20:46:37

主从架构

主从架构有什么用?

通过搭建MySQL主从集群,可以缓解MySQL的数据存储以及访问的压力。

  1. 数据安全(主备):给主服务增加一个数据备份。基于这个目的,可以搭建主从架构,或者也可以基于主从架构搭建互主的架构。
  2. 读写分离(主从):对于大部分的Java业务系统来说,都是读多写少的,读请求远远高于写请求。这时,当主服务的访问压力过大时,可以将数据读请求转为由从服务来分担,主服务只负责数据写入的请求,这样大大缓解数据库的访问压力。
    注意:我们不能对备份的的节点进行写操作只能进行读,我们写入一定是写入主节点
  3. 故障转移-高可用:当MySQL主服务宕机后,可以由一台从服务切换成为主服务,继续提供数据读
    写功能。
    对于高可用架构,主从数据的同步也只是实现故障转移的一个前提条件,要实现MySQL主从切换,
    还需要依靠一些其他的中间件来实现。比如MMM、MHA、MGR。
主从架构原理

在这里插入图片描述
具体流程如下:

  • 在主服务上打开binlog记录每一步的数据库操作
  • 然后,从服务上会有一个IO线程,负责跟主服务建立一个TCP连接,请求主服务将binlog传输过来
  • 这时,主库上会有一个IO dump线程,负责通过这个TCP连接把binlog日志传输给从库的IO线程
  • 主服务器MySQL服务将所有的写操作记录在 binlog 日志中,并生成 log dump 线程,将 binlog 日志传给从服务器MySQL服务的 I/O 线程。
  • 接着从服务的IO线程会把读取到的binlog日志数据写入自己的relay日志文件中。
  • 然后从服务上另外一个SQL线程会读取relay日志里的内容,进行操作重演,达到还原数据的目的。

注意:

  • 主从复制是异步的逻辑的 SQL 语句级的复制
  • 复制时,主库有一个 I/O 线程,从库有两个线程,即 I/O 和 SQL 线程
  • 实现主从复制的必要条件是主库要开启记录 binlog 的功能
  • 作为复制的所有 MySQL 节点的 server-id 都不能相同
  • binlog 文件只记录对数据内容有更改的 SQL 语句,不记录任何查询语句
  • 双方MySQL必须版本一致,至少需要主服务的版本低于从服务
  • 两节点间的时间需要同步
主从复制形式

1 一主一从
在这里插入图片描述
2 主主复制
存在数据一致性问题,可以提高读写能力。
在这里插入图片描述
3 一主多从
在这里插入图片描述
4 多主一从(mysql5.7以后)
在这里插入图片描述
主一从的MySQL主从同步集群,具有了数据同步的基础功能。而在生产环境中,通常会以此为基础,根据业务情况以及负载情况,搭建更大更复杂的集群,掌握了一主一从的搭建方式,其它的方式就好弄了。
互主集群:我们也可以扩展出互为主从的互主集群甚至是环形的主从集群,实现多活部署。
5 联级复制
降低主从同步的延迟,降低主服务器的压力,因为同步也是要消耗资源的。

在这里插入图片描述

案例实战

一主一从

首先配置主服务器

[mysqld]
# binlog刷盘策略
sync_binlog=1
# 需要备份的数据库
binlog-do-db=hello
# 不需要备份的数据库
binlog-ignore-db=mysql
# 启动二进制文件
log-bin=mysql-bin
# 服务器ID
server-id=132
#设置错误日志输出路径
log-error=/var/lib/logs/log-err.log
log_warnings=1
#慢查询相关日志
log_output=FILE
slow_query_log=1
long_query_time=10
slow_query_log_file=/var/lib/logs/slow_query_log.log
#记录没有使用到索引的sql语句
log_queries_not_using_indexes=ON

创建用于同步的用户

#需要保证mysql-slave 主机名能够被解析
CREATE USER 'slave' @'mysql-slave' IDENTIFIED BY '654321';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave' @'mysql-slave';
docker run -d -p 3306:3306  -v $(pwd)/logs:/var/lib/logs  -v $(pwd)/conf:/etc/mysql/conf.d  -v $(pwd)/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=654321  --name mysql-master mysql:5.7
show master status;

在这里插入图片描述
创建从数据库

[mysqld]
server-id=133
#设置错误日志输出路径
log-error=/var/lib/logs/log-err.log
log_warnings=1
#慢查询相关日志
log_output=FILE
slow_query_log=1
long_query_time=10
slow_query_log_file=/var/lib/logs/slow_query_log.log
#记录没有使用到索引的sql语句
log_queries_not_using_indexes=ON
#--link 这样从数据库可以直接和主数据库通信 原理就是在从数据库hosts文件里加了容器的端口映射并且和容器进行绑定
docker run -d -p 13306:13306 --link=mysql:msql-master -v $(pwd)/logs:/var/lib/logs  -v $(pwd)/conf:/etc/mysql/conf.d  -v $(pwd)/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=654321  --name mysql-slave mysql:5.7
change master to
master_host='myql-master',
master_port=3306,
master_user='slave',
master_password='654321',
master_log_file='mysql-bin.000004',
#这个值一定要填我上面 show master status 中的偏移值
master_log_pos=6316,
MASTER_AUTO_POSITION=0;
start slave;
show slave status \G;

在这里插入图片描述
验证这个时候我们去主库间插入数据,就会被同步到从库。

基于主从复制有这样几个问题:
1 如果我们部署的是一主多从,这个时候如果主节点挂掉了,需要从节点变为主节点是一件麻烦的事情,并且丢失了很多数据。
2 同步有延迟或者同步丢失。

基于GTID的主从复制

什么是GTID?
从 MySQL 5.6.5 开始新增了一种基于 GTID 的复制方式。GTID即全局事务ID (Global TransactionIdentifier),其保证每个主节点上提交的事务,在从节点可以一致性的复制。
这种方式强化了数据库的主备一致性,故障恢复以及容错能力。GTID在一主一从情况下没有优势,对于两主以上的结构优势异常明显,可以在数据不丢失的情况下切换新主
GTID实际上是由UUID+TID (即transactionId)组成的,其中UUID(即server_uuid) 产生于auto.conf文件,是一个MySQL实例的唯一标识。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增,所以GTID能够保证每个MySQL实例事务的执行。GTID在一组复制中,全局唯一。 通过GTID的UUID可以知道这个事务在哪个实例上提交的。
GTID的优势

  • GTID相对于binlog+pos 复制数据安全性更高、failover更简单、搭建主从复制更简单
    • 实现 failover不用像binlog+pos 复制那样需要找 log_file 和 log_pos
    • 一个 GTID 在一个node上只执行一次,避免重复执行导致数据混乱或者主从不一致
  • 根据 GTID 可以快速的确定事务最初是在哪个实例上提交
  • 使得 DBA 在运维中做集群变迁时更加方便
    注意事项
  • 在一个复制组中必须要求统一开启GTID或是关闭GTID
  • 主从库的表存储引擎必须是一致,不允许一个SQL同时更新一个事务引擎和非事务引擎的表
  • MySQL在主从复制时如果要跳过报错,可以采取以下方式跳过SQL(event)组成的事务,但GTID不支持以下方式(也就是说GTID不支持跳过报错)
set global SQL_SLAVE_SKIP_COUNTER=1;
start slave sql_thread;
  • 不支持下面语句的复制(主库直接报错)
    create table….select
    create temporary table
    drop temporary table

GTID 主从复制原理
在这里插入图片描述

  1. Master更新数据时,会在事务前产生GTID一同记录到binlog日志中
  2. Slave的IO Thread将变更后的binlog写入到本地的relaylog中,这其中含有Master的GTID
  3. SQL Thread读取这个 GTID 的值并设置 GTID_NEXT变量,告诉 Slave下一个要执行的 GTID 值,然后对比 Slave 端的 binlog 是否有该 GTID
    • 如果有,说明该 GTID 的事务已经执行 Slave 会忽略
    • 如果没有,Slave 就会执行该 GTID 事务,并记录该 GTID 到自身的 binlog
  4. 在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有二级索引就用全表扫描

在使用GTID的时候如果这个时候一主多从,切换从节点为主节点非常的方便,我们可以找到数据较为完整的Server。由于MASTER_AUTO_POSITION功能的出现,我们都不需要知道GTID的具体值,直接使用
CHANGE MASTER TO MASTER_HOST=‘xxx’,MASTER_AUTO_POSITION命令就可以直接完成failover的工作。
注意:在我们切换完Master以后不要在这个数据库上进行一些操作,例如更新和删除数据,因为这部分事务到时候会同步到从节点,万一操作错了,从节点的数据也被刷新了,容易导致数据出问题。

下面我们基于上面的一主一从来搭建GTID主从(直接搭建一主多从,需要重启):
主节点的配置

[mysqld]
server-id=133
#设置错误日志输出路径
log-error=/var/lib/logs/log-err.log
log_warnings=1
#开启gtid
gtid_mode=on
enforce_gtid_consistency=on
# 做级联复制的时候,再开启。允许下端接入slave
log_slave_updates=1
#慢查询相关日志
log_output=FILE
slow_query_log=1
long_query_time=10
slow_query_log_file=/var/lib/logs/slow_query_log.log
#记录没有使用到索引的sql语句
log_queries_not_using_indexes=ON

#查看服务器的UUID 
cat /var/lib/mysql/auto.cnf
#可以才看到GTID 是UUID + 事务ID
show master status;

在这里插入图片描述
从服务器
由于我们之前已经有数据了所以我们要,先把数据迁移过来。

#备份
mysqldump -u root -p --all-databases > backup.sql 
#导入
mysql -uroot -p < backup.sql
[mysqld]
# binlog刷盘策略
sync_binlog=1
# 需要备份的数据库
binlog-do-db=hello
# 不需要备份的数据库
binlog-ignore-db=mysql
# 启动二进制文件
log-bin=mysql-bin
# 服务器ID
server-id=132
#设置错误日志输出路径
log-error=/var/lib/logs/log-err.log
log_warnings=1
#慢查询相关日志
log_output=FILE
slow_query_log=1
long_query_time=10
slow_query_log_file=/var/lib/logs/slow_query_log.log
#记录没有使用到索引的sql语句
log_queries_not_using_indexes=ON
gtid_mode=on
enforce_gtid_consistency=on
# 强烈建议,其他格式可能造成数据不一致
binlog_format=row
change master to
master_host='mysql-master',
master_port=3306,
master_user='slave',
master_password='654321',
MASTER_AUTO_POSITION=1;

另一个服务器一样的操作,记得一定要修改server-id。接着去验证是否同步即可。
在这里插入图片描述

半同步复制机制

1)异步复制
MySQL主从集群默认采用的是一种异步复制的机制。
主服务在执行用户提交的事务后,写入binlog日志,然后就给客户端返回一个成功的响应了。而binlog
会由一个dump线程异步发送给Slave从服务。由于这个发送binlog的过程是异步的。主服务在向客户端
反馈执行结果时,是不知道binlog是否同步成功了的。这时候如果主服务宕机了,而从服务还没有备份
到新执行的binlog,那就有可能会丢数据。
在这里插入图片描述
2)半同步复制
半同步复制机制是一种介于异步复制和全同步复制之前的机制。
主库在执行完客户端提交的事务后,并不是立即返回客户端响应,而是等待至少一个从库接收并写到relaylog中,才会返回给客户端。
MySQL在等待确认时,默认会等 10 秒,如果超过10秒没有收到ack,就会降级成为 异步复制 。
在这里插入图片描述

这种半同步复制相比异步复制,能够有效的提高数据的安全性。但是这种安全性也不是绝对的,他只保证事务提交后的binlog至少传输到了一个从库,且并不保证从库应用这个事务的binlog是成功的。另一方面,半同步复制机制也会造成一定程度的延迟,这个延迟时间最少是一个TCP/IP请求往返的时间。整个服务的性能是会有所下降的。而当从服务出现问题时,主服务需要等待的时间就会更长,要等到从服务的服务恢复或者请求超时才能给用户响应。

案例搭建

我们基于上面的GTID一主两从来搭建,只需要在这个基础上加上半同步机制就行。

#查看当前数据库是否支持 版同步机制 
select @@have_dynamic_loading;

在这里插入图片描述

#查看插件的位置
show variables like 'plugin_dir';
安装插件

主机节点

install plugin rpl_semi_sync_master soname 'semisync_master.so';
#查看半同步机制的参数
show global variables like 'rpl_semi%';
#开半同步机制
set global rpl_semi_sync_master_enabled=ON;
# 单位是毫秒,可动态调整,表示主库事务等待从库返回commit成功信息超过30秒就降为异步模式,
set global rpl_semi_sync_master_timeout=30000;
#查看插件是否搭建成功了
select * from mysql.plugin;
#监控状态
show status like 'rpl_semi_sync%';

在这里插入图片描述

半同步复制有两种方式,rpl_semi_sync_master_wait_point通过这个参数指定:

  • AFTER_SYNC 方式:默认,主库把日志写入binlog并且复制给从库,然后开始等待从库的响应。从库返回成功后,主库再提交事务,接着给客户端返回一个成功响应性能更差,安全性更好。
  • AFTER_COMMIT 方式:主库把日志写入binlog并且复制给从库,主库就提交自己的本地事务,再等待从库返回给自己一个成功响应,等到响应后主库再给客户端返回响应。性能更好,安全性较差区别:提交事务的时机不同。

安装从节点的插件

install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
#开启半同步
set global rpl_semi_sync_slave_enabled = on;
#监控状态
show status like 'rpl_semi_sync%';

验证停止其中的一个节点

stop slave io_thread;
#下面插入一条数据然后看半同步状态

在这里插入图片描述

#恢复
start slave;

在这里插入图片描述

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

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

相关文章

00x集—二维轻量多线段LWpolyline设置凸度bulge——vba实现

本文主要讲LightweightPolyline ,即轻量多段线。 LightweightPolyline (每一顶点用2个元素表示,数组大小必须为2的倍数)对象, 而对比polyline(每一顶点用三个元素表示,数组大小必须为3的倍数) 优化多段线&#xff08;轻量多段线&#xff09;&#xff0c;由线和弧段组成的可调节…

第三十周:文献阅读

第三十周&#xff1a;综述阅读文献阅读pytorch学习 摘要Abstract1. 深度可分离卷积1.1 文献摘要1.2 引言1.3 Inception 模块1.4 Inception模块与深度可分离卷积的差别1.5 Xception架构1.6 实验1.7 总结1.8 创新点 摘要 深度可分离卷积是一种卷积神经网络&#xff08;CNN&#…

【Linux】线程概念|线程理解|线程控制

文章目录 线程概念Linux中线程是否存在的讨论线程创建和线程控制线程的终止和等待&#xff08;三种终止方式 pthread_join()的void**retval&#xff09; 线程概念 线程就是进程内部的一个执行流&#xff0c;线程在进程内运行&#xff0c;线程在进程的地址空间内运行&#xff0…

【c++】继承深度解剖

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么事继承&#xff0c;基类和派生类的使用和…

启动CMD/powershell命令窗口时,设置默认的python虚拟环境 in window10

启动CMD/powershell命令窗口时&#xff0c;设置默认的python虚拟环境 in window10 本文有两个目的&#xff1a; CMD命令窗口&#xff0c; 设置默认启动的python环境PowerShell命令窗口&#xff0c; 设置默认启动的python环境 CMD命令窗口&#xff0c; 设置默认启动的python环…

企业计算机服务器中了360勒索病毒如何解密,360后缀勒索病毒处理流程

对于众多的企业来说&#xff0c;企业的数据是企业发展的核心&#xff0c;越来越多的企业开始注重企业的数据安全问题&#xff0c;但随着网络技术的不断发展与应用&#xff0c;网络黑客的攻击加密手段也在不断升级。近期&#xff0c;云天数据恢复中心接到多家企业的求助&#xf…

PDN分析及应用系列二-简单5V电源分配-Altium Designer仿真分析-AD

PDN分析及应用系列二 —— 案例1:简单5V电源分配 预模拟DC网络识别 当最初为PCB设计打开PDN分析仪时,它将尝试根据公共电源网络命名法从设计中识别所有直流电源网络。 正确的DC网络识别对于获得最准确的模拟结果非常重要。 在示例项目中已经识别出主DC网络以简化该过程。 …

人工智能之Tensorflow程序结构

TensorFlow作为分布式机器学习平台&#xff0c;主要架构如下&#xff1a; 网络层&#xff1a;远程过程调用(gRPC)和远程直接数据存取(RDMA)作为网络层&#xff0c;主要负责传递神经网络算法参数。 设备层&#xff1a;CPU、GPU等设备&#xff0c;主要负责神经网络算法中具体的运…

【旧文搬运】为你的 Laravel 应用添加一个基于 Swoole 的 WebSocket 服务

做了一个基于 Swoole 的 WebSocket 扩展包&#xff0c;可以用来做实时状态推送&#xff0c;或者自定义消息处理实现 im&#xff0c;有需要的可以看看: [giorgio-socket] 使用方法 安装 安装扩展包 composer require wu/giorgio-socket发布配置文件 php artisan vendor:pu…

可莉炸鱼

情况有s*k>n&#xff0c;最多炸鱼数为n s*k<n&#xff0c;最多炸鱼数为s*k 将s*k转化为k个s相加&#xff0c;每次结果与n比较 #include<iostream> #include<vector> #include<algorithm> using namespace std; #define endl \n #define ll long lon…

Java---文件,流✨❤️

文章目录 1.遍历文件夹2.遍历子文件夹3.练习流4.以字节流的形式读取文件内容5.以字节流的形式向文件写入数据顶折纠问6 .写入数据到文件 1.遍历文件夹 一般说来操作系统都会安装在C盘&#xff0c;所以会有一个 C:\WINDOWS目录。 遍历这个目录下所有的文件(不用遍历子目录) 找出…

pyqt5怎么返回错误信息给页面(警告窗口)

在软件设计中&#xff0c;我们可能会遇到对异常的处理&#xff0c;有些异常是用户需要看到的&#xff0c;比如说&#xff0c;当我们登录出错的时候&#xff0c;后端需要给我们返回响应的错误信息&#xff0c;就像下图实现的这样。 类似这种效果&#xff0c;我们该如何实现&…

选择何种操作系统作为网站服务器

选择操作系统时&#xff0c;需考虑稳定性、安全性、成本、兼容性和技术支持等因素&#xff0c;常见选项有Windows Server和Linux发行版。 选择网站服务器的操作系统是一个关键的决策&#xff0c;因为它将影响到网站的性能、稳定性、安全性以及未来的扩展性&#xff0c;目前市场…

ES向量功能实战:向量搜索

1 缘起 项目需要&#xff0c;向量搜索使用ES&#xff0c;为了顺利使项目顺利交付&#xff0c;开始学习ES的稠密向量功能&#xff0c;本文即ES向量的实践&#xff1a;增删查改。ES从7.x版本支持向量功能&#xff0c;为测试ES向量功能&#xff0c;需要使用7.x及以上的版本。本文…

算法刷题day20:二分

目录 引言概念一、借教室二、分巧克力三、管道四、技能升级五、冶炼金属六、数的范围七、最佳牛围栏 引言 这几天一直在做二分的题&#xff0c;都是上了难度的题目&#xff0c;本来以为自己的二分水平已经非常熟悉了&#xff0c;没想到还是糊涂了一两天才重新想清楚&#xff0…

vue3 vite项目一运行就401(Unauthorized)

问题&#xff1a;项目一执行&#xff1a; pnpm run dev, 启动就出错&#xff0c; Failed to load resource: the server responded with a status of 401 (Unauthorized) 分析&#xff1a; 项目之前是正常运行的&#xff0c;没有问题&#xff0c;回溯刚刚改动&#xff0c;还原…

W5300驱动说明

W5300是一款带有硬件协议栈的网络芯片&#xff0c;内部拥有128K的缓存&#xff0c;最大支持8路socket通信&#xff0c;与MCU之间通过16位数据总线通信&#xff0c;通信速度远超W5500之类以SPI作为通信接口的网络芯片&#xff0c;特别适合对高速网络传输有需求的应用。 本次使用…

基于springboot+vue的疫苗发布和接种预约系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

关于工业 24V 电源转换电路参考设计

一. 概述 在工业邻域的应用中&#xff0c;部分电路板输入电源为 24V&#xff0c;而电路板上 MCU 及外设等的供电多为 3.3V、5V 以及 12V&#xff0c;因此设计将 24V 降压转换为各种电压非常有必要。常用的电源转换芯片有 DCDC 及 LDO 等&#xff0c;了解选型依据及其电路…

DolphinScheduler——调度系统数仓任务编排规范

原文大佬的这篇DS数仓任务编排规范有借鉴意义&#xff0c;这里摘抄下来用作学习和知识沉淀。 前言 在使用DolphinScheduler&#xff08;以下简称DS&#xff09;做数仓任务管理时&#xff0c;数据建模分层落地到调度上缺少规范&#xff0c;往往比较随意&#xff0c;例如将所有任…