《MySQL 组复制实战:单主 / 多主模式搭建、故障切换与数据同步全流程》

MySQL组复制单主和多主模式

概念

组复制是 MySQL 5.7.17 版本出现的新特性,它提供了高可用、高扩展、高可靠的 MySQL 集群服务。
MySQL 组复制分单主模式和多主模式,传统的mysql复制技术仅解决了数据同步的问题,MGR 对属于同一组的服务器自动进行协调。对于要提交的事务,组成员必须就全局事务序列中给定事务的顺序达成一致,提交或回滚事务由每个服务器单独完成,但所有服务器都必须做出相同的决定,如果存在网络分区,导致成员无法达成事先定义的分割策略,则在解决此问题之前系统不会继续进行,直到网络问题解决,这是一种内置的脑裂保护机制。
MGR由组通信系统( Group Communication System , GCS ) 协议支持该系统提供故障检测机制、组成员服务以及安全且有序的消息传递。

组复制流程

首先我们将多个节点共同组成一个复制组,在执行读写(RW)事务的时候,需要通过一致性协议层(Consensus 层)的同意,也就是读写事务想要进行提交,必须要经过组里“大多数人”(对应 Node 节点)的同意,大多数指的是同意的节点数量需要大于 (N/2+1),这样才可以进行提交,而不是原发起方一个说了算。而针对只读(RO)事务则不需要经过组内同意,直接 提交 即可 。

1.实现MySQL组复制-单主模式

1.1 环境说明

主机名ip操作系统版本mysql版本
master192.168.168.128/24rhel7.9mysql8.0.40
rep1192.168.168.129/24rhel7.9mysql8.0.40
rep2192.168.168.130/24rhel7.9mysql8.0.40

所有主机上配置域名自解析:

