mgr特点
(1)基于paxos协议和原生复制,多数节点同意即可通过事务提交
(2)具备高可用自动故障检测,可自动切换
(3)可弹性扩展,集群自动的新增和移除节点
(4)有单主和多主模式
(5)支持多节点写入,具备冲突检测机制,可以适应多种应用场景需求
mgr组复制是什么
(1)主从复制是异步复制
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无法感知。
(2)半同步复制
基于传统异步存在的缺陷,mysql在5.5版本推出半同步复制。可以说半同步复制是传统异步复制的改进,在master事务的commit之前,必须确保一个slave收到relay
log并且响应给master后(从库收到并产生 relaylog 后会向主库发送一个 ack 的信息包,当主库获得这个包后,认为从库已经获得 relaylog)才能进行事务的commit。但是slave对于relay log的应用仍然是异步进行的。
(3)组复制
基于传统异步复制和半同步复制的缺陷——数据的一致性问题无法保证,mysql官方在5.7.17版本正式推出组复制(mysql group replication,简称mgr)。
由若干个节点共同组成一个复制组,一个事务的提交,必须经过组内大多数节点(n
/ 2
1)决议并通过,才能得以提交。如上图所示,由3个节点组成一个复制组,consensus层为一致性协议层,在事务提交过程中,发生组间通讯,由2个节点决议(certify)通过这个事务,事务才能够最终得以提交并响应。
引入组复制,主要是为了解决传统异步复制和半同步复制可能产生数据不一致的问题。组复制依靠分布式一致性协议(paxos协议的变体),实现了分布式下数据的最终一致性,提供了真正的数据高可用方案(是否真正高可用还有待商榷)。其提供的多写方案,给我们实现多活方案带来了希望。
组复制脱离了传统的主从模式结构,是一个具有容错功能的集群架构,在组复制的架构中,有多个 server成员构成,并且每个成员都可以独立执行事务,也就意味着多写的功能,但是所有的读写事务必须在冲突校验完成后才能提交,如果是只读型的事务那么会直接提交。当某个节点上发出一个读写的事务准备提交时,那么这个节点就会向整个集群开始广播这次读写的变更和对应的一个校验标识符,然后会针对这个事务产生一个全局的顺序号,由于是有顺序号的,所以集群中的每个成员都会按照顺序去执行事务的变更从而保证了数据的一致性。
如果在不同的 server 上执行了相同的操作,并且产生了事务冲突,那么校验机制就会做成相应的判断,通常先提交的事务先执行,后提交的回滚。所以从某种程度上来说,组复制是一种伪同步复制模式。
组复制的模式
(1)单主模式
在单主模式下,组有一个设置为读写模式的单主 server。 组中的所有其他成员被自动设置为只读模式(超级只读模式)。主服务器通常是用于引导组的第一个 server,所有其他加入的 server 自动从主服务器同步并设置为只读。
在单主机模式下,将禁用在多主机模式下部署的某些检查,因为系统会强制在组中每次只有一个写入server。 例如,在单主模式下允许对具有外键的表进行更改,而在多主模式下不允许。 在主服务器故障时,自动选主机制选择下一个主服务器。 通过按字典顺序(使用其 uuid)来排序剩余的 server 成员并选择列表中的第一个成员来作为下一个主服务器。
如果主服务器从组中移除,则启动主节点选择程序,然后从组中的其余 server 成员中选择新的主节点。通过查看新视图,按照词典顺序将 server 的 uuid 进行排序并选择第一个作为主节点。选择了新的主节点后,它将自动设置为只读,其他辅助节点仍然为辅助节点,因此也是只读。
(2)多主模式
多主模式,也就是所有节点都可以写入,每个节点基本都一样
pxc和mgr的区别
(1)执行提交
pxc 事务需要在所有节点跑一下
mgr 多数节点同意,即可执行
(2)复制
pxc 在复制上需要gcache中缓存
mgr 直接写binlog
(3)新增节点
新增节点pxc支持mysqldump xtrabackup
mgr直接集成复制克隆
(4)网络中断
网络中断发生时,pxc具有分区的表不可读写
mgr 可读不可写
(5)流控
mgr 写入变慢
pxc所有节点不可写
(6)跨平台
跨平台;pxc支持linux
mgr支持所有平台
(7)ddl
当pxc在进行ddl时,为了保证节点数据一致,此时整个集群拒绝写操作,注意是集群内所有的表写操作均无法提供写服务,但是读操作可以正常进行。
mgr 采用innodb存储引擎,支持在线ddl
单主搭建(5.7)
规划主机
我这里用三台虚拟机
192.168.168.101 3306
192.168.168.102 3306
192.168.168.103 3306
(1)配置host和ip的映射
在三台主机上分别 vi /etc/hosts
mysql 的组复制依然存在解析 host 的 bug,所以我们必须在所有节点内把 host和 ip 的映射关系配置完毕。
192.168.168.101 master1
192.168.168.102 slave2
192.168.168.103 slave3
(2)关闭防火墙
查看centos7的防火墙
firewall-cmd --state
停止firewall
systemctl stop firewalld.service
禁止firewall开机启动
systemctl disable firewalld.service
(3)快速初始化3台mysql库
1、压缩包解压
tar -xvf mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz
mv mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz /usr/local/mysql
2、配置环境变量
vi /etc/profile
export path=/usr/local/mysql/bin:$path
source /etc/profile
3、编辑mysql配置文件
vi /etc/my.cnf
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/3306/data
log_bin=/data/3306/binlog/mysql-bin
port=3306
server_id=1013306 #(另外两台机器 server_id=1023306\ server_id=1033306)
socket=/tmp/mysql.sock
gtid-mode=on
enforce-gtid-consistency=true
log_slave_updates=1
relay_log_info_repository=table
master_info_repository=table
relay_log_recovery=on
4、创建数据目录和赋权
mkdir -p /data/3306/data
mkdir -p /data/3306/binlog
chown mysql:mysql -r /data
5、初始化
mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql --initialize-insecure --datadir=/data/3306/data --user=mysql &
6、启动
mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &
7、登录
mysql -u root
mysql -s /tmp/mysql3306.sock -u root
(4)配置mgr参数
分别在三台配置文件my.cnf上添加,配置后重启生效
101上:
transaction_write_set_extraction=xxhash64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.101:34901"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"
102上:
transaction_write_set_extraction=xxhash64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.102:34902"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"
103上:
transaction_write_set_extraction=xxhash64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.103:34903"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"
分别将三台库重启
mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &
(5)创建组复制用户
set sql_log_bin=0;
create user repl@'%' identified by 'repl';
grant replication slave on *.* to repl@'%';
flush privileges;
set sql_log_bin=1;
(6)安装组复制插件
在3套库上都安装
install plugin group_replication soname 'group_replication.so';
show plugins;
(7)启动并引导组复制
在单主模式中我们需要默认的选择一个节点作为主节点,并且使这个节点成为引导节点。
选择在101主机上的 mysql 中运行以下的命令
set global group_replication_bootstrap_group=on;
start group_replication;
set global group_replication_bootstrap_group=off;
set global group_replication_bootstrap_group=on; 意思是打开节点的引导模式
start group_replication; 意思是开启同步
set global group_replication_bootstrap_group=off; 在我们将节点一设置为引导节点后关闭
启动报错,查看日志
set @@global.binlog_checksum='none';
在3套库上都需要执行,可以写入配置文件
可以查看到,改节点已经加入到集群中 online
在erro日志中看到到节点 1 已经通过 mgr 的内部通信管理 gcs 加入到节点中
查看是否是主节点,可以看到101主机的库是主节点
select * from performance_schema.replication_group_members;查询节点是否正常
8.0版本可以直接通过表performance_schemaerformance_schema.replication_group_members查看是否是主节点,在5.7中查看是否主节点需要这样查
select if((select
@@server_uuid) = (select variable_value from
performance_schema.global_status where variable_name=
'group_replication_primary_member'), 1, 0) as is_primary_node;
测试:
为了验证组复制是否能做到加入的节点后自动同步,我们这里可以在节点 1 上造一点数据
这里我创建了一些库和一些表。等节点 2 和节点 3 加入组后观察是否同步
create database test;
use test;
create table t(id int,name varchar(30),primary key (`id`));
insert into t select 1,'aa';
(8)节点2加入
set @@global.binlog_checksum='none';
change master to master_user='repl', master_password='repl' for channel 'group_replication_recovery';
start group_replication;
2节点加入到集群,且不是主
如果是8.0的mgr,可以直接从这里查到是否是主
数据也自动同步过来了,验证了组复制新加入的节点数据自动同步
(9)节点3加入
set @@global.binlog_checksum='none';
change master to master_user='repl', master_password='repl' for channel 'group_replication_recovery';
start group_replication;
3节点加入集群,且不是主
可以查看,数据已经同步过来了,再次验证了组复制新加入的节点数据自动同步
注意:配置文件没有写
loose-group_replication_single_primary_mode = true
loose-group_replication_enforce_update_everywhere_checks = false
在5.7中,开始组复制之前,可以手动配置写入
set global group_replication_single_primary_mode=true;
set global group_replication_enforce_update_everywhere_checks = false;
当然如果不写,默认是
多主搭建
多主节点搭建基本和单主步骤一样,只需要配置文件my.cnf额外添加,本文以下示例为单主节点搭建,多主节点搭建亦相差无几
loose-group_replication_single_primary_mode=false
loose-group_replication_enforce_update_everywhere_checks= true
单主搭建(8.0)
1、压缩包解压
tar -xvf mysql-8.0.25-linux-glibc2.12-x86_64.tar
rm -rf /usr/local/mysql
mv mysql-8.0.25-linux-glibc2.12-x86_64 /usr/local/mysql
2、配置环境变量
vi /etc/profile
export path=/usr/local/mysql/bin:$path
source /etc/profile
3、编辑mysql配置文件
vi /etc/my.cnf
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/3306/data
log_bin=/data/3306/binlog/mysql-bin
port=3306
server_id=1013306 #(另外两台机器 server_id=1023306\ server_id=1033306)
socket=/tmp/mysql.sock
gtid-mode=on
enforce-gtid-consistency=true
log_slave_updates=1
relay_log_info_repository=table
master_info_repository=table
relay_log_recovery=on
--101----------------------------------------------------------------------------------------------------------
transaction_write_set_extraction=xxhash64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.101:34901"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"
--102----------------------------------------------------------------------------------------------------------
transaction_write_set_extraction=xxhash64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.102:34902"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"
--103----------------------------------------------------------------------------------------------------------
transaction_write_set_extraction=xxhash64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.103:34903"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"
------------------------------------------------------------------------------------------------------------
4、创建数据目录和赋权
mkdir -p /data/3306/data
mkdir -p /data/3306/binlog
chown mysql:mysql -r /data
5、初始化
mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql --initialize-insecure --datadir=/data/3306/data --user=mysql &
6、启动
mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &
7、登录
mysql -u root
mysql -s /tmp/mysql3306.sock -u root
8、安装组复制插件
install plugin group_replication soname 'group_replication.so';
show plugins;
9、在101上创建复制用户
set sql_log_bin=0;
create user repl@'%' identified with mysql_native_password by 'repl';
grant replication slave on *.* to repl@'%';
grant backup_admin on *.* to repl@'%';
flush privileges;
set sql_log_bin=1;
10、启动并引导组复制
在单主模式中我们需要默认的选择一个节点作为主节点,并且使这个节点成为引导节点。
在 mysql 中运行以下的命令
set global group_replication_bootstrap_group=on;
start group_replication;
set global group_replication_bootstrap_group=off;
11、依次在另外两个节点
change master to master_user='repl', master_password='repl' for channel 'group_replication_recovery';
start group_replication;
如下为8.0的单主三节点mgr集群