一、MGR 介绍
MGR 集群简介
MySQL Group Replication(简称 MGR)是 MySQL 官方于 2016 年 12 月推出的一个全新的高
可用与高扩展的解决方案。MySQL 组复制提供了高可用、高扩展、高可靠的 MySQL 集群服务
MGR 的特点
1、高一致性,基于原生复制及 paxos 协议的 组复制技术 ,并以插件的方式提供,提供一致数据安全 保证;
2、高容错性,只要不是大多数节点坏掉就可以继续工作,有自动检测机制,当不同节点产生资源争 用冲突时,不会出现错误,按照先到者优先原则进行处理,并且内置了自动化脑裂防护机制;
3、高扩展性,节点的新增和移除都是自动的,新节点加入后,会自动从其他节点上同步状态,直到 新节点和其他节点保持一致,如果某节点被移除了,其他节点自动更新组信息,自动维护新的组信息;
4、高灵活性,有单主模式和多主模式,单主模式下,会自动选主,所有更新操作都在主上进行;多 主模式下,所有 server 都可以同时处理更新操作。
MGR 是 MySQL 数据库未来发展的一个重要方向。
小结:高一致性,高容错性,高扩展性,高灵活性
MGR 基础结构要求
1)引擎必须为 innodb,因为需事务支持在 commit 时对各节点进行冲突检查
2)每个表必须有主键,在进行事务冲突检测时需要利用主键值对比
3)必须开启 binlog 且为 row 格式
4)开启 GTID,且主从状态信息存于表中(--master-info-repository=TABLE 、--relay-log
info-repository=TABLE),--log-slave-updates 打开
什么是 GTID?
GTID(Global Transaction ID)是对于一个 已提交事务的编号 ,并且是一个 全局唯一的编号 。
GTID 实际上是由 UUID+TID 组成的。其中 UUID 是一个 MySQL 实例的唯一标识。TID 代表了该实例
上已经提交的事务数量,并且随着事务提交单递增。下面是一个 GTID 的具体形式
3E11FA47-71CA-11E1-9E33-C80AA9429562:23
5)一致性检测设置--transaction-write-set-extraction=XXHASH64
MGR 使用限制:
1. 和普通复制 binlog 校验不能共存,需设置--binlog-checksum=none
2. 不支持 gap lock(间隙锁),隔离级别需设置为 read_committed
3. 不支持对表进行锁操作(lock /unlock table),不会发送到其他节点执行 ,影响需要对表进行加 锁操作的情况,列入 mysqldump 全表备份恢复操作
4. 不支持 serializable(序列化)隔离级别
5. DDL 语句不支持原子性,不能检测冲突,执行后需自行校验是否一致, 不支持外键:多主不支持,单主模式不存在此问题
最多支持 9 个节点:超过 9 台 server 无法加入组
————————————————
二、部署 MGR 集群
环境准备
关闭所以服务器防护墙和slinux
systemctl stop firewalld && setenforce 0
数据库服务器规划
安装MySQL
所以节点安装
上传 mysql-5.7.tar.gz 到 Linux 主机上,并解压:
注:mysql-5.7.tar.gz 中包括了安装 mysql5.7 主要的软件包。 这样部署起来更方便
[root@xuegod63 ~]# scp mysql-5.7.tar.gz xuegod64:/root/
[root@xuegod63 ~]# scp mysql-5.7.tar.gz xuegod65:/root/
安装 mysql
注:所有 mysql 节点全部安装,由于临时密码不同,此处省略 64、65节点安装初始化过程
[root@xuegod63 ~]# tar xvf mysql-5.7.tar.gz
[root@xuegod63 ~]# yum -y install ./mysql*.rpm
[root@xuegod63 ~]# systemctl start mysqld
#启动 MySQL 会生成临时密码
在 MySQL 的配置文件/etc/my.cnf 中关闭密码强度审计插件,并重启 MySQl 服务。
[root@xuegod63 ~]# vim /etc/my.cnf #修改 MySQL 的配置文件,在[myqld]标签
处末行添加以下项:
validate-password=OFF
#不使用密码强度审计插件
[root@xuegod63 ~]# systemctl restart mysqld #重启 MySQL 服务
[root@xuegod63 ~]# grep 'password' /var/log/mysqld.log #获取临时密码。
2018-08-01T09:59:33.918961Z 1 [Note] A temporary password is generated for
root@localhost: buL.UJp!T2Od #临时密码
[root@xuegod63 ~]# mysql -u root -p'buL.UJp!T2Od' #使用临时密码登录 MySQl, 注意临时密码要引号
mysql> set password for root@localhost = password('123456'); #修改 root 用户密
码为 123456
mysql> flush privileges; #刷新权限
配置主机名解析
在三台数据库服务器上都设置:
[root@xuegod63 ~]# vim /etc/hosts
192.168.0.63 xuegod63
192.168.0.64 xuegod64
192.168.0.65 xuegod65
[root@xuegod63 ~]# scp /etc/hosts xuegod64:/etc/hosts
[root@xuegod63 ~]# scp /etc/hosts xuegod65:/etc/hosts
配置 xuegod63 主节点
服务器 xuegod63 配置/etc/my.cnf
[root@xuegod63 ~]# vim /etc/my.cnf #最下面添加
# Group Replication
server_id = 100 #服务 ID
gtid_mode = ON #全局事务
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 #级联复制
log_bin = binlog #开启二进制日志记录
binlog_format = ROW #以行的格式记录
transaction_write_set_extraction = XXHASH64 #使用哈希算法将其编码为散列
loose-group_replication_group_name = 'ce9be252-2b71-11e6-b8f4-00212844f856' #加入的组名
loose-group_replication_start_on_boot = off #不自动启用组复制集群
loose-group_replication_local_address = 'xuegod63:33061' #以本机端口 33061 接受来自组中成员的传入连接
loose-group_replication_group_seeds = 'xuegod63:33061, xuegod62:33062, xuegod64:33063' #组中成员访问表
loose-group_replication_bootstrap_group = off #不启用引导组
重启 MySQL 服务
[root@xuegod63 ~]# systemctl restart mysqld
服务器 xuegod63.cn 上建立复制账号:
[root@xuegod63 ~]# mysql -u root -p123456
mysql> set SQL_LOG_BIN=0; #停掉日志记录
mysql> grant replication slave on *.* to repl@'192.168.0.%' identified by '123456';
mysql> flush privileges;
mysql> set SQL_LOG_BIN=1; #开启日志记录
mysql> change master to master_user='repl',master_password='123456' for channel
'group_replication_recovery'; #构建 group replication 集群
在 MySQL 服务器 xuegod63.cn 上安装 group replication 插件
安装插件
mysql> install PLUGIN group_replication SONAME 'group_replication.so';
查看 group replication 组件
mysql> show plugins;
启动服务器 xuegod63.cn 上 MySQL 的 group replication
mysql> set global group_replication_bootstrap_group=ON;
mysql> start group_replication;
mysql> set global group_replication_bootstrap_group=OFF;
mysql> select * from performance_schema.replication_group_members #查看状态
测试服务器 xuegod63.cn 上的 MySQL
mysql> create database test;
mysql> use test;
mysql> create table t1 (id int primary key,name varchar(20)); #注意创建主键
mysql> insert into t1 values (1,'man');
mysql> select * from t1;
mysql> show binlog events;
集群中添加 xuegod64 主机
修改/etc/my.cnf 配置文件,方法和之前相同vim /etc/my.cnf
# Group Replication
server_id = 101 #注意服务 ID 不一样
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 = 'ce9be252-2b71-11e6-b8f4-00212844f856'
loose-group_replication_start_on_boot = off
loose-group_replication_local_address = 'xuegod64:33062'
loose-group_replication_group_seeds=' xuegod63:33061,xuegod64:33062,xuegod65:33063'
loose-group_replication_bootstrap_group = off
重启 MySQL 服务
[root@xuegod64 ~]# systemctl restart mysqld
用户授权
[root@xuegod64 ~]# mysql -u root -p123456
mysql> set SQL_LOG_BIN=0; #停掉日志记录
mysql> grant replication slave on *.* to repl@'192.168.0.%' identified by '123456';
mysql> flush privileges;
mysql> set SQL_LOG_BIN=1; #开启日志记录
mysql> change master to master_user='repl',master_password='123456' for channel 'group_replication_recovery'; #构建 group replication 集群
安装 group replication 插件
mysql> install PLUGIN group_replication SONAME 'group_replication.so';
把实例添加到之前的复制组
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;
mysql> start group_replication;
在 xuegod63.cn 上查看复制组状态
mysql> select * from performance_schema.replication_group_members;
在新加的实例上查看数据库发现 test 库和 t1 表已经同步
mysql> show databases;
集群中添加 xuegod65 主机修改/etc/my.cnf 配置文件,方法和之前相同vim /etc/my.cnf
# Group Replication
server_id = 102 #注意服务 ID 不一样
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 = 'ce9be252-2b71-11e6-b8f4-00212844f856'
loose-group_replication_start_on_boot = off
loose-group_replication_local_address = 'xuegod65:33063'
loose-group_replication_group_seeds ' xuegod63:33061,xuegod64:33062,xuegod65:33063'
loose-group_replication_bootstrap_group = off
重启 MySQL 服务
[root@xuegod64 ~]# systemctl restart mysqld
用户授权
[root@xuegod64 ~]# mysql -u root -p123456
mysql> set SQL_LOG_BIN=0; #停掉日志记录
mysql> grant replication slave on *.* to repl@'192.168.1.%' identified by '123456';
mysql> flush privileges;
mysql> set SQL_LOG_BIN=1; #开启日志记录
mysql> change master to master_user='repl',master_password='123456' for channel
'group_replication_recovery'; #构建 group replication 集群
安装 group replication 插件
mysql> install PLUGIN group_replication SONAME 'group_replication.so';
把实例添加到之前的复制组
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;
mysql> start group_replication;
在 xuegod63.cn 上查看复制组状态
mysql> select * from performance_schema.replication_group_members;
以上单 master 节点的集群就搭建完毕!
MGR集群维护
mysql> show variables like 'group_replication%'; #查看集群参数设置列表
查看是否只读 show variables like '%read_only%';
另外两台查看
扩展-multi-primary 多主模式
1. 该模式启用需设置两个参数
group_replication_single_primary_mode=0 #这个参数很好理解,就是关闭单 master 模式
group_replication_enforce_update_everywhere_checks=1 #这个参数设置多主模式下各个节
点严格一致性检查
2. 默认启动的都是单 master 模式,其他节点都设置了 read_only、super_read_only 这两个参
数,需要修改这两个配置
3. 完成上面的配置后就可以执行多点写入了,多点写入会存在冲突检查,这耗损性能挺大的,官方
建议采用网络分区功能,在程序端把相同的业务定位到同一节点,尽量减少冲突发生几率。
由单主模式修改为多主模式方法
第一种:在原来单主模式的主节点执行操作如下:
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> stop GROUP_REPLICATION;
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;(即使含有组中不存在的事 务,也允许当前 server 加入组)
mysql> set global group_replication_single_primary_mode=off;
mysql> set global group_replication_enforce_update_everywhere_checks=ON;
mysql> start group_replication;
第二种:直接搭建多主 master 模式
在所有节点上执行,my.cnf 配置文件,vim /etc/my.cnf
# Group Replication
server_id = 100 #服务 ID
gtid_mode = ON #全局事务
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 #级联复制
log_bin = binlog #开启二进制日志记录
binlog_format= ROW #以行的格式记录
transaction_write_set_extraction = XXHASH64 #使用哈希算法将其编码为散列
loose-group_replication_group_name = 'ce9be252-2b71-11e6-b8f4-00212844f856' #加 入的组名
loose-group_replication_start_on_boot = off #不自动启用组复制集群
loose-group_replication_local_address = 'xuegod63:33061' #以本机端口 33061 接受来自组
中成员的传入连接
loose-group_replication_group_seeds = 'xuegod63:33061,xuegod64:33062,xuegod65:33063' #组中成员访问表
loose-group_replication_bootstrap_group = off #不启用引导组
group_replication_single_primary_mode = off #关闭单 master 模式
group_replication_enforce_update_everywhere_checks = ON #多主一致性检查
查看是否只读
mysql>show variables like '%read_only%';
发现现在 read_only 都是 OFF 了