谈谈mysql——主从模式下的同步方式及半同步、MGR的部署方式

news2024/9/28 15:19:02

MySQL的复制模式

异步复制

MySQL的复制方式默认是异步的,主从复制涉及三个线程

  • master I/O
    master I/O线程负责写入Binlog,并将执行结果返给客户端,至于Binlog有没有被IO线程读取,读取后有没有重放,重放有没有成功,它是不关心的。
  • slave I/O线程
    负责将读取master的Binlog并写入slave的relay log(中继日志)
  • slave sql线程
    在slave重放relay log中的event,MySQL5.6以后支持并行复制,所谓并行复制,指的是从库开启多个SQL线程,并行读取relay log中不同库的日志,然后并行重放不同库的日志,这是库级别的并行。而MySQL 5.7版本对并行复制进一步改进,已经支持“真正”的并行复制功能,是基于组提交的并行复制,一个组提交的事务都是可以并行回放,官方称为enhanced multi-threaded slave(简称MTS),复制延迟问题已经得到了极大的改进。

在这里插入图片描述

这种模式在高并发的情况下,master只负责写Binlog和返回结果,至于Binlog有没有被读取和重放,它是不关心的,那么这就可能就发生主从延迟的问题。或者master宕机后,slave升级为master,但是binlog未执行完毕,就会导致数据不一致。

这里讲一个小技巧,为了减少主从延迟的问题,主库和备库的硬件性能尽可能保持一致,如果主备硬件差距比较大,从主从延迟的角度上看,应该在性能更好的机器上面安装备库。如果给主库用更好的硬件,那延迟只会越来越大。

半同步复制

为了解决异步存在的问题,MySQL5.5版本推出半同步复制,在master执行完毕后,commit之前,slave的io进程开始把Binlog写入到relaylog中,写完之后,反馈给master,master收到任何一个slave的反馈后,执行commit并返回结果给客户端。半同步的机制减少了主从数据不同步的问题,但是也牺牲了一部分主库的性能,比异步复制至少多了一个tcp的往返时间。

如果在更新期间,主从库发生了网络故障或者从库宕机,那么此时主库在事务提交后会等待10秒(默认值),如果10秒内还是不能联系到该从库,就会放弃更新该从库,并向用户返回数据。这时主从库就会恢复到默认的异步复制状态。
在这里插入图片描述

同步复制【不推荐】

全同步复制(full sync replication)是指当主库执行完一个事务后,需要确保所有的从库都执行了该事务才返回给客户端。因为需要等待所有的从库都执行完该事务才能返回,所以全同步复制的性能较差。
MySQL自身不支持同步复制,需要用到第三方工具如DRBD(sync模式)等实现同步复制,严格来说,把半同步复制技术默认(或人为)全部应用到所有从库上也算是全同步复制。

MGR组复制

MGR(MySQL GroupReplication)是MySQL 5.7.17提出的,MGR既可以很好的保证数据一致性又可以自动切换,具备故障检测功能、支持多节点写入.MGR (MySQL Group Replication)是MySQL自带的一个插件,可以灵活部署。MySQL MGR集群是多个MySQL Server节点共同组成的分布式集群,每个Server都有完整的副本,它是基于ROW格式的二进制日志文件和GTID特性。架构主要是APIs层、组件层、复制协议模块层和GCSAPI+Paxos引擎层构成。

MGR的解决的问题
  • 高可用性:由于数据在多个服务器之间复制,因此即使某个服务器出现故障,也不会影响到整体的服务。
  • 数据一致性:MGR使用了一种称为“多数派”或“半数以上”的策略来保证数据的一致性。只有当大多数服务器都确认了一次操作,这次操作才会被视为有效。
  • 负载均衡:MGR允许你将读取操作在多个服务器之间分配,从而实现负载均衡。
MGR带来的问题
  • 写入性能:由于需要在多个服务器之间复制数据,因此写入操作可能会比在单个服务器上执行慢。
  • 网络延迟:如果服务器之间的网络连接不稳定或者延迟高,可能会影响到MGR的性能和可靠性。
  • 管理复杂性:管理和维护一个MGR集群可能会比管理单个服务器更复杂。

