mysql 高可用之MGR

一. 背景介绍

基于传统异步复制和半同步复制的缺陷——数据的一致性问题无法保证,MySQL官方在5.7.17版本正式推出组复制(MySQL Group Replication,简称MGR)。

由若干个节点共同组成一个复制组,一个事务的提交,必须经过组内大多数节点(N / 2 + 1)决议并通过,才能得以提交。如上图所示,由3个节点组成一个复制组,Consensus层为一致性协议层,在事务提交过程中,发生组间通讯,由2个节点决议(certify)通过这个事务,事务才能够最终得以提交并响应。

引入组复制,主要是为了解决传统异步复制和半同步复制可能产生数据不一致的问题。组复制依靠分布式一致性协议(Paxos协议的变体),实现了分布式下数据的最终一致性,提供了真正的数据高可用方案(是否真正高可用还有待商榷)。其提供的多写方案,给我们实现多活方案带来了希望。

 1.MGR特点

MySQL Group Replication(MGR)是MySQL官方在5.7.17版本引进的一个数据库高可用与高扩展的解决方案,以插件形式提供,实现了分布式下数据的最终一致性,总结MGR特点如下:

  • 高一致性:基于分布式paxos协议实现组复制,保证数据一致性;
  • 高容错性:自动检测机制,只要不是大多数节点都宕机就可以继续工作,内置防脑裂保护机制;
  • 高扩展性:节点的增加与移除会自动更新组成员信息,新节点加入后,自动从其他节点同步增量数据,直到与其他节点数据一致;
  • 高灵活性:提供单主模式和多主模式,单主模式在主库宕机后能够自动选主,所有写入都在主节点进行,多主模式支持多节点写入。

2.组复制故障检测

故障检测是提供关于哪些 server 可能已死的信息(猜测)的分布式服务。 某个 server 无响应时触发猜测,组中其余成员进行协调决定以排除给定成员。如果某个 server 与组的其余成员隔离,则它会怀疑所有其他 server 都失败了。由于无法与组达成协议(因为它无法确保仲裁成员数),其怀疑不会产生后果。当服务器以此方式与组隔离时,它无法执行任何本地事务。 在线 server 列表通常称为视图,新成员server的加入离开,无论是自愿还是被迫的离开,该组都会动态地重新规划其配置,并触发视图更新。

3.组复制的限制

  • 存储引擎必须为Innodb,即仅支持InnoDB表,并且每张表一定要有一个主键,用于做write set的冲突检测;
  • 每个表必须提供主键;
  • 只支持ipv4,网络需求较高;
  • 必须打开GTID特性,二进制日志格式必须设置为ROW,用于选主与write set;
  • COMMIT可能会导致失败,类似于快照事务隔离级别的失败场景;
  • 目前一个MGR集群组最多支持9个节点;
  • 不支持外键于save point特性,无法做全局间的约束检测与部分部分回滚;
  • 二进制日志binlog不支持Replication event checksums;
  • 多主模式(也就是多写模式) 不支持SERIALIZABLE事务隔离级别;
  • 多主模式不能完全支持级联外键约束;
  • 多主模式不支持在不同节点上对同一个数据库对象并发执行DDL(在不同节点上对同一行并发进行RW事务,后发起的事务会失败);

二.安装环境

3台服务器搭建3节点MGR集群,MySQL版本5.7.28,操作系统版本CentOS 6.10。

  • 192.168.109.101
  • 192.168.109.102
  • 192.168.109.103

2.1为了方便实验,关闭所有节点的防火墙

[root@mysql01 ~]# service iptables stop

2.2所有节点的selinux设置为disabled

[root@mysql01 ~]# getenforce
Disabled

2.3配置各主机名和ip映射,所有节点配置一样

