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

这篇具有很好参考价值的文章主要介绍了谈谈mysql——主从模式下的同步方式及半同步、MGR的部署方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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),复制延迟问题已经得到了极大的改进。

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

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

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

半同步复制

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

如果在更新期间,主从库发生了网络故障或者从库宕机,那么此时主库在事务提交后会等待10秒(默认值),如果10秒内还是不能联系到该从库,就会放弃更新该从库,并向用户返回数据。这时主从库就会恢复到默认的异步复制状态。
谈谈mysql——主从模式下的同步方式及半同步、MGR的部署方式,mysql,mysql,android,adb

同步复制【不推荐】

全同步复制(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——主从模式下的同步方式及半同步、MGR的部署方式,mysql,mysql,android,adb
  • 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";来看一下
    谈谈mysql——主从模式下的同步方式及半同步、MGR的部署方式,mysql,mysql,android,adb
  • 我们插入一条记录到user表看一下
    谈谈mysql——主从模式下的同步方式及半同步、MGR的部署方式,mysql,mysql,android,adb
  • 接下来我们看看,如果停了slave,master会不会降级为异步。从库执行命令stop slave;主库插入数据,发现执行插入语句后一直等待,10s后返回结果,查看主库的半同步状态show status like 'Rpl_semi_sync_master_status';和从库的状态show status like 'Rpl_semi_sync_slave_status';已经关闭
    谈谈mysql——主从模式下的同步方式及半同步、MGR的部署方式,mysql,mysql,android,adb
  • 在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——主从模式下的同步方式及半同步、MGR的部署方式,mysql,mysql,android,adb
  • 至此,三台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来查看错误日志
    谈谈mysql——主从模式下的同步方式及半同步、MGR的部署方式,mysql,mysql,android,adb
  • 配置成功后,我们在master新建一个数据库看一下create database mgr;,我们看到从库已经同步过去了;
  • 我们停掉主库看一下stop group_replication;主库和备库的状态,我们发现主库停掉后,会有一个备库升级成主库继续提供服务
    谈谈mysql——主从模式下的同步方式及半同步、MGR的部署方式,mysql,mysql,android,adb

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

  • 我们在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', '李四');

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

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

谈谈mysql——主从模式下的同步方式及半同步、MGR的部署方式,mysql,mysql,android,adb文章来源地址https://www.toymoban.com/news/detail-554341.html

参考文档

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

到了这里,关于谈谈mysql——主从模式下的同步方式及半同步、MGR的部署方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • mysql 主从同步

    角色 ip master 192.168.233.100 slave1 192.168.233.101 slave2 192.168.233.102 禁用 selinux 跟 firewal l情况下: 新路径已修改为 /var/lib/mysql/new_bin master 节点信息 在 master 节点新建同步账号 在 master 与 slave 节点创建数据库 在 slave1 节点配置 发现错误:Last_IO_Error: Fatal error: The slave I/O thread stops be

    2024年02月07日
    浏览(24)
  • 配置mysql的主从同步

    添加用户 添加用户权限 显示主库状态 配置从库 启动从库 如果要重新修改配置 ,需要先停止 最后查看从库状态

    2024年02月21日
    浏览(26)
  • mysql 主从同步案例集合

      relay log 损坏了,导致从库的 SQL 线程解析 relay log 时出现异常。从库恢复方式是通过手动设置当时出错的 GTID 的下一个值,让从库不从主库同步这个 GTID,最后从库就能正常同步这个 GTID 之后的 binlog 了,后续 SQL 线程也能正常解析 relay log 了。 你好,我是悟空。 本文主要内

    2023年04月14日
    浏览(29)
  • Mysql架构篇--Mysql 主从同步方案

    本文对mysql的传统主从复制,半同步复制和组复制进行介绍。 Master 数据库只要发生变化,立马记录到Binlog 日志文件中,Slave数据库启动一个I/0 thread连接Master数据库,请求Master变化的二进制日志。Save I/0获取到的二进制日志,保存到自己的Relay log 日志文件中。Slave 有一个 SQL

    2024年02月07日
    浏览(26)
  • MySQL主从同步(不开GTID)

    一、背景 了解并熟悉MySQL的主从同步的搭建过程,并解决搭建过程中所碰到的问题。 二、目标 了解并熟悉MySQL的主从同步的搭建过程,并解决搭建过程中所碰到的问题。 IP地址 MySQL版本 主从关系 192.168.3.244 5.6.51 Master 192.168.3.245 5.7.41 Slaver 192.168.3.246 8.0.33 Slaver 三、过程 1、安

    2024年02月06日
    浏览(42)
  • MYSQL---主从同步概述与配置

    实现数据自动同步的服务结构 Maste:启用binlog 日志 Slave:Slave_IO: 复制master主机binlog 日志文件的SQL命令到本机的relay-log(中继日志) 文件里。 Slave_SQL: 执行本机 relay-log(中继日志) 文件里的SQL语句,实现与 Master 数据一致。 1》开启binlog日志,记录所有除查询以外的SQL命令 1》从服

    2023年04月21日
    浏览(23)
  • mysql主从同步配置及故障定位

    主节点:     1) 启动二进制日志;         vim /etc/my.cnf | vim /etc/my.cnf.d/server.cnf             [mysqld]             log-bin=master-bin             server-id=1             innodb_file_per_table=ON             skip_name_resolve=ON         systemctl restart mysqld     2) 为当前节点设

    2024年02月11日
    浏览(41)
  • MySQL数据库实现主从同步

    安装MySQL数据库8.0.32 今天来学习数据库主从同步的原理及过程,数据库主要是用来存储WEB数据,在企业当中是极为重要的,下面一起来看下。 MySQL主从复制在中小企业,大型企业中广泛使用,MySQL主从复制的目的是实现数据库冗余备份,将master数据库数据定时同步到slave数据库

    2024年02月02日
    浏览(32)
  • 使用本地mysql+linux实现mysql主从同步

    1.1修改该linux配置文件 1.2重启linux的mysql 1.3使用账户密码登录linux中的mysql,查看是否配置成功 若显示有FIile和Posttion就表示注linux的主节点配置成功 注意事项: 本地的这个数据库的权限必须是管理员权限,否则会出现数据库不能进行访问,配置就会失败 2.1修改本地mysql中的 my.ini 文

    2024年02月09日
    浏览(28)
  • Mysql架构篇--Mysql(M-S) 主从同步

    MySQL主从同步(MySQL Replication)是MySQL服务器的一个常用特性,它能够将MySQL服务器数据自动同步到其他MySQL服务器上,从而实现数据备份和负载均衡的功能。在实际应用中,MySQL主从同步可以用于实现高可用、灾备转移、读写分离等。 首先需要有大于等于2个的mysql 实例,一个

    2024年02月09日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包