浅谈 MySQL高可用

发布于 2022-12-22  787 次阅读


浅谈 MySQL高可用

MySQL常见的高可以方式是通过主从实现的,但是当到了MySQL8.X 后

一、了解MySQL

1.1 MySQL 主从同步过程

mysql 的主从同步原理是建立在binlog 日志上的,通过对binlog 数据的同步来实现主从同步。

binlog全称binary log,二进制日志文件,它记录了数据库所有执行的 DDL 和 DML 等数据库更新的语句,但是不包含select或者show等没有修改任何数据的语句。它是MySQL级别的日志,也就是说所有的存储引擎都会产生bin log,而redo log或者undo log事务日志只有innoDB存储引擎才有

在一主一从的模式种,通常主库用于写数据,从库用来读数据。

web 端或者mysql Master服务执行 更新/删除/添加动作后,会将内容写入binlog 然后同步到从库得relaylog 最后写入到slave从库

image-20230714140202994

1.2 mysql支持的复制类型

异步复制(Asynchronous replication)

MySQL主从集群默认采用的就是异步复制方式,主库在执行完客户端提交的事务后会立即将结果返给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题:主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

异步复制存在比较大的隐患,但是容易可以

半同步复制(Semisynchronous replication)

介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。

这个半同步复制再2台以上机器做slave从库情况下,是一种很好的选择,在兼顾集群稳定的情况下又没有消耗过大的性能

https://blog.csdn.net/frostlulu/article/details/128036951 半同步复制配置

同步复制(Fully synchronous replication)

指当主库执行完一个事务,所有的从库都执行了该事务后才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

两台机器做集群的情况下:虽然同步复制的性能很差,但是相应的安装性要好太多了。

1.3 mysql主从架构搭建模式

MMM 模式

MMM(Master-Master replication manager for mysql)主主复制管理器。它需要2个Master,同一时刻只有1个Master对外提供服务,类似于主备模式。

这种模式是基于VIP(虚拟IP)机制来保证集群的高可用,当一个Master发生故障后,通过虚拟IP转移到新的Master上来继续提供服务。

image-20230717105549070

MHA 模式

MHA(Master High Availability Manager and Tools for mysql),这种架构模式下当发现Master故障时,会选出拥有新数据的Slave节点成为新的master。

自动故障切换过程中,MHA总会试图从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失。

MHA管理器需要单独部署,分为Manager节点和Node节点。

MHA里有 两个角色一个是MHA Node(数据节点)另一个是MHA Manager(管理节点)。MHA Manager可以单独部署 在一台独立的机器上管理多个master-slave集群,也可以部署在一台主服务器或者从服务器上节点上。

image-20230718094527281

MGR 模式

MGR(mysql group replication)是mysql5.7推出的一种组复制机制,解决传统异步复制和半同步复制的数据一致性问题。
MGR也是shared-nothing的,每个节点都有一份完整的数据副本,节点间通过GCS(Group Communication System)进行交互。GCS层提供了节点间的全局消息及其有序性的保证。

MGR可以做到在任何节点、任何时间都能执行读写事务(不含只读事务),不过读写事务要被整个复制组确认后才能提交。如果是只读事务则没有这个限制,任何节点都可以发起及提交。

当读写事务准备提交前,它会向复制组发出一个原子广播,内容包括:该事务修改的数据,及其所对应的writeset。复制组中所有节点要么接收该事务,要么都不接收。如果组中所有节点都接收该事务消息,那么它们都会按照与之前发送事务的相同顺序收到该广播消息。因此,所有组成员都以相同的顺序接收事务的写集,并为事务建立全局顺序。

image-20230726162010543

组复制的特性可以查看官网的文档看详细的内容:MySQL 8.0 参考手册--组复制

二、MySQL MMM 方式搭建主从

2.1 MySQL 安装

这里使用yum 安装mysql-5.7,配置mysql yum 源

cat /etc/yum.repos.d/mysql-community.repo
[mysql-5.7-community]
name=MySQL 5.7 Community Server
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-5.7-community-el7-$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql

安装mysql 5.7

yum install mysql-community-server mysql-devel -y

如果出现以下错误