如何减少主从延迟的问题

  • 查主库
    这是我们目前使用的方法,当要求数据一致性的时候,先写主库,再读主库,比如插入订单表之后要马上查询订单的信息。
  • 分库
    原来一个库的并发是400/s,我们把一个库拆分为4个库后,每个库的并发就可以平均到100/s(这个拆分,不是让你把表平均分了,而是要根据业务量拆分,使得每个库都能得到合理的访问量)
  • 硬件设备尽可能保持一致,网络延迟短
  • 开启并行复制。启动多个SQL线程处理relaylog

动手实现半同步和MGR

半同步复制的安装

  • 查看动态加载是否为true 执行命令show variables like "have_dynamic_loading";
  • 安装插件,在master执行INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';,在slave执行INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
  • 如需卸载(就是关闭半同步),则分别执行UNINSTALL PLUGIN rpl_semi_sync_master;UNINSTALL PLUGIN rpl_semi_sync_slave;
  • 执行SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%semi%';查看插件是否启用
    在这里插入图片描述
  • MySQL默认是异步的,我们通过命令SET GLOBAL rpl_semi_sync_master_enabled = 1;开启半同步,在slave执行SET GLOBAL rpl_semi_sync_slave_enabled = 1;
  • 也可以配置在my.cnf文件中
#master配置
plugin-load=rpl_semi_sync_master=semisync_master.so
rpl_semi_sync_master_enabled=1

# slave配置
plugin-load=rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_slave_enabled=1

  • 重新启动slave的IO thread
mysql> STOP SLAVE IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.03 sec)

mysql> START SLAVE IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.01 sec)
  • 查看半同步的状态,在master执行show status like 'Rpl_semi_sync_master_status';,在slave执行show status like 'Rpl_semi_sync_slave_status';
  • 我们前面说过,超过10s的话半同步就会降级为异步,那么这个10s哪来的呢?我们执行show variables like "rpl_semi_sync_master_timeout";来看一下
    在这里插入图片描述
  • 我们插入一条记录到user表看一下
    在这里插入图片描述
  • 接下来我们看看,如果停了slave,master会不会降级为异步。从库执行命令stop slave;主库插入数据,发现执行插入语句后一直等待,10s后返回结果,查看主库的半同步状态show status like 'Rpl_semi_sync_master_status';和从库的状态show status like 'Rpl_semi_sync_slave_status';已经关闭
    在这里插入图片描述
  • 在slave执行start slave; 半同步状态将会再次开启;
其他参数说明
  • 我们通过show variables like '%Rpl%';show status like '%Rpl_semi%';可以看到其他的参数

  • rpl_semi_sync_master_wait_for_slave_count: MySQL 5.7.3引入的,该变量设置主需要等待多少个slave应答,才能返回给客户端,默认为1。

MGR的相关配置

  • 以下配置是基于MySQL8.0
    上篇文章我们使用docker创建了两个MySQL服务,那么在这个案例中,我们还是使用docker快速启动三个服务,在启动前,我们先来看一下需要配置哪些项,我们拿一个配置文件作为参考

#  指定了服务器的唯一标识符,用于复制或群组复制。每个服务器必须有一个不同的server_id值
server_id=1

#  启用了全局事务标识符(GTID)模式,这是一种复制模式,可以跟踪每个事务的执行情况,而不需要使用二进制日志文件名和位置
gtid_mode=ON

#  强制GTID模式的一致性,即只允许那些可以安全地使用GTID复制的语句执行
enforce_gtid_consistency=ON

#  禁用了二进制日志的校验和功能,即不在二进制日志事件中添加额外的数据来验证事件的完整性
binlog_checksum=NONE
 
#  启用了二进制日志,并指定了二进制日志文件的基本名称为binlog
log_bin=binlog

#  使得从服务器在接收到主服务器的更新后,也将这些更新记录到自己的二进制日志中,这对于链式复制或备份从服务器很有用
log_slave_updates=ON