[root@mysql01 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.109.101 mysql01
192.168.109.102 mysql02
192.168.109.103 mysql03

说明:必须保证各个mysql节点的主机名不一致,并且能通过主机名找到各成员!则必须要在每个节点的/etc/hosts里面做主机名绑定,否则后续将节点加入group组会失败!报错RECOVERING!!

三.安装步骤

3.1 官网下载5.7安装包 mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz,建立安装目录/mysql和数据目录/data/mysql,解压压缩包

[root@mysql01 ~]#mkdir /mysql
[root@mysql01 ~]#mkdir /data/mysql
[root@mysql01 ~]# cd /softwares/
[root@mysql01 softwares]#tar -zxvf  mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz
[root@mysql01 softwares]# cd mysql-5.7.28-linux-glibc2.12-x86_64
[root@mysql01 mysql-5.7.28-linux-glibc2.12-x86_64]# cp -rf * /mysql
[root@mysql01 mysql-5.7.28-linux-glibc2.12-x86_64]#chown -R mysql.mysql /mysql /data/mysql

3.2配置环境变量

vi /root/.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

# User specific environment and startup programs

#PATH=$PATH:$HOME/bin
PATH=$PATH:$HOME/bin:/mysql/bin:/mysql/lib:/mysql
export PATH

3.3配置my.cnf

编辑配置文件 /etc/my.cnf,3个节点除了server_id、loose-group_replication_local_address参数不一样外,其他保持一致。
mysql01配置:
[mysqld]
datadir=/data/mysql
basedir=/mysql
port=3306
socket=/data/mysql/mysql.sock
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="05153196-c2ab-43ae-b355-b9832eacf0b2"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address="192.168.109.101:33061"
loose-group_replication_group_seeds="192.168.109.101:33061,192.168.109.102:33061,192.168.109.103:33061"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=FALSE
loose-group_replication_enforce_update_everywhere_checks= TRUE
mysql02配置:
[mysqld]
datadir=/data/mysql
basedir=/mysql
port=3306
socket=/data/mysql/mysql.sock
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="05153196-c2ab-43ae-b355-b9832eacf0b2"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address="192.168.109.102:33061"
loose-group_replication_group_seeds="192.168.109.101:33061,192.168.109.102:33061,192.168.109.103:33061"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=FALSE
loose-group_replication_enforce_update_everywhere_checks= TRUE
mysql03配置:
[mysqld]
datadir=/data/mysql
basedir=/mysql
port=3306
socket=/data/mysql/mysql.sock
server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="05153196-c2ab-43ae-b355-b9832eacf0b2"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address="192.168.109.103:33061"
loose-group_replication_group_seeds="192.168.109.101:33061,192.168.109.102:33061,192.168.109.103:33061"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=FALSE
loose-group_replication_enforce_update_everywhere_checks= TRUE

组复制部分配置参数说明:

group_replication变量使用的loose-前缀是指示Server启用时尚未加载复制插件也将继续启动
transaction_write_set_extraction = XXHASH64
##指示Server必须为每个事务收集写集合,并使用XXHASH64哈希算法将其编码为散列
loose-group_replication_group_name="01e5fb97-be64-41f7-bafd-3afc7a6ab555"
##表示将加入或者创建的复制组命名为01e5fb97-be64-41f7-bafd-3afc7a6ab555
##可自定义(通过cat /proc/sys/kernel/random/uuid)
loose-group_replication_start_on_boot=off 
##设置为Server启动时不自动启动组复制
loose-group_replication_local_address="192.168.109.101:33061" 
##绑定本地的192.168.109.101及33061端口接受其他组成员的连接,IP地址必须为其他组成员可正常访问
loose-group_replication_group_seeds="192.168.109.101:33061,192.168.109.102:33061,192.168.109.103:33061"
##本行为告诉服务器当服务器加入组时,应当连接到192.168.109.101:33061,192.168.109.102:33061,192.168.109.101:33061
##这些种子服务器进行配置。本设置可以不是全部的组成员服务地址。
loose-group_replication_bootstrap_group = off 
##配置是否自动引导组
loose-group_replication_ip_whitelist=”10.30.0.0/16,10.31.0..0/16,10.27.0.0/16″
##配置白名单,默认情况下只允许192.168.109.x连接到复制组,如果是其他IP则需要配置。
3.4初始化并启动各数据库节点
/mysql/bin/mysqld --initialize-insecure  --user=mysql --basedir=/data/mysql --datadir=/data/mysql

/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &

3.5登录数据库,加载MGR插件,创建同步账号

[root@mysql01 ~]# mysql -uroot -p -S /data/mysql/mysql.sock
# 安装MGR插件
mysql>INSTALL PLUGIN group_replication SONAME 'group_replication.so';

#设置复制账号
mysql> SET SQL_LOG_BIN=0;
mysql> CREATE USER repl@'%' IDENTIFIED BY '123';
mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%';
mysql> FLUSH PRIVILEGES;
mysql> SET SQL_LOG_BIN=1;
mysql> CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='123' FOR CHANNEL 'group_replication_recovery';

四.启动MGR单主模式

# 启动MGR,在主库(192.168.109.101)上执行
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
mysql> START GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
# 查看MGR组信息
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 6972ca25-25ba-11ea-b9c7-000c29dde96d | mysql01     |        3306 | ONLINE       |

# 其他节点加入MGR,在从库(192.168.109.102,192.168.109.103)上执行
mysql> START GROUP_REPLICATION;

# 查看MGR组信息
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 604a4cd6-25bb-11ea-8182-000c29378257 | mysql02     |        3306 | ONLINE       |
| group_replication_applier | 6972ca25-25ba-11ea-b9c7-000c29dde96d | mysql01     |        3306 | ONLINE       |
| group_replication_applier | ac6d7494-25bb-11ea-8409-000c29258d07 | mysql03     |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)