[root@master ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.168.128 master
192.168.168.129 rep1
192.168.168.128 rep2

1.2 配置master

1.2.1 根据官网填写配置文件

https://dev.mysql.com/doc/refman/8.0/en/group-replication-configuring-instances.html

[root@master ~]# vim /etc/my.cnf
[root@master ~]# cat /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
##设置日志时间和本地时间保持一致
log_timestamps=SYSTEM    
##组复制,数据必须存储在 InnoDB 事务存储引擎中,禁用其他的存储引
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server_id=129
#组复制要开启gtid
gtid_mode=ON
enforce_gtid_consistency=ON
#将组复制插件添加到服务器启动时加载的插件列表中
plugin_load_add='group_replication.so'
#告诉插件它正在加入或创建的组名为“aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa”
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
#插件在服务器启动时不自动启动操作,使用手动启动插件
group_replication_start_on_boot=off
#与其它主机通信时使用的网络地址和端口
group_replication_local_address= "192.168.168.128:33061"
 #设置组成员的主机名和端口
group_replication_group_seeds= "master:33061,rep1:33061,rep2:33061"
 #设置组成员的主机名和端口
group_replication_bootstrap_group=off
#仅允许白名单内的 IP 加入复制组
group_replication_ip_whitelist="192.168.168.0/24,127.0.0.1/8"
#caching_sha2_password插件要求安全传输密码,开启主从之间的连接使用SSL/TLS 
group_replication_recovery_use_ssl=on
1.2.2 启动mysql服务
[root@master ~]# /etc/init.d/mysqld start
Starting MySQL.Logging to '/data/mysql/master.err'.
. SUCCESS!
1.2.3 在主的数据库中使用sql语句添加复制账号并授予权限
mysql> SET SQL_LOG_BIN=0;
mysql> CREATE USER rp@'%' IDENTIFIED BY '123';
#给用户 rp 授予从复制相关权限
mysql> GRANT REPLICATION SLAVE ON *.* TO rp@'%';
#赋予 rp 用户连接管理权限
mysql> GRANT CONNECTION_ADMIN ON *.* TO rp@'%';
#该语句是为 rp 用户授予备份管理权限
mysql> GRANT BACKUP_ADMIN ON *.* TO rp@'%';
#授予 rp 用户组复制流权限
mysql> GRANT GROUP_REPLICATION_STREAM ON *.* TO rp@'%';
#刷新权限
mysql> FLUSH PRIVILEGES;
mysql> SET SQL_LOG_BIN=1;

CHANGE REPLICATION SOURCE TO SOURCE_USER='rp', SOURCE_PASSWORD='123' FOR CHANNEL 'group_replication_recovery';
1.2.4 查看是否有group_replication插件
mysql> show plugins;
| group_replication    | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL |
1.2.5 启动MGR集群
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION USER='rp',PASSWORD='123';
SET GLOBAL group_replication_bootstrap_group=OFF;

在主上查看组信息

mysql> SELECT * FROM performance_schema.replication_group_members;

在这里插入图片描述

说明

CHANNEL_NAME:通道名称。组复制插件创建两个复制通道:
group_replication_recovery:用于与分布式恢复阶段相关的复制更改。
group_replication_applier:用于来自组传入的更改,是应用直接来自组的事务的通道。
MEMBER_ID:组成员实例的server_uuid。
MEMBER_HOST:组成员主机名。如果配置了report_host参数,这里显示IP地址。
MEMBER_ROLE:成员角色,主为PRIMARY,从为SECONDARY。
MEMBER_VERSION:成员数据库实例版本。
MEMBER_STATE:成员状态,取值和含义如下所示:
ONLINE 表示该成员可正常提供服务
RECOVERING 表示当前成员正在从其它节点恢复数据
OFFLINE 表示组复制插件已经加载,但是该成员不属于任何一个复制组
ERROR 表示成员在recovery阶段出现错误或者从其它节点同步状态中出现错误
UNREACHABLE 成员处于不可达状态,无法与之进行网络通讯

1.3 配置从节点

1.3.1 写配置文件
#在rep1上
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
log_timestamps=SYSTEM
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server_id=128 #这个在组内必须独一无二
gtid_mode=ON
enforce_gtid_consistency=ON
plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "192.168.168.129:33061" #记得修改为当前主机IP
group_replication_group_seeds= "master:33061,rep1:33061,rep2:33061"
group_replication_bootstrap_group=off
group_replication_ip_whitelist="192.168.168.0/24,127.0.0.1/8"
group_replication_recovery_use_ssl=on
[root@rep1 ~]# /etc/init.d/mysqld start
Starting MySQL.Logging to '/data/mysql/rep1.err'.
.. SUCCESS!

#在rep2上
[root@rep2 ~]# /etc/init.d/mysqld start
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
log_timestamps=SYSTEM
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server_id=130
gtid_mode=ON
enforce_gtid_consistency=ON
plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "192.168.168.130:33061" #改为本机IP
group_replication_group_seeds= "master:33061,rep1:33061,rep2:33061"
group_replication_bootstrap_group=off
group_replication_ip_whitelist="192.168.168.0/24,127.0.0.1/8"
group_replication_recovery_use_ssl=on
[root@rep2 ~]# /etc/init.d/mysqld start
Starting MySQL.Logging to '/data/mysql/rep2.err'.
.. SUCCESS!
1.3.2 在所有从的数据库中使用sql语句添加复制账号并授予权限
SET SQL_LOG_BIN=0;
CREATE USER rp@'%' IDENTIFIED BY '123';
GRANT REPLICATION SLAVE ON *.* TO rp@'%';
GRANT CONNECTION_ADMIN ON *.* TO rp@'%';
GRANT BACKUP_ADMIN ON *.* TO rp@'%';
GRANT GROUP_REPLICATION_STREAM ON *.* TO rp@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;

CHANGE REPLICATION SOURCE TO SOURCE_USER='rp', SOURCE_PASSWORD='123' FOR CHANNEL 'group_replication_recovery';
1.3.3 开启组复制
mysql> START GROUP_REPLICATION USER='rp', PASSWORD='123';

查看

mysql> SELECT * FROM performance_schema.replication_group_members;

在这里插入图片描述

1.4 测试

#在主库节点数据上执行
mysql> create database test;
Query OK, 1 row affected (0.01 sec)
mysql> use test
Database changed
mysql> create table t1(id int,name char(20));
Query OK, 0 rows affected (0.01 sec)
#报错是因为没有设置主键,无法插入数据
mysql> insert t1 values(1,'zhangsan'),(2,'lisi');
ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin.
mysql> alter table t1 modify id int primary key;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> insert t1 values(1,'zhangsan'),(2,'lisi');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

#三个节点都可以查到数据
mysql> select * from test.t1;
+----+----------+
| id | name     |
+----+----------+
|  1 | zhangsan |
|  2 | lisi     |
+----+----------+
2 rows in set (0.00 sec)
#在从节点写入数据,发现不支持写入只有只读权限
mysql> use test
Database changed
mysql> insert t1 values (3,'wangwu');
ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement
1.4.1 测试主节点宕机
mysql> stop group_replication;
Query OK, 0 rows affected (3.09 sec)
mysql> select * from performance_schema.replication_group_members;
#这个时候主节点已经宕机了,脱离了组

在这里插入图片描述

#从库节点查看,发现仅剩2个节点,并且自动选举出主节点 
mysql> SELECT * FROM performance_schema.replication_group_members;
#rep2为主节点

在这里插入图片描述

#重新启动前面的master主节点,可以看到master已经作为从节点加入到群组中
mysql> start group_replication;
mysql> select * from performance_schema.replication_group_members;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. 实现mysql组复制-多主模式

2.1 修改所有主机的配置文件

#修改所有的my.cnf的配置文件,添加如下内容
#关闭单master模式
loose-group_replication_single_primary_mode=off
#多主一致性检查
loose-group_replication_enforce_update_everywhere_checks=ON
[root@master ~]# vim /etc/my.cnf
[root@master ~]# /etc/init.d/mysqld restart
Shutting down MySQL...... SUCCESS!
Starting MySQL. SUCCESS!
[root@master ~]#

2.2 开启组复制

#在其中一台主机里面执行以下mysql命令
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (1.08 sec)
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)
#在另外两台主机里面执行以下mysql命令,开启组复制
mysql> START GROUP_REPLICATION;
mysql> SELECT * FROM performance_schema.replication_group_members;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.3 测试三台主机是否都能写入

#master
mysql> insert test.t1 values (3,'liming'),(4,'xiaomei');
#rep1
mysql> insert test.t1 values (5,'xiaowu');
#rep2
mysql> insert test.t1 values(7,'xiaoqi');
#查看
mysql> select * from test.t1;
+----+----------+
| id | name     |
+----+----------+
|  1 | zhangsan |
|  2 | lisi     |
|  3 | liming   |
|  4 | xiaomei  |
|  5 | xiaowu   |
|  7 | xiaoqi   |
+----+----------+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值