1、背景

主从复制,一主多从,主库提供读写功能,从库提供只读功能。当一个事务在master 提交成功时,会把binlog文件同步到从库服务器上落地为relay log给slave端执行,这个过程主库是不考虑从库是否有接收到binlog文件,有可能出现这种情况,当主库commit一个事务后,数据库发生宕机,刚好它的binlog还没来得及传送到slave端,这个时候选任何一个slave端都会丢失这个事务,造成数据不一致情况。 为了避免出现主从数据不一致的情况,MySQL引入了半同步复制,添加多了一个从库反馈机制,即半同步复制。这个有两种方式设置:

  • 主库执行完事务后,同步binlog给从库,从库ack反馈接收到binlog,主库提交commit,反馈给客户端,释放会话;
  • 主库执行完事务后,主库提交commit ,同步binlog给从库,从库ack反馈接收到binlog,反馈给客户端,释放会话; 下载 (1)

但是,虽然满足了一主多从,读写分析,数据一致,但是,依旧有两个弊端:

  • 写操作只能在master上;
  • 如果master宕机,需要人为选择新主并重新给其他的slave端执行change master;

下载 (2)

为了解决一系列问题,官方推出了MySQL Group Replication,从group replication发布以后,就有3种方法来实现MySQL的高可用集群:

  • 异步复制
  • 半同步复制
  • group replication

2、Group Replication原理

MySQL Group Replication有两种模式,单主模式single-primary mode和多主模式multi-primary mode,在同一个group内,不允许两种模式同时存在,并且若要切换到不同模式,必须修改配置后重新启动集群。

1、单主模式

在单主模式下,只有一个节点可以读写,其他节点提供只读服务。单主模式下,该参数 _ 必须被设置为 FALSE ,当主节点宕掉,自动会根据服务器的server_uuid变量和group_replication_member_weight变量值,选择下一个slave谁作为主节点,group_replication_member_weight的值最高的成员被选为新的主节点,该参数默认为50,建议可以在节点上设置不同值;在group_replication_member_weight值相同的情况下,group根据数据字典中 server_uuid排序,排序在最前的被选择为主节点。

  • 单主模式中发现当前的主服务器,该值VARIABLE_VALUE为实例节点的server_uuid:
select * from performance_schema.global_status WHERE VARIABLE_NAME like '%group_replication%';

2、多主模式

在mysql多主模式下,在组复制中通过Group Replication Protocol协议及Paxos协议,形成的整体高可用解决方案 同时增加了certify的概念,负责检查事务是否允许提交,是否与其它事务存在冲突,Group Replication是由多个节点共同组成一个数据库集群,每个节点都可以单独执行事务,但是read-write(rw)的操作只有在组内验证后才可以commit,Read-only (RO)事务是不需要验证可以立即执行,当一个事务在一个节点上提交之前,会在组内自动进行原子性的广播,告知其他节点变更了什么内容/执行了什么事务,然后为该事物建立一个全局的排序,最终,这意味着所有的服务器都以相同的顺序接收相同的事务集。因此,所有服务器都按照相同的顺序应用相同的变更集,因此它们在组中保持一致。 在多主模式下,该组的所有成员都设置为读写模式,在多主模式下,不支持SERIALIZABLE事务隔离级别,且不能完全支持级联外键约束。

下载 (3)

3、MGR特点

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

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

4.组复制的限制

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

4、搭建MGR组复制

1、环境准备

IP 节点 属性 hostname
64.115.5.33/24 master keepalived+mysql5.7 CentOS76
64.115.5.100/24 slave1 keepalived+mysql5.7 k8s-node1
64.115.5.200/24 slave2 keepalived+mysql5.7 k8s-node2
64.115.5.111/24 VIP 虚拟IP  
#关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
#关闭 SELINUX
swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab && setenforce 0 && sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
#配置域名解析
vim /etc/hosts
64.115.5.100 k8s-node1
64.115.5.200 k8s-node2
64.115.5.33  CentOS76

2、安装配置MYSQL

  • 安装MYSQL