可以看到,3个节点状态为online,并且主节点为192.168.109.101,只有主节点可以写入,其他节点只读,MGR单主模式搭建成功。

五.切换至多主模式

MGR切换模式需要重新启动组复制,因些需要在所有节点上先关闭组复制,设置 group_replication_single_primary_mode=OFF 等参数,再启动组复制。

# 停止组复制(所有节点执行):
mysql> stop group_replication;
mysql> set global group_replication_single_primary_mode=OFF;
mysql> set global group_replication_enforce_update_everywhere_checks=ON;

# 随便选择某个节点执行
mysql> SET GLOBAL group_replication_bootstrap_group=ON; 
mysql> START GROUP_REPLICATION; 
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;

# 其他节点执行
mysql> START GROUP_REPLICATION; 

# 查看组信息,所有节点的 MEMBER_ROLE 都为 PRIMARY
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 604a4cd6-25bb-11ea-8182-000c29378257 | mysql02     |        3306 | ONLINE       |
| group_replication_applier | 6972ca25-25ba-11ea-b9c7-000c29dde96d | mysql01     |        3306 | ONLINE       |
| group_replication_applier | ac6d7494-25bb-11ea-8409-000c29258d07 | mysql03     |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)

可以看到所有节点状态都是online,角色都是PRIMARY,MGR多主模式搭建成功。

六.切换回单主模式

# 所有节点执行
mysql> stop group_replication;
mysql> set global group_replication_enforce_update_everywhere_checks=OFF;
mysql> set global group_replication_single_primary_mode=ON;

# 主节点(192.168.109.101)执行
SET GLOBAL group_replication_bootstrap_group=ON; 
START GROUP_REPLICATION; 
SET GLOBAL group_replication_bootstrap_group=OFF;

# 从节点(192.168.109.102、192.168.109.103)执行
START GROUP_REPLICATION; 

# 查看MGR组信息
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 604a4cd6-25bb-11ea-8182-000c29378257 | mysql02     |        3306 | ONLINE       |
| group_replication_applier | 6972ca25-25ba-11ea-b9c7-000c29dde96d | mysql01     |        3306 | ONLINE       |
| group_replication_applier | ac6d7494-25bb-11ea-8409-000c29258d07 | mysql03     |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)

七.问题记录

注: 前面的用户密码修改和创建用户操作必须设置binlog不记录,执行后再打开,否则会引起START GROUP_REPLICATION执行报错:
ERROR 3092 (HY000): The server is not configured properly to be an active member of the group. Please see more details on error log.

解决方案是:根据提示打开group_replication_allow_local_disjoint_gtids_join选项,mysql命令行执行:
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;
然后再执行:
mysql> start group_replication;
posted @ 2020-01-03 15:53  KeepBetter  阅读(11261)  评论(1编辑  收藏  举报