#  指定了二进制日志的格式为行格式,即记录每个被修改的行的变化,而不是记录执行的语句
binlog_format=ROW

#  指定了从服务器存储主服务器信息(如主服务器的主机名、端口号、用户名、密码等)的位置为一个表(mysql.slave_master_info),而不是一个文件(master.info)
master_info_repository=TABLE

#  指定了从服务器存储中继日志信息(如当前正在执行的中继日志文件名和位置等)的位置为一个表(mysql.slave_relay_log_info),而不是一个文件(relay-log.info)
relay_log_info_repository=TABLE
 
#  指定了事务写集提取算法为XXHASH64,这是一种快速的哈希算法,用于生成每个事务写集的唯一标识符,以便在群组复制中检测和避免冲突
transaction_write_set_extraction=XXHASH64

#  指定了群组复制中的群组名称,它是一个128位的无符号整数,用16进制表示,用于标识一个复制群组。所有参与群组复制的服务器必须使用相同的群组名称
loose-group_replication_group_name="aadaaaaa-adda-adda-aaaa-aaaaaaddaaaa"

#  指定了服务器启动时是否自动启动群组复制插件。如果设置为OFF,则需要手动执行START GROUP_REPLICATION语句来启动群组复制
loose-group_replication_start_on_boot=OFF

#  指定了本地服务器在群组复制中使用的地址,包括IP地址和端口号。这个地址用于与其他群组成员通信
loose-group_replication_local_address= "172.17.0.2:13308"

#  指定了一组种子地址,用于在启动群组复制时发现其他群组成员。这些地址可以是本地服务器或远程服务器的地址
loose-group_replication_group_seeds= "172.17.0.2:13308,172.17.0.3:13309,172.17.0.4:13310"

#  指定了是否将本地服务器作为引导服务器,用于创建一个新的群组或恢复一个已有的群组。只有在没有其他可用的群组成员时,才需要设置这个参数为ON
loose-group_replication_bootstrap_group=OFF;

  • 我们创建一个专门的网络,用来连接各个容器
$ docker network create mysql_mgr
$ docker network ls
  • 我们需要MySQL对外服务的端口,还需要群组复制使用的端口,那么我们改一下我们的docker启动命令,我们先来启动一个mysql-c,创建目录mysqlc ,进入目录并执行
docker run -d --name mysql-c -p 23308:3306   \
--net=mysql_mgr \
-v $(pwd)/conf:/etc/mysql/conf.d \
-v $(pwd)/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
mysql

  • 创建目录mysqld并执行
docker run -d --name mysql-d -p 23309:3306   \
--net=mysql_mgr \
-v $(pwd)/conf:/etc/mysql/conf.d \
-v $(pwd)/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
mysql
  • 创建目录mysqle并执行
docker run -d --name mysql-e -p 23310:3306   \
--net=mysql_mgr \
-v $(pwd)/conf:/etc/mysql/conf.d \
-v $(pwd)/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
mysql
  • 使用下面命令找到容器对应的ip
$ docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysql-c
/mysql-c - 172.17.0.2

  • 我们参照上面的配置文件配置自己my.cnf,并重启docker容器,如果你忘记了my.cnf的目录,可以使用mysql --help | grep "my.cnf"查看my.cnf的目录
[mysqld]
#  指定了服务器的唯一标识符,用于复制或群组复制。每个服务器必须有一个不同的server_id值
server_id=3

#  启用了全局事务标识符(GTID)模式,这是一种复制模式,可以跟踪每个事务的执行情况,而不需要使用二进制日志文件名和位置
gtid_mode=ON

#  强制GTID模式的一致性,即只允许那些可以安全地使用GTID复制的语句执行
enforce_gtid_consistency=ON

#  禁用了二进制日志的校验和功能,即不在二进制日志事件中添加额外的数据来验证事件的完整性
binlog_checksum=NONE
 
#  启用了二进制日志,并指定了二进制日志文件的基本名称为binlog
log_bin=binlog

