MySQL高可用之组复制(MGR)

华子目录

组复制的特点

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

组复制工作原理

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

  • 节点数量不能超过9台

单主模式和多主模式

单主

  • single-primary mode(单写或单主模式)
  • 单写模式group内只有一台节点可写可读其他节点只可以。当主服务器失败时,会自动选择主服务器

多主

  • multi-primary mode(多写或多主模式)
  • 组内所有机器都是primary节点,同时可以进行读写操作,并且数据最终一致的

实现mysql多主模式组复制

  • 为了避免出错,在所有节点从新生成数据库数据

  • node1

bash 复制代码
[root@mysql-node1 ~]# /etc/init.d/mysqld stop

[root@mysql-node1 ~]# rm -rf /data/mysql/*
  • node2
bash 复制代码
[root@mysql-node2 ~]# /etc/init.d/mysql.server stop

[root@mysql-node2 ~]# rm -rf /data/mysql/*
  • node3
bash 复制代码
[root@mysql-node3 ~]# /etc/init.d/mysqld stop

[root@mysql-node3 ~]# rm -rf /data/mysql/*
  • 修改master上的配置文件内容
bash 复制代码
[root@mysql-node1 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=10   #配置server唯一标识号

disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"  #禁用指定存储引擎
gtid_mode=ON  #启用全局事件标识
enforce_gtid_consistency=ON   #强制gtid一致
master_info_repository=TABLE  #复制事件数据到表中而不记录在数据目录中
relay_log_info_repository=TABLE
binlog_checksum=NONE   #禁止对二进制日志校验
log_slave_updates=ON   #打开数据库中继,当slave中sql线程读取日志后也会写入到自己的binlog中
log_bin=binlog  #开启binlog日志并重新指定log名称
binlog_format=ROW  #使用行日志格式
plugin_load_add='group_replication.so'  #加载组复制插件
transaction_write_set_extraction=XXHASH64  #把每个事件编码为加密散列
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"  #通知插件正式加入,或创建的组名,名称为uuid格式
group_replication_start_on_boot=off  #在server启动时不自动启动组复制
group_replication_local_address="172.25.254.10:33061"  #指定插件接受其他成员的信息端口
group_replication_group_seeds="172.25.254.10:33061,172.25.254.20:33061,172.25.254.30:33061"   #本地地址允许访问成员列表
group_replication_ip_whitelist="172.25.254.0/24,127.0.0.1/8"  #主机白名单
group_replication_bootstrap_group=off  #不随系统自启而启动
group_replication_single_primary_mode=OFF  #使用多主模式
group_replication_enforce_update_everywhere_checks=ON  #组同步中有任何改变检测更新
group_replication_allow_local_disjoint_gtids_join=1  #放弃自己信息以master事件为主
  • 3台节点上配置hosts解析(这里ip解析域名一定要和主机名一致
sql 复制代码
[root@mysql-node1 ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.10  mysql-node1
172.25.254.20  mysql-node2
172.25.254.30  mysql-node3
sql 复制代码
[root@mysql-node2 ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.10  mysql-node1
172.25.254.20  mysql-node2
172.25.254.30  mysql-node3
sql 复制代码
[root@mysql-node3 ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.10  mysql-node1
172.25.254.20  mysql-node2
172.25.254.30  mysql-node3
  • master上进行初始化
bash 复制代码
[root@mysql-node1 ~]# mysqld --user=mysql --initialize
  • master上启动数据库
bash 复制代码
[root@mysql-node1 ~]# /etc/init.d/mysqld start

[root@mysql-node1 ~]# mysql -uroot -p'7t84Qherg)&U'
sql 复制代码
mysql> alter user root@localhost identified by '123456';
  • 进行组复制配置
sql 复制代码
mysql> set sql_log_bin=0;

mysql> create user huazi@'%' identified by '123456';

mysql> grant replication slave on *.* to huazi@'%';

mysql> flush privileges;

mysql> set sql_log_bin=1;

mysql> change master to master_user='huazi',master_password='123456' for channel 'group_replication_recovery';

mysql> set global group_replication_bootstrap_group=on;

mysql> start group_replication;

mysql> set global group_replication_bootstrap_group=off;
  • 测试
sql 复制代码
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | c0dd8ac3-b159-11ef-9d51-000c2928b963 | mysql-node1 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
  • 此时做好了,但是这时,这个组是一个光杆司令,我们需要把别的主机加入到这个组
  • node2
sql 复制代码
#先将node1上的my.cnf文件拷贝过来
[root@mysql-node1 ~]# rsync /etc/my.cnf root@172.25.254.20:/etc/

[root@mysql-node2 ~]# vim /etc/my.cnf
  • 初始化
bash 复制代码
[root@mysql-node2 ~]# mysqld --user=mysql --initialize
  • 启动mysql
bash 复制代码
[root@mysql-node2 ~]# /etc/init.d/mysql.server start
sql 复制代码
[root@mysql-node2 ~]# mysql -uroot -p'Pd=RovxmK6Oj'

mysql> alter user root@localhost identified by "123456";
  • 进行组复制配置
sql 复制代码
mysql> set sql_log_bin=0;

mysql> create user huazi@'%' identified by "123456";

mysql> grant replication slave on *.* to huazi@'%';

mysql> flush privileges;

mysql> set sql_log_bin=1;

mysql> change master to master_user='huazi',master_password='123456' for channel 'group_replication_recovery';

mysql> start group_replication;
  • 测试
sql 复制代码
#我们发现node2加入到了组里
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 79c39c85-b15d-11ef-b574-000c292fa568 | mysql-node2 |        3306 | ONLINE       |
| group_replication_applier | c0dd8ac3-b159-11ef-9d51-000c2928b963 | mysql-node1 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
  • node3
sql 复制代码
#先将node1上的my.cnf文件拷贝过来
[root@mysql-node1 ~]# rsync /etc/my.cnf root@172.25.254.30:/etc/

[root@mysql-node3 ~]# vim /etc/my.cnf
  • 初始化
sql 复制代码
[root@mysql-node3 ~]# mysqld --user mysql --initialize
  • 启动MySQL
sql 复制代码
[root@mysql-node3 ~]# /etc/init.d/mysqld start
sql 复制代码
[root@mysql-node3 ~]# mysql -uroot -p'&jTpm:rok9Pv'

mysql> alter user root@localhost identified by '123456';
  • 进行组复制配置
sql 复制代码
mysql> set sql_log_bin=0;

mysql> create user huazi@'%' identified by "123456";

mysql> grant replication slave on *.* to huazi@'%';

mysql> flush privileges;

mysql> set sql_log_bin=1;

mysql> change master to master_user='huazi',master_password='123456' for channel 'group_replication_recovery';

mysql> start group_replication;
  • 测试
sql 复制代码
#我们发现,node3也加入到了组里
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 747e4cef-b15f-11ef-a867-000c290eaf9d | mysql-node3 |        3306 | ONLINE       |
| group_replication_applier | 79c39c85-b15d-11ef-b574-000c292fa568 | mysql-node2 |        3306 | ONLINE       |
| group_replication_applier | c0dd8ac3-b159-11ef-9d51-000c2928b963 | mysql-node1 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+

测试

bash 复制代码
#node1上创建一个库
mysql> create database huazi;

#node2上查看
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| huazi              |  #发现了创建的库
| mysql              |
| performance_schema |
| sys                |
+--------------------+

#node3上查看
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| huazi              | #发现了创建的库
| mysql              |
| performance_schema |
| sys                |
+--------------------+
bash 复制代码
#node3上创建一个表(在创建表时,必须存在主键,否则插入数据时会失败)
mysql> use huazi;
Database changed
mysql> create table userlist(
    -> name varchar(10) primary key,
    -> password varchar(20));

#node2上查看
mysql> use huazi;

Database changed
mysql> show tables;
+-----------------+
| Tables_in_huazi |
+-----------------+
| userlist        |
+-----------------+

#node1上查看
mysql> use huazi;

Database changed
mysql> show tables;
+-----------------+
| Tables_in_huazi |
+-----------------+
| userlist        |
+-----------------+
  • 在创建表时,必须存在主键,否则插入数据时会失败
bash 复制代码
#node2上插入数据
mysql> insert into userlist values 
    -> ("huazi","123456");

#node3上查看
mysql> select * from userlist;
+-------+----------+
| name  | password |
+-------+----------+
| huazi | 123456   |
+-------+----------+

#node1上查看
mysql> select * from userlist;
+-------+----------+
| name  | password |
+-------+----------+
| huazi | 123456   |
+-------+----------+
  • 总结:所有主机都是可读可写的
bash 复制代码
#当有一台主机挂了
mysql> quit
Bye
[root@mysql-node2 ~]# /etc/init.d/mysql.server stop

#我们在node1上可以发现,挂了的主机自动从组中消除了
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 747e4cef-b15f-11ef-a867-000c290eaf9d | mysql-node3 |        3306 | ONLINE       |
| group_replication_applier | c0dd8ac3-b159-11ef-9d51-000c2928b963 | mysql-node1 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
bash 复制代码
#当主机上线后
[root@mysql-node2 ~]# /etc/init.d/mysql.server start

#也不会自动加进去,需要我们手动加入
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 747e4cef-b15f-11ef-a867-000c290eaf9d | mysql-node3 |        3306 | ONLINE       |
| group_replication_applier | c0dd8ac3-b159-11ef-9d51-000c2928b963 | mysql-node1 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
  • 为什么需要手动加入
bash 复制代码
#进行手动加入
[root@mysql-node2 ~]# mysql -uroot -p
Enter password:

#手动加入
mysql> start group_replication;

#我们发现加入了
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 747e4cef-b15f-11ef-a867-000c290eaf9d | mysql-node3 |        3306 | ONLINE       |
| group_replication_applier | 79c39c85-b15d-11ef-b574-000c292fa568 | mysql-node2 |        3306 | ONLINE       |
| group_replication_applier | c0dd8ac3-b159-11ef-9d51-000c2928b963 | mysql-node1 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
相关推荐
还算善良_1 小时前
【乐企文件生成工程】搭建docker环境,使用docker部署工程
运维·docker·容器
Lalolander2 小时前
2024信创数据库TOP30之华为Gauss DB
大数据·数据库·科技·华为·系统架构
莳花微语4 小时前
Oracle 11G DataGuard GAP 修复过程(通过主库scn增备恢复)
数据库·oracle
petaexpress4 小时前
云原生和数据库哪个好一些?
数据库·云原生·云原生和数据库哪个好·云原生和数据库
Cristiano永远是goat4 小时前
数据库原理-期末复习基础知识第二弹
数据库
18.Show4 小时前
有趣的Docker
运维·docker·容器
wuzuyu3654 小时前
docker.io连接超时的处理,用代理网站
运维·docker·容器
zz-zjx4 小时前
nerdctl:与 Docker 兼容的 containerd CLI
运维·docker·容器
MXsoft6185 小时前
智能运维视角下的网络设备监测与数据分析
大数据·运维·数据库
冧轩在努力5 小时前
redis的应用--分布式锁
数据库·redis·分布式