The GPG keys listed for the "MySQL 5.7 Community Server" repository are already installed but they are not correct for this package.
Check that the correct key URLs are configured for this repository.
 Failing package is: mysql-community-common-5.7.43-1.el7.x86_64
 GPG Keys are configured as: https://repo.mysql.com/RPM-GPG-KEY-mysql
-----------------------------
需要导入密钥
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

检查mysql 5.7 安装包安装情况

rpm -qa|grep mysql

image-20230718132323864

启动MySQL服务,并设置开机自启服务

systemctl start mysqld
systemctl enable mysqld

查看mysql安装后的初始密码

grep 'password' /var/log/mysqld.log 

修改mysql 初始密码

mysql -u'root' -p'初始密码'
mysql>ALTER USER 'root'@'localhost' IDENTIFIED BY '*NxqFN4@zJ01';
flush privileges; //刷新MySQL的系统权限相关表

以下密码问题在密码复杂程度过低时候需要用到,不建议密码过于简单

mysql 5.7 密码长度以及以及复杂程度,要求也可以通过

mysql-password

默认是1,即MEDIUM,所以刚开始设置的密码必须符合长度,且必须含有数字,小写或大写字母,特殊字符。
有时候,只是为了自己测试,不想密码设置得那么复杂,譬如说,我只想设置root的密码为123456。
必须修改两个全局参数:

######首先,修改validate_password_policy参数的值
mysql> set global validate_password_policy=0;
Query OK, 0 rows affected (0.00 sec)
######validate_password_length(密码长度)参数默认为8,我们修改为1
mysql> set global validate_password_length=1;
Query OK, 0 rows affected (0.00 sec)  
#####到这里密码就可以配置成比较简单的pawword 或者123456

2.2 MySQL 主从配置

在master 服务器授权一个账户,拥有slave权限(192.168.232.172 是从库服务器IP)

mysql > GRANT REPLICATION SLAVE ON *.* TO 'tuser'@'192.168.232.172' IDENTIFIED BY '*NxqFN4@zJ';
mysql > flush privileges; //刷新MySQL的系统权限相关

修改master 的mysql配置文件/etc/my.cnf,添加以下内容

log-bin=mysql-bin
server-id=1
binlog_format=row
expire_logs_days=7
binlog_cache_size=1M
---------------------------------------
#####以下两个可选参数(2选1),根据需求配置
#####binlog-do-db=db1,db2 #需要同步的库
#####binlog-ignore-db=db1,db2 #忽略不同步的库
###expire_logs_days  二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
###binlog_cache_size 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存

binlog的格式:
1.statement基于操作的SQL语句记录到binlog,mysql5.1之前都是这种默认格式,生产不建议使用。
优点:并不需要记录每一条SQL语句和每一行数据的变化,减少了binlog日志量,,节约了I/O,提高了性能。
缺点:在某些情况下导致主备数据不一致。row

2.row基于行的变更情况记录基于行的变更情况记录,(会记录行变更前的样子及变更后的内容),生产中使用这种存储格式。
优点:不记录每条SQL语句的上下文信息,仅仅记录哪条数据数据被修改了,然后修改成什么样子了,(任何情况下都可以复制),最为安全。
缺点:会产生大量日志,生产中往往会发现binlog(保留7天)比数据量大的多。
3.mixed:混合使用row和statement格式

重启后查看master status;

mysql> flush tables with read lock;
mysql> show master status;

image-20230718172216201

修改slave的mysql配置文件/etc/my.cnf,添加以下内容

server-id=2
---------------------------------------
#####可选参数(2选1,这两个参数设置成和主一样,根据需求配置
#####replicate-do-db=db1,db2
#####replicate-ignore-db=db1,db2

同步主库数据

###在该数据库中关闭slave同步
stop slave;
mysql>CHANGE MASTER TO
MASTER_HOST='192.168.232.171',
MASTER_USER='tuser',
MASTER_PASSWORD='*NxqFN4@zJ',
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=154;
###在该数据库中启动slave同步
mysql>start slave;
mysql> show slave status\G;

image-20230718172151001

锁表,不让数据写入

flush tables with read lock;
show master status;

2.3 vip 配置

在两台服务器上安装 keepalived

yum -y install keepalived

配置主库从库上的keepalive

备份keepalived配置文件:cp keepalived.conf keepalived.conf.bak

