官网 https://dev.mysql.com/doc/refman/5.7/en/group-replication.html
master事务的提交不需要经过slave的确认,slave是否接收到master的binlog,master并不care。slave接收到master binlog后先写relay log,最后异步地去执行relay log中的sql应用到自身。由于master的提交不需要确保slave relay log是否被正确接受,当slave接受master binlog失败或者relay log应用失败,master无法感知。
假设master发生宕机并且binlog还没来得及被slave接收,而切换程序将slave提升为新的master,就会出现数据不一致的情况!另外,在高并发的情况下,传统的主从复制,从节点可能会与主产生较大的延迟(当然mysql后续版本陆续做了优化,推出了并行复制,以此降低异步复制的延迟)
基于传统异步存在的缺陷,mysql在5.5版本推出半同步复制。可以说半同步复制是传统异步复制的改进,在master事务的commit之前,必须确保一个slave收到relay log并且响应给master以后,才能进行事务的commit。但是slave对于relay log的应用仍然是异步进行的,原理如下图所示:
基于传统异步复制和半同步复制的缺陷——数据的一致性问题无法保证,MySQL官方在5.7.17版本正式推出组复制(MySQL Group Replication,简称MGR)。
由若干个节点共同组成一个复制组,一个事务的提交,必须经过组内大多数节点(N / 2 + 1)决议并通过,才能得以提交。如上图所示,由3个节点组成一个复制组,Consensus层为一致性协议层,在事务提交过程中,发生组间通讯,由2个节点决议(certify)通过这个事务,事务才能够最终得以提交并响应。
引入组复制,主要是为了解决传统异步复制和半同步复制可能产生数据不一致的问题。组复制依靠分布式一致性协议(Paxos协议的变体),实现了分布式下数据的最终一致性,提供了真正的数据高可用方案(是否真正高可用还有待商榷)。其提供的多写方案,给我们实现多活方案带来了希望。
一个复制组由若干个节点(数据库实例)组成,组内各个节点维护各自的数据副本(Share Nothing),通过一致性协议实现原子消息和全局有序消息,来实现组内实例数据的一致。
组复制可以在两种模式下运行:
OS: Centos7.5
MySQL: 5.7.24
注意:一下配置是单主模式
systemctl stop firewalld
systemctl disable firewalld
vi /etc/selinux/config,修改后重启服务器
SELINUX=disabled
cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.100 mgr1
192.168.56.101 mgr2
192.168.56.102 mgr3
rpm -e 删除mariadb-libs
rpm -ivh mysql-community-common-5.7.24-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.24-1.el7.x86_64.rpm
rpm -ivh mysql-community-devel-5.7.24-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-5.7.24-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.24-1.el7.x86_64.rpm
[root@mgr1 ~]# cat /etc/my.cnf | grep -vE "^#"
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
character-set-server = utf8
collation-server = utf8_unicode_ci
lower_case_table_names = 1
explicit_defaults_for_timestamp = true
server_id=100
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="25aa5618-e940-11e8-a6f6-0800273cba9a"
loose-group_replication_start_on_boot=off #插件在server启动时不自动启动组复制
loose-group_replication_local_address= "192.168.56.100:24901"
loose-group_replication_group_seeds= "192.168.56.100:24901,192.168.56.101:24901,192.168.56.102:24901"
loose-group_replication_bootstrap_group=off
#loose-group_replication_single_primary_mode = off #关闭单主模式的参数
#loose-group_replication_enforce_update_everywhere_checks = on
注意:不同节点红色标注的参数需修改。该配置为最简单
这里再强调一个参数:group_replication_auto_increment_increment
该参数代表自增属性,默认值为7。我们要保证每个成员的该值相同,并且建议该参数的设置尽量比组内成员的个数大一些,方便后期集群的扩展。
systemctl start mysqld
根据/var/log/mysqld.log日志中临时密码,修改root密码
grep password /var/log/mysqld.log
mysql -uroot -p
set password = password('Root@123456');
FLUSH PRIVILEGES;
此需要关闭binlog,使得创建用户不记录到binlog中
SET SQL_LOG_BIN=0;
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.%' IDENTIFIED BY 'Repl@123456';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='repl',MASTER_PASSWORD='Repl@123456' FOR CHANNEL 'group_replication_recovery';
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.11 sec)
mysql> show plugins ; ##检查插件
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
mysql> SELECT * FROM performance_schema.replication_group_members;
CREATE DATABASE test;
USE test;
CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
INSERT INTO t1 VALUES (1, 'Luis');
此需要关闭binlog,使得创建用户不记录到binlog中
SET SQL_LOG_BIN=0;
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.%' IDENTIFIED BY 'Repl@123456';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='repl',MASTER_PASSWORD='Repl@123456' FOR CHANNEL 'group_replication_recovery';
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.11 sec)
mysql> show plugins ; ##检查插件
set global group_replication_allow_local_disjoint_gtids_join=ON;
START GROUP_REPLICATION;
SELECT * FROM performance_schema.replication_group_members;
mysql> show variables like '%read_only%';
测试时发现,从节点直接重启,重新加入集群如需要设置强制加入集群参数,而如果重启主节点且当前节点变过主节点后则不需要加参数直接启动即可。
group_replication_allow_local_disjoint_gtids_join
故先逐个重启主节点,注意主节点重启可能需要change master
SHOW STATUS LIKE 'group_replication_primary_member' ;
此时如果关闭主节点,则其他节点自动会转换为主节点。
START GROUP_REPLICATION;
STOP GROUP_REPLICATION;
loose-group_replication_start_on_boot=on
该参数改为ON
SELECT * FROM performance_schema.replication_group_members;
如果未设置group_replication_ip_whitelist,则该值为AUTOMATIC,mysql会自动添加本机的私有IP地址到白名单中,且mysqld.log日志中出现如下信息
[Note] Plugin group_replication reported: '[GCS] Added automatically IP ranges 10.0.2.9/24,127.0.0.1/8,192.168.56.100/24 to the whitelist
3个节点都需要添加
STOP GROUP_REPLICATION;
SET GLOBAL group_replication_ip_whitelist="127.0.0.1/32,192.168.56.0/24";
START GROUP_REPLICATION;
注意:单主模式和多主模式只是配置文件的区别,其他一样
STOP GROUP_REPLICATION;
set global group_replication_single_primary_mode=OFF;
set global group_replication_enforce_update_everywhere_checks=ON;
修改/etc/my.cnf配置文件,防止重启失效,添加如下参数
loose-group_replication_single_primary_mode = off #关闭单主模式的参数
loose-group_replication_enforce_update_everywhere_checks = on
不支持串行的隔离级别。单个MySQL服务器中,通过锁的方式来实现串行化的隔离级别。而多主模式时,多个成员之间的并发操作无法通过锁来实现串行的隔离级别;
不支持外键的级联操作;
参数:group_replication_enforce_update_everywhere_checks=TRUE 是用来控制是否做以上限制的检测,如果开启了这个参数,当发现这些情况时就会报错;
SELECT * FROM performance_schema.replication_group_members;
SHOW STATUS LIKE 'group_replication_primary_member' ;
show variables like '%read_only%';
任选一个节点
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
其他节点
START GROUP_REPLICATION;
group_replication_recovery_retry_count:加入MGR尝试次数
group_replication_recovery_reconnect_interval : 连接间隔默认1分钟
测试案例查看
https://blog.csdn.net/Mlztesoft/article/details/79927425
1、loose-group_replication_group_name该为MGR的名称,所有节点需一样
2、添加节点需设置set global group_replication_allow_local_disjoint_gtids_join=ON;
3、需设置/etc/hosts文件