#下载并安装MySQL官方的 Yum Repository
1、 wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
2、 yum -y install mysql57-community-release-el7-10.noarch.rpm
#安装mysql数据库
3、 yum -y install mysql-community-server
  • 配置组复制
[mysqld]
#基本设置
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

#复制框架,根据Mysql组复制要求配置复制
server_id=1  #唯一标识号1 (每台主机不同)
gtid_mode=ON  #组复制使用全局事务标识符,来精确追踪哪些事务已在所有server实例上提交,从而能判断哪些server执行了与已提交事务冲突的事务
enforce_gtid_consistency=ON  #强制GTID的一致性
master_info_repository=TABLE  #将master.info元数据保存在系统表中
relay_log_info_repository=TABLE   #将relay.info元数据保存在系统表中
binlog_checksum=NONE  #禁用二进制日志事件校验
log_slave_updates=ON  #server需记录applier应用的二进制日志
log_bin=binlog  #MySQL组复制会复制二进制日志的内容,因此需打开二进制日志
binlog_format=ROW  #组复制依赖于行的复制格式

#组复制设置
 transaction_write_set_extraction=XXHASH64  ##指示server必须为每个事务收集写集合,并使用XXHASH64哈希算法将其编码为散列
 loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
 loose-group_replication_start_on_boot=off  ##指示插件在server启动时不自动启动组复制
 loose-group_replication_local_address= "64.115.5.33:33061" #每个节点此处为本机的IP及端口
 loose-group_replication_group_seeds= "64.115.5.100:33061,64.115.5.200:33061" #MGR组的所有IP及端口
 loose-group_replication_bootstrap_group=off  ##配置是否自动引导组
 loose-group_replication_ip_whitelist="127.0.0.1,64.115.5.0/24"   ##用户白名单
 loose-group_replication_enforce_update_everywhere_checks=ON  ##多主模式下为多主更新启用或禁用严格一致性检查
 loose-group_replication_single_primary_mode=OFF  ##设置组自动选择一个server来处理读/写工作
 ##group_replication_member_weight=100 #权重,如果多个服务器权重相同会根据server_uuid按字典顺序和选择第一个。
 loose-group_replication_enforce_update_everywhere_checks=OFF  ##单主模式下一致性检查可以关闭
 loose-group_replication_single_primary_mode=ON  ##单主模式
  • 启动修改密码
#启动数据,并设置开机自启
systemctl start  mysqld && systemctl enable   mysqld
#查看运行状态
systemctl status mysqld.service
  • 加载MGR插件,创建同步账号
# 安装MGR插件
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';

#修改ROOT账户初始密码
grep "password" /var/log/mysqld.log
mysql -uroot -p
mysql> SET SQL_LOG_BIN=0;  #关闭二进制日志
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'WANG_feng123';
mysql> flush privileges; 
#创建组复制用户
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'rpl_user123W';  #创建用户设置密码
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';   #授权
mysql> FLUSH PRIVILEGES;  #刷新权限
mysql> SET SQL_LOG_BIN=1;   #打开二进制日志
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_user123W' FOR CHANNEL 'group_replication_recovery';   #设置用户密码
  • 启动MGR单主模式Master执行
# 启动MGR,在主库master上执行
mysql> SET GLOBAL group_replication_bootstrap_group=ON;  ##设置group_replication_bootstrap_group为ON是为了标示以后加入集群的服务器以这台服务器为基准,以后加入的就不需要设置,设置group_replication_bootstrap_group 只需要在master上执行一次,另外两个实例不执行这句
mysql> START GROUP_REPLICATION;   ##作为首个节点启动MGR集群
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
# 查看MGR组信息
mysql> SELECT * FROM performance_schema.replication_group_members;

image-20201216104251974

  • Slave节点加入组
#slave节点执行
mysql> START GROUP_REPLICATION;
mysql> SELECT * FROM performance_schema.replication_group_members;
注: 前面的用户密码修改和创建用户操作必须设置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;

查看状态为ONLINE ,主节点为CentOS76,只有主节点可以写入,其他节点只读,MGR单主模式搭建完成。

image-20201216135729027

参考:

MGR原理及部署

部署

测试

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据