将配置修改为以下内容

# 主库配置
vrrp_script chk_mysql {
   script "/etc/keepalived/switch_mysql_vip.sh"
   interval 2
}
vrrp_instance VI_1 {
     interface ens33
     state MASTER
     virtual_router_id 51
     priority 101
     virtual_ipaddress {
         192.168.232.170
     }
     track_script {
         chk_mysql
     }
}

# 从库配置
vrrp_script chk_mysql {
   script "/etc/keepalived/switch_mysql_vip.sh"
   interval 2
}
vrrp_instance VI_1 {
     interface ens33
     state BACKUP
     virtual_router_id 51
     priority 100
     virtual_ipaddress {
         192.168.232.170
     }
     track_script {
         chk_mysql
     }
}

脚本编写

cat /etc/keepalived/switch_mysql_vip.sh
#!/bin/sh
check=$(/usr/bin/mysql -uroot -p'*NxqFN4@zJ01' -e 'select 1' |sed -n '2p')
function error_query(){
   #systemctl stop  keepalived
   echo "keepalived 切换"
}
#echo "$check"
echo $(date)"--mysql-status:$check"
if [ "$check" != "1" ]
then
   error_query
fi

2.4 配置半同步复制

半同步复制是以插件的形式实现的,要使用半同步复制,要在主从分别安装相应的插件,并且通过参数来控制半同步复制。

在使用半同步复制前需要先满足下列条件:

  • 服务器要支持动态加载,参数have_dynamic_loading要设置为True(MySQL8.0默认就是True)。
  • 已经完成基础异步复制的配置。
  • 不支持一从多主的复制(多通道)

查看半同步插件

先确认MySQL服务器是否支持动态增加插件

mysql> select @@have_dynamic_loading;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    9
Current database: mysql

+------------------------+
| @@have_dynamic_loading |
+------------------------+
| YES                    |
+------------------------+
1 row in set (0.01 sec)

查看数据库的插件文件是否存在

主库的插件是semisync_master.so,从库是semisync_slave.so

[root@test-mysql01 plugin]# pwd
/usr/lib64/mysql/plugin
[root@test-mysql01 plugin]# ll |grep semis
-rwxr-xr-x. 1 root root   937976 Jun 21 09:27 semisync_master.so
-rwxr-xr-x. 1 root root   160912 Jun 21 09:27 semisync_slave.so

安装插件

在主库安装插件:

如果使用的是8.0.26以上的版本,参数中的'master'会被替换为'source','slave'会被替换为'replica'

mysql>install plugin rpl_semi_sync_master soname 'semisync_master.so';

从库安装插件:

mysql>install plugin rpl_semi_sync_slave soname 'semisync_slave.so';

安装完成后,在plugin表(系统表)中查看一下

mysql> select * from mysql.plugin;
+----------------------+----------------------+
| name                 | dl                   |
+----------------------+----------------------+
| rpl_semi_sync_master | semisync_master.so   |
| validate_password    | validate_password.so |
+----------------------+----------------------+
2 rows in set (0.00 sec)

开启半同步复制

主库配置

mysql>set global rpl_semi_sync_master_enabled=1;
mysql>set global rpl_semi_sync_master_timeout=30000;

从库配置

mysql>set global rpl_semi_sync_slave_enabled=1;

防止配置不丢失,建议也将配置添加到my.cnf中

主库配置文件添加