#  使得从服务器在接收到主服务器的更新后,也将这些更新记录到自己的二进制日志中,这对于链式复制或备份从服务器很有用
log_slave_updates=ON

#  指定了二进制日志的格式为行格式,即记录每个被修改的行的变化,而不是记录执行的语句
binlog_format=ROW

#  指定了从服务器存储主服务器信息(如主服务器的主机名、端口号、用户名、密码等)的位置为一个表(mysql.slave_master_info),而不是一个文件(master.info)
master_info_repository=TABLE

#  指定了从服务器存储中继日志信息(如当前正在执行的中继日志文件名和位置等)的位置为一个表(mysql.slave_relay_log_info),而不是一个文件(relay-log.info)
relay_log_info_repository=TABLE
 
#  指定了事务写集提取算法为XXHASH64,这是一种快速的哈希算法,用于生成每个事务写集的唯一标识符,以便在群组复制中检测和避免冲突
transaction_write_set_extraction=XXHASH64

#  指定了群组复制中的群组名称,它是一个128位的无符号整数,用16进制表示,用于标识一个复制群组。所有参与群组复制的服务器必须使用相同的群组名称
loose-group_replication_group_name="aadaaaaa-adda-adda-aaaa-aaaaaaddaaaa"

#  指定了服务器启动时是否自动启动群组复制插件。如果设置为OFF,则需要手动执行START GROUP_REPLICATION语句来启动群组复制
loose-group_replication_start_on_boot=OFF

#  指定了本地服务器在群组复制中使用的地址,包括IP地址和端口号。这个地址用于与其他群组成员通信
loose-group_replication_local_address= "172.21.0.4:13308"

#  指定了一组种子地址,用于在启动群组复制时发现其他群组成员。这些地址可以是本地服务器或远程服务器的地址
loose-group_replication_group_seeds= "172.21.0.2:13306,172.21.0.3:13307,172.21.0.4:13308"

#  指定了是否将本地服务器作为引导服务器,用于创建一个新的群组或恢复一个已有的群组。只有在没有其他可用的群组成员时,才需要设置这个参数为ON
loose-group_replication_bootstrap_group=OFF;
# 修改MySQL8的验证插件为mysql_native_password
default_authentication_plugin=mysql_native_password
  • 进入容器执行以下命令(每个机器都要操作)
SET SQL_LOG_BIN=0;
CREATE USER mgruser@'%' IDENTIFIED BY 'mgruser';
GRANT REPLICATION SLAVE ON *.* TO mgruser@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='mgruser', MASTER_PASSWORD='mgruser' FOR CHANNEL 'group_replication_recovery';
  • 下载插件(每个机器都要操作)
install PLUGIN group_replication SONAME 'group_replication.so';
  • 通过show plugins查看插件是否安装成功
    在这里插入图片描述
  • 至此,三台MySQL服务器配置完毕,我们现在选择一台(即单主模式)作为master并执行命
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
SELECT * FROM performance_schema.replication_group_members;
  • 因为是mysql8验证方式的问题,我们需要在两台备库上面执行mysql -umgruser -pmgruser -h172.21.0.2 --get-server-public-key
  • 在备库执行
START GROUP_REPLICATION;
  • 查询集群的状态SELECT * FROM performance_schema.replication_group_members; ,全部是online才算成功,中间如果有启动错误,可以通过docker logs container_name来查看错误日志
    在这里插入图片描述
  • 配置成功后,我们在master新建一个数据库看一下create database mgr;,我们看到从库已经同步过去了;
  • 我们停掉主库看一下stop group_replication;主库和备库的状态,我们发现主库停掉后,会有一个备库升级成主库继续提供服务
    在这里插入图片描述

在这里插入图片描述

  • 我们在master创建一个表,插入几条记录
use mgr;
CREATE TABLE `user` (
  `id` bigint NOT NULL ,
  `account` varchar(30)  NOT NULL ,
  `name` varchar(50) NOT NULL ,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `UN_ACCOUNT` (`account`) USING BTREE
) 