[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=30000

从库配置文件添加

[mysqld]
rpl_semi_sync_slave_enabled=1;

注意:如果之前配置的是异步复制,在这里要重启一下从库的IO线程,如果是全新的半同步则不用重启

###从库操作
mysql>stop slave io_thread;
mysql>start slave io_thread;

在主库查看半同步复制状态

mysql> show status like 'rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+
1 row in set (0.00 sec)

在从库查看半同步复制状态

mysql> show status like 'rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.01 sec)

通过状态变量,我们看到主备的半同步都是处于工作状态,半同步复制的搭建完成

半同步相关配置参数

主库查看半同步相关配置参数:

mysql> show variables like 'rpl_semi_sync%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 30000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.01 sec)

在输出信息中,我们重点关注三个参数:

  • rpl_semi_sync_master_enabled OFF/ON #ON表示半同步复制打开,OFF表示关闭

  • rpl_semi_sync_master_timeout 主库等待从库ACK超时的时长,单位是毫秒,默认是10000(10s)。

  • rpl_semi_sync_master_trace_level 半同步复制时主库的调试级别

  • rpl_semi_sync_master_wait_for_slave_count

    主库需要收到多少个ACK才认为此次提交成功,否则就降级为异步复制,默认是1,即只要有1个从库确认即可提交。

  • rpl_semi_sync_master_no_tx [number] #表示有几个事务不是通过半同步复制到从库的

  • rpl_semi_sync_master_wait_point
    控制主库上commit、接收ACK、返回控制给客户端的时间点。值为after_sync(默认)或after_commit。

监控半同步复制

完成了半同步配置后,和半同步相关的相关状态变量可以帮助我们监控半同步复制的状态:

show status like 'rpl_semi_sync%';

image-20230719202859902

主库有半同步复制相关的状态变量解释:

Rpl_semi_sync_master_clients:当前有多少个半同步从库连接到主库。

Rpl_semi_sync_master_net_avg_wait_time:主库等待从库回复的平均时间,以微秒为单位。此变量始终为0,不推荐使用,并且将在以后的版本中删除。

Rpl_semi_sync_master_net_wait_time:主库等待从库回复的总时间,以微秒为单位。此变量始终为0,不推荐使用,并且将在以后的版本中删除。

Rpl_semi_sync_master_net_waits:主库等待从库回复的总次数。

Rpl_semi_sync_master_no_times:主库关闭半同步复制的次数。

Rpl_semi_sync_master_no_tx:从库未成功确认的事务数。

Rpl_semi_sync_master_status:为ON时表示使用半同步复制,为OFF时表示异步复制。

Rpl_semi_sync_master_timefunc_failures:调用gettimeofday等时间函数时主库失败的次数。

Rpl_semi_sync_master_tx_avg_wait_time:主库等待一个事务的平均时间,以微秒为单位。

Rpl_semi_sync_master_tx_wait_time:主库等待事务的总时间,以微秒为单位。

Rpl_semi_sync_master_tx_waits:主库等待事务的总次数。

Rpl_semi_sync_master_wait_pos_backtraverse:主库等待事件的二进制日志次数低于之前等待事件的总次数。当事务等待回复的顺序与其二进制日志事件的写入顺序不同时,就会发生这种情况。

Rpl_semi_sync_master_wait_sessions:当前正在等待从库回复的会话数。

Rpl_semi_sync_master_yes_tx:从库成功确认的事务数。

三、MySQL MHA 方式搭建主从

四、MySQL MGR 方式搭建主从

这次我们选择的使用3台机器使用 1主两从方式搭建mgr 集群(也可以使用docker 安装3个容器测试),使用方式是通过docker 安装mgr

,需要先安装docker 环境

MGR是MySQL 5.7.17开始引入的,但随着5.7版本逐渐退出历史舞台(MySQL 5.7已于2020年10月起不再做大的功能更新,只有修修补补以及针对安全更新),更多MGR相关特性都只在MySQL 8.0上才有。

因此,如果线上还有基于MySQL 5.7版本的MGR环境的话,建议尽快升级、迁移到MySQL 8.0版本。进一步提醒,推荐MySQL 8.0.22及之后的版本,整体会更稳定可靠,也有些很不错的新功能(不只是MGR方面的)。

安装docker 的过程可以查看 这篇文档:docker 安装

mgr 具有节点管理、故障检测、容错机制

4.2 安装mysql 8

网上有很多关于mgr 的教程,但是都是①一台机器上安装安docker 使用同一个容器网络,安装3个mgr 容器,或者使用三台机器一个内网来搭建,我觉得不够丰富,目前dokcer 拉取服务很快应该是,按照docker 做集群的方式搭建,并且可以扩容节点以及缩节点方式,真正做到动态横向扩容。

三台机器信息如下:

主机名 ip 映射端口 mysql 版本
mysql-mgr175 192.168.232.175 3306 mysql 8.0.20
mysql-mgr176 192.168.232.176 3306 mysql 8.0.20
mysql-mgr177 192.168.232.177 3306 mysql 8.0.20

在三台机器中执行以下命令

拉取mysql8 镜像

docker pull mysql:8.0.20

创建存储数据相关目录

mkdir -p  /data/mysql/mgr/conf
mkdir -p  /data/mysql/mgr/data
mkdir -p  /data/mysql/mgr/mysql-files

创建容器并启动

##在192.168.232.175 上创建容器
docker run -d --name mysql-mgr175 \
-h mgr-175 -p 3306:3306 -p 33061:33061  --net host \
-v /data/mysql/mgr/conf:/etc/mysql/conf.d \
-v /data/mysql/mgr/data:/var/lib/mysql/ \
-v /data/mysql/mgr/mysql-files:/var/lib/mysql-files/ \
-e MYSQL_ROOT_PASSWORD=Admin@mgr175 \
-e TZ=Asia/Shanghai \
mysql:8.0.20

##在192.168.232.176 上创建容器
docker run -d --name mysql-mgr176 \
-h mgr-176 -p 3306:3306 -p 33061:33061  --net host \
-v /data/mysql/mgr/conf:/etc/mysql/conf.d \
-v /data/mysql/mgr/data:/var/lib/mysql/ \
-v /data/mysql/mgr/mysql-files:/var/lib/mysql-files/ \
-e MYSQL_ROOT_PASSWORD=Admin@mgr176 \
-e TZ=Asia/Shanghai \
mysql:8.0.20

##在192.168.232.177 上创建容器
docker run -d --name mysql-mgr177 \
-h mgr-177 -p 3306:3306 -p 33061:33061  --net host \
-v /data/mysql/mgr/conf:/etc/mysql/conf.d \
-v /data/mysql/mgr/data:/var/lib/mysql/ \
-v /data/mysql/mgr/mysql-files:/var/lib/mysql-files/ \
-e MYSQL_ROOT_PASSWORD=Admin@mgr177 \
-e TZ=Asia/Shanghai \
mysql:8.0.20

4.3 配置文件添加

修改主机上my.

vim /data/mysql/mgr/conf/my.cnf
################################主服务器my.cnf
[mysqld]
user=mysql
port=3306
character_set_server=utf8mb4
secure_file_priv=''
server-id = 101
default-time-zone = '+8:00'
log_timestamps = SYSTEM
log-bin = 
binlog_format=row
binlog_checksum=NONE
log-slave-updates=1
auto-increment-increment=2
auto-increment-offset=1
gtid-mode=ON
enforce-gtid-consistency=ON
skip-name-resolve
default_authentication_plugin=mysql_native_password
max_allowed_packet = 500M
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log=mgr175-relay-bin
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="e3331c14-33f9-4111-8ae7-e2f418e05d9d"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address= "192.168.232.175:33061"
loose-group_replication_group_seeds= "192.168.232.175:33061,192.168.232.176:33061,192.168.232.177:33061"
loose-group_replication_bootstrap_group=OFF
loose-group_replication_ip_whitelist="192.168.232.175,192.168.232.176,192.168.232.177"
report_host=192.168.232.175
report_port=3306
############################################从服务器1
[mysqld]
user=mysql
port=3306
character_set_server=utf8mb4
secure_file_priv=''
server-id = 102
default-time-zone = '+8:00'
log_timestamps = SYSTEM
log-bin =
binlog_format=row
binlog_checksum=NONE
log-slave-updates=1
gtid-mode=ON
enforce-gtid-consistency=ON
skip-name-resolve
default_authentication_plugin=mysql_native_password
max_allowed_packet = 500M
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log=mgr176-relay-bin
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="e3331c14-33f9-4111-8ae7-e2f418e05d9d"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address= "192.168.232.176:33061"
loose-group_replication_group_seeds= "192.168.232.175:33061,192.168.232.176:33061,192.168.232.177:33061"
loose-group_replication_bootstrap_group=OFF
loose-group_replication_ip_whitelist="192.168.232.175,192.168.232.176,192.168.232.177"
report_host=192.168.232.176
report_port=3306
############################################从服务器2
[mysqld]
user=mysql
port=3306
character_set_server=utf8mb4
secure_file_priv=''
server-id = 103
default-time-zone = '+8:00'
log_timestamps = SYSTEM
log-bin =
binlog_format=row
binlog_checksum=NONE
log-slave-updates=1
gtid-mode=ON
enforce-gtid-consistency=ON
skip_name_resolve
default_authentication_plugin=mysql_native_password
max_allowed_packet = 500M
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log=mgr177-relay-bin
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="e3331c14-33f9-4111-8ae7-e2f418e05d9d"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address= "192.168.232.177:33061"
loose-group_replication_group_seeds= "192.168.232.175:33061,192.168.232.176:33061,192.168.232.177:33061"
loose-group_replication_bootstrap_group=OFF
loose-group_replication_ip_whitelist="192.168.232.175,192.168.232.176,192.168.232.177"
report_host=192.168.232.177
report_port=3306

server_id各节点不可重复,可以设置为ip最后一位

report_host写本机ip

loose-group_replication_group_name可以在服务器中输入uuidgen生成:

重启三台机器上的容器

docker restart mysql-mgr17*

分别登录三台服务器的对应容器,测试数据是否正常

#docker ps 查询 CONTAINER ID
docker exec -it <CONTAINER ID>  /bin/bash
root@mgr-175:/# mysql -uroot -p'Admin@mgr175'
mysql> select @@hostname,@@server_id,@@server_uuid;
+------------+-------------+--------------------------------------+
| @@hostname | @@server_id | @@server_uuid                        |
+------------+-------------+--------------------------------------+
| mgr-175    |         101 | 2abb4529-2c2c-11ee-87ae-0242ac120002 |
+------------+-------------+--------------------------------------+
1 row in set (0.00 sec)

4.4 安装GR 插件

## 安装前可以先检查本地mysql lib库中是否有这个插件如果没有可能需要想办法下载
## 插件存放位置如下:/usr/lib/mysql/plugin 或者 /usr/lib64/mysql/plugin
###安装插件
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';

查看当前容器节点已经安装的插件

mysql> show plugins;

image-20230727155253021

安装插件步骤 在三个容器内都要执行

4.5 配置同步数据账号

单主模式下,各个节点的数据是强一致的,因此数据写入到某个节点的时候,必然存在不同节点之间数据的拷贝,因此需要创建一个用户复制的账号,在3个容器里面依次执行下面的命令

SET SQL_LOG_BIN=0;
CREATE USER repl@'%' IDENTIFIED BY 'Admin@mgr170';
GRANT REPLICATION SLAVE ON *.* TO repl@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='Admin@mgr170' FOR CHANNEL 'group_replication_recovery';
##第三行表示为之前创建的repl用户授予了复制权限。REPLICATION SLAVE权限允许用户作为从节点连接到主节点,并从主节点复制数据。
##SQL_LOG_BIN=0表示禁止将当前会话中的操作写入二进制日志,SQL_LOG_BIN=1表示开启写入
##最后 配置连接MASTER 节点信息

4.6 开启gr

主节点 上执行以下操作

SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
-- 查看MGR组信息
SELECT * FROM performance_schema.replication_group_members;

在从节点上执行以下操作

START GROUP_REPLICATION;
-- 查看MGR组信息
SELECT * FROM performance_schema.replication_group_members;

image-20230803132449504

6.7 设置权重

由于mgr 的特性,在一主的模式里,但是主机点宕机后,会选举新的主机作为。

我们三个节点时候会使用keepalived 服务配置一个vip,使用vip 的节点是主节点,其他节点是从节点

例如本案例中:192.168.232.175 主节点(读写权限),176 ,177 作为从节点

可以使用keepalived+haproxy 来做高可用,需要注意的是在,vip 的漂移,正常我们vip 作为主(读写),漂移的节点要和mgr 选举的节点一致才可以

可以通过

set global group_replication_member_weight=[number]
#默认权重50,查看权重
show variables like '%group_replication_member_weight%';

可以通过和keepalived 上权重保持一致来控制vip 和mgr 飘移到预定的机器上

例如 :175 gr权重80 keepalived 权重80,176 gr权重70 keepalived 权重70,175 gr权重60 keepalived 权重60

mgr 和vip 都在 175 上,当mysql 你可用使用通过keepalived 脚本判断,关闭keepalived ,自动将vip 做切换,这个时候就会切换到176,mgr 也自动将 176 选举为主。这样就做到高可用和负载,主库写入和,和集群读都没有收到宕机服务器的影响。