INSERT INTO user VALUES (1, 'zhangsan', '张三');
INSERT INTO user VALUES (2, 'lisi', '李四');

在这里插入图片描述

  • 在备库上也插入一条看一下效果,插入失败,并且提示是只读的,而且主库插入的数据也读到了

在这里插入图片描述

参考文档

  • 相关参考
  • 相关参考
  • 相关参考
  • 参考文章

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

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

相关文章

Linux系统:OpenSSH7.4p升级到9.0p

目录 一、理论 1.ssh 2.OpenSSH 二、实验 1.OpenSSH升级 三、问题 1.远程SSH服务器拒绝X11转发请求 2.sshd服务重启报错 四、总结 一、理论 1.ssh (1)概念 ssh 是协议,基于22端口的安全协议。 ssh中文解释是安全的shell&#xff…

使用高斯计需要注意哪些事项

高斯计(特斯拉计)是检测磁体磁感应强度的专用仪器,可以测量永磁材料的表磁,磁路间隙磁场以及磁场发生装置产生的空间磁场测量。高斯计(特斯拉计)作为一种比较精密的仪器,在使用过程中应注意以下…

【数据挖掘】推荐系统(一):协同过滤

一、说明 推荐系统是一种计算机程序或算法,用于预测用户对特定项目的兴趣度,并根据这些预测向用户提供个性化推荐。这种系统通常使用大量数据来分析用户的行为和偏好,以找出潜在的喜好和兴趣。推荐系统可以应用于电子商务、社交媒体、影视娱乐…

Java 项目 - SpringBoot+Vue的智慧养老系统

文章目录 1.研究背景2. 技术栈3.系统分析4系统设计4.1 软件功能模块设计4.2数据库设计与实现 5系统详细设计5.1系统功能模块5.2后台登录功能5.2.1管理员功能 源码下载地址 1.研究背景 困扰管理层的许多问题当中,智慧养老平台一定是养老平台不敢忽视的一块。但是管理好智慧养老…

浅浅记录下fortinet vpn链接遇到的一些问题

一、前言 有点问题的win7系统 一、fortinet vpn无法安装问题 说是缺少KB3033929。 首先激活这个系统,怎么激活的这里省略了, 然后下载了一个360修复了一下系统。 二、fortinet vpn安装 刚开始安装的forticlientVPNSetup_7.0.5,安装完成。…

sd卡自动删除的数据如何恢复?数据重获新生的五种方法

用户咨询案例分享: 咨询1:请问SD卡为什么会自动删除里头的文件呀?怎么找回!!! 咨询2:SD卡不知道为什么突然自动删除什么都没有了!还能恢复吗 更多...... 在日常生活中,我们经常使用S…

【电子量产工具】5.页面系统

文章目录 前言一、页面系统分析二、页面数据结构抽象三、底层代码 main_page.c四、页面管理器五、测试程序测试效果总结 前言 最近看了 电子量产工具 这个项目,本专栏是对该项目的一个总结。 一、页面系统分析 页面系统是指在软件应用或网站中,将功能和…

Linux基础服务8——cobbler批量装机

文章目录 一、基本了解1.1 配置文件1.2 数据目录1.3 日志文件1.4 常用命令 二、普通安装2.1 服务端操作2.2 客户端操作 三、定制安装3.1 手动安装3.2 脚本安装(推荐) 一、基本了解 cobbler简介: Cobbler是一个Linux服务器安装的服务&#xff…

Django_MVT(二)

目录 一、MVT简介 二、M-模型类 1. 定义模型类 2. 迁移 2.1 生成迁移文件命令如下: 2.2 执行迁移命令如下: 3. 数据基础操作 三、V-视图 1.定义视图 2.配置URLconf 访问服务器 四、T-模板 创建模板文件 定义模板 视图调用模板 视图调用模…

vue el-table的每行操作el-button添加单独的loading效果实现

vue el-table的每行操作el-button添加单独的loading效果实现 效果图&#xff1a;实现代码&#xff1a;结语 效果图&#xff1a; 实现代码&#xff1a; <tamplate><el-table :data"list" ><el-table-column fixed"right" label"操作&q…

Application Context的继承关系

Application Context他们关系很复杂&#xff0c;紫色是借口&#xff0c;浅绿色是抽象类&#xff0c;我们要创建继承&#xff0c;要创建实现。第一个class path代表未加载路径&#xff0c;rouces下都是未加载路径.FileSystem代表文件系统&#xff0c;代表则磁盘。 看看文件怎么写…

Gof23设计模式之装饰者模式

1.概述 定义 指在不改变现有对象结构的情况下&#xff0c;动态地给对象增加一些职责&#xff08;即增加其额外功能&#xff09;的模式。 例子 我们先来看一个快餐店的例子。 快餐店有炒面、炒饭这些快餐&#xff0c;可以额外附加鸡蛋、火腿、培根这些配菜&#xff0c;当然加…

抖音seo矩阵源码*开发搭建*代码打包部署(开源)分享

1一、 抖音seo矩阵源码开发搭建&#xff08;支持二开&#xff09;概述 抖音SEO矩阵指的是一系列通过搜索引擎优化&#xff08;SEO&#xff09;技术和策略来提升抖音账号在搜索结果中排名的方法和工具。在抖音上&#xff0c;用户可以通过搜索关键词来查找与其相关的视频和账号…

网络子系统1

网络子系统 1 ISO/OSI和TCP/IP参考模型 国际标准化组织&#xff09;设计了一种参考模型&#xff0c;定义了组成网络的各个层。该模型由7层组成&#xff0c;称为OSI&#xff08;Open Systems Interconnection&#xff0c;开放系统互连&#xff09;模型&#xff0c;如图所示。其…

Android耗电优化需要注意的要点

作者&#xff1a;小墙程序员 在应用开发中&#xff0c;耗电是我们需要关注的重点。但是&#xff0c;开始进行耗电优化时&#xff0c;我们常常感到无从下手。这篇文章将介绍耗电优化的相关要点&#xff0c;让我们优化时有一个方向。 传感器 大多数Android设备都内置传感器&…

【停用词】NLP中的停用词怎么获取?我整理了6种方法

文章目录 一、停用词介绍二、停用词应用场景2.1 提取高频词2.2 词云图 三、停用词获取方法3.1 自定义停用词3.2 用wordcloud调取停用词3.3 用nltk调取停用词3.3.1 nltk中文停用词3.3.2 nltk英文停用词 3.4 用sklearn调取停用词3.5 用gensim调取停用词3.6 用spacy调取停用词 一、…

select语句与CSP模型~Go进阶

select语句 select 是 Go 中的一个控制结构。select 语句类似于 switch 语句&#xff0c;但是select会随机执行一个可运行的case。如果没有case可运行&#xff0c;它将阻塞&#xff0c;直到有case可运行。 语法结构 select语句的语法结构和switch语句很相似&#xff0c;也有…

【UGUI学习笔记】Rect Transform

文章目录 Rect Transform锚点和轴心轴心点锚点 Rect Transform 锚点和轴心 在上图中&#xff0c;中心位置的蓝色同心圆代表了轴心点&#xff0c;而四角花瓣的图形代表了实体的锚点。 Attribute含义轴心点 Pivot默认实体的几何中心处&#xff0c;轴心代表了对物体在空间上的坐…

安装git工具

下载安装地址&#xff1a; Git - Downloading Package (git-scm.com) 命令安装&#xff1a;创建文件夹下载路径 启动powershell 输入命令&#xff1a;winget install --id Git.Git -e --source winget 等待下载安装

集合面试题--ArrayList数组

介绍数组 数组&#xff08;Array&#xff09;是一种用连续的内存空间存储相同数据类型数据的线性数据结构。数组&#xff08;Array&#xff09;是一种用连续的内存空间存储相同数据类型数据的线性数据结构。 因为int占4个字节&#xff0c;所以也可以理解为占四块内存 数组如何…