MGR高可用集群
MGR高可用集群
目录
1MGR高可用集群
2.MGR的优缺点
2.1.组复制需要满足以下要求
3.MGR单主模式搭建
4.从单主模式扩到多主模式
5. 从多主模式扩到单主模式
6. 故障切换
7. MGR状态监控
8. MGR客户端连接
1.MGR概述和架构
Group Replication是MySQL官方发布的一个开源插件,用来实现MySQL高可用集群。
2016.12月Group Replication的第一个GA版本正式发布于MySQL5.7.17中。想要使用Group Replication功能,需要安装MySQL5.7.17及以后的版本。
组的概念:
Group Replication插件中有组(group)的概念,被Group Replication插件连接在一起的MySQL服务器是一个高可用组,组内的MySQL服务器被称为成员(Member)。
Group Replication在传输数据时,使用了paxos协议,保证了数据传输的一致性和原子性。
Paxos是用于一种分布式系统并且具有容错性的一致性算法,是目前业界公认能解决分布式系统一致性问题的算法之一。
服务模式:
单主模式
多主模式
当主宕机之后,会自动选举新的主,无需人工干预。
2.MGR的优缺点
2.1.组复制需要满足以下要求
1.innodb存储引擎。
2.主键。主键或者not null的唯一键(unique)
3.网络。网络延迟和网络带宽都会影响MGR的性能和稳定性。最好是在局域网中(千兆、万兆)。
4.需要开启GTID。
5数据库版本须在5.7.17以上。
2.2.优点
1. 避免脑裂:MGR中不会出现脑裂的现象(但要注意可能出现网络分区的情况,MGR根据参数group_replication_unreachable_majority_timeout=0/N设置的不同,行为稍有不同)。
2. 数据一致性保障:MGR的冗余能力很好,能够保证Binlog Event至少被复制到超过一半的成员上,只要同时宕机的成员不超过半数便不会导致数据丢失。
MGR还保证只要Binlog Event没有被传输到半数以上的成员,本地成员不会将事务的Binlog Event写入Binlog文件和提交事务,
从而保证宕机的服务器上不会有组内在线成员上不存在的数据。因此,宕机的服务器重启后,不再需要特殊的处理就可以加入组。
3. 多节点写入支持:多写模式下支持集群中的所有节点都可以写入。
2.3.缺点
(1)仅支持InnoDB表,并且每张表一定要有一个主键(或者非空唯一键),用于做write set的冲突检测;
(2)必须打开GTID特性,二进制日志格式必须设置为ROW,用于选主与write set
(3)COMMIT可能会导致失败,类似于快照事务隔离级别的失败场景
(4)目前一个MGR集群最多支持9个节点
(5)不支持外键于save point特性,无法做全局间的约束检测与部分部分回滚
(6)二进制日志不支持binlog event checksum
(7)不支持间隙锁。认证过程没考虑间隙锁。推荐使用READ COMMITED事务隔离级别,在此级别innodb不使用间隙锁。MySQL默认的事务隔离级别为REPEATABLE-READ。
show variables like '%isolation%';
select @@tx_isolation;
select @@transaction_isolation;
(8)表锁和命名锁。认证过程没有考虑表锁和命名锁。
(9)多主模式不支持SERIALIZABLE隔离级别。
(10)多主模式下不支持并发(DDL-DML)操作。
(11)多主模式下不支持具有级联约束的外键,如果group_replication_single_primary_mode=ON,
设置group_replication_enforce_update_everywhere_checks=ON。在单主模式下支持。
(12)多主模式死锁。多主模式下SELECT .. FOR UPDATE可能导致死锁。
(13)不支持复制过滤。
2.4.事务大小限制
如果单个事务导致消息内容足够大,以致于无法在5秒的时间内通过网络在组成员之间复制消息,则可能会怀疑成员失败了,然后将其驱逐出局。
限制事务大小。
group_replication_transaction_size_limit 来指定组将接受的最大事务大小,默认为0。
group_replication_compression_threshold在该消息大小之上进行压缩
3.MGR单主模式搭建
环境准备:
主机名 | IP | 系统 | 数据库版本 |
db01 | 192.168.230.101 | CentOS7.6 | 5.7.28 |
db02 | 192.168.230.102 | CentOS7.6 | 5.7.28 |
db03 | 192.168.230.103 | CentOS7.6 | 5.7.28 |
3.1.1准备工作
3.1.1.检查三台服务器防火墙状态
systemctl status firewalld
iptables -L(检查端口是否开放)
修改selinux配置
vi /etc/selinux/config
3.1.2.设置主机名
vi /etc/hosts
在101上:
vi /etc/hostname(另外两台分别修改为db02,db03)
然后重启服务
reboot
3.1.3.安装密码插件
2:在101上:
2.1:在101上修改mysql的配置文件
先要在mysql里面
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
3.2.修改配置文件
以101为例(修改102.103从库的配置文件):
vi /etc/my.cnf
[mysqld] validate_password = OFF character_set_server = utf8mb4 server_id = 101 gtid_mode = ON enforce_gtid_consistency = ON master_info_repository = TABLE #将master.info元数据保存在系统表中 relay_log_info_repository = TABLE #将relay.info元数据保存在系统表中 binlog_checksum = NONE #禁用二进制日志事件校验 log_slave_updates = ON #级联复制A->B->C log_bin = mysql-bin binlog_format= ROW #以行的格式记录 transaction_write_set_extraction = XXHASH64 #使用哈希算法 loose-group_replication_group_name= '5a421130-2674-11ea-bbce-00505639ee45' loose-group_replication_start_on_boot = off #不自动启用组复制集群 loose-group_replication_local_address = '192.168.230.101:33061' #本机地址和端口 loose-group_replication_group_seeds='192.168.230.101:33061,192.168.230.102:33061,192.168.230.103:33061' #组中成员,主机名:通讯端口 loose-group_replication_bootstrap_group = off #不启用引导组,手动引导启动 |
注释:loose-group_replication_group_name 里面的内容是select uuid();的内容,而不是show variables like '%uuid%';
重启mysql服务
systemctl restart mysqld
3.5启动MGR单主模式
3.5.1.启动db01上的group replication集群
set global group_replication_bootstrap_group=ON; start group_replication; set global group_replication_bootstrap_group=OFF; |
3.5.2.启动db02上的group replication集群
start group_replication; |
3.5.3.启动db03上的group replication集群
start group_replication; |
3.3.安装组复制插件
在101,102,103上:
install plugin group_replication soname 'group_replication.so';
3.4.建立复制账号
[root@db01 ~]# mysql -uroot -p123456 set SQL_LOG_BIN=0; grant replication slave on *.* to repl@'%' identified by '123456'; flush privileges; set SQL_LOG_BIN=1; change master to master_user='repl',master_password='123456' for channel 'group_replication_recovery'; |
3.6.查询组复制状态
SELECT * FROM performance_schema.replication_group_members;
3.7.测试组复制
3.7.1.db01上(主)
create database fxdb default character set utf8mb4; use fxdb; create table tbs01(id int, name varchar(20));--无主键 insert into tbs01 values(1, 'fxkt');
create table tbs02(id int primary key, name varchar(20)); insert into tbs02 values(1, 'fxkt');
|
3.7.2.主上可读写,其它成员只读
show variables like '%read_only%'; super_read_only为ON
|
3.8.查询哪个是主库
show global status like '%primary_member%'; 或 select * from performance_schema.global_status where variable_name='group_replication_primary_member'; 或 SELECT * FROM replication_group_members a INNER JOIN global_status b ON a.member_id = b.variable_value WHERE b.variable_name = 'group_replication_primary_member'; |
4.从单主模式扩到多主模式
环境准备:
主机名 | IP | 系统 | 数据库版本 |
db01 | 192.168.230.101 | CentOS7.6 | 5.7.28 |
db02 | 192.168.230.102 | CentOS7.6 | 5.7.28 |
db03 | 192.168.230.103 | CentOS7.6 | 5.7.28 |
4.1.在db01,db02,db03上
停止组复制
stop group_replication; |
在所有节点执行:
set global group_replication_single_primary_mode=OFF; set global group_replication_enforce_update_everywhere_checks=ON; set global transaction_isolation= READ-COMMITTED; 或在配置文件中添加如下参数,并重启服务 group_replication_single_primary_mode=off#关闭单主模式 group_replication_enforce_update_everywhere_checks=ON #冲突检测 #多主模式下,强制检查每一个实例是否允许该操作,如果不是多主,可以关闭 transaction_isolation= READ-COMMITTED |
4.2.在db01上
SET GLOBAL group_replication_bootstrap_group=ON; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=OFF; |
4.3.在db02,db03上
start group_replication; |
4.4.查看MGR状态
select * from performance_schema.replication_group_members;
4.5.测试多主模式
use fxdb; create table tbs03(id int primary key,name varchar(20)); insert into tbs03 values(1, 'fxkt1'); --db01节点执行 insert into tbs03 values(2, 'fxkt2'); --db02节点执行 insert into tbs03 values(3, 'fxkt3'); --db03节点执行 |
所有成员读写。
show variables like '%read_only%'; super_read_only为OFF
|
查询主:
show global status like '%primary_member%';
或 select * from performance_schema.global_status where variable_name='group_replication_primary_member';
SELECT * FROM PERFORMANCE_SCHEMA .replication_group_members a INNER JOIN PERFORMANCE_SCHEMA .global_status b ON a.member_id = b.variable_value WHERE b.variable_name = 'group_replication_primary_member'; |
4.6.修改数据库隔离级别
多主复制时,通过冲突检测来辨别有冲突的事物,有冲突的事务进行回滚。MySQL DDL(创建表,修改表结构)无法回滚,group replication没有对DDL做冲突检测。在同一库DDL会被阻塞。
1修改隔离级别为READ-COMMITTED
transaction_isolation= READ-COMMITTED
db01 | db02 |
create table v1(id int primary key); begin; insert into v1 values(1);
| use fxdb; select * from v1;
|
| truncate v1; |
commit; |
|
在db01上:
在db02上:
db03:1条数据
结果:
db01:无数据
db02:1条数据
db03:1条数据
2在不同主库下执行两个事务:
db01,db02上两个事物的执行顺序:
truncate t1;
insert into v1 values(1);
会出现上述冲突
3若两个事务都在db01不同会话上执行:
truncate t1;
insert into v1 values(1);
不会出现上述冲突
4自增字段的处理:
如果不配置auto_increment_increment和auto_increment_offset,则会将group_replication_auto_increment_increment和server_id的值替代。
show variables like '%increment%';
create table tbs05(id int primary key auto_increment,name varchar(20)); insert用工具在db01,db02,db03上插入数据,看他们的id如何变化 |
5. 从多主模式扩到单主模式
5.1.在db01,db02,db03上
停止组复制
stop group_replication; |
在所有节点执行:
set global group_replication_single_primary_mode=ON; set global group_replication_enforce_update_everywhere_checks=OFF; 或在配置文件中添加如下参数,并重启服务 set global group_replication_single_primary_mode=ON; set global group_replication_enforce_update_everywhere_checks=OFF; |
5.2.在db01上
SET GLOBAL group_replication_bootstrap_group=ON; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=OFF; |
5.3.在db02,db03上
start group_replication; |
5.4.查看MGR状态
select * from performance_schema.replication_group_members;
6. 故障切换
6.1.主库挂掉
ps -ef |grep mysql
pkill mysqld
6.2.查询组复制状态
SELECT * FROM performance_schema.replication_group_members;
6.3.查询那个是主库
SELECT * FROM replication_group_members a INNER JOIN global_status b ON a.member_id = b.variable_value WHERE b.variable_name = 'group_replication_primary_member'; |
在103
在103上写入一条数据,发现db02同步过去
然后开启db01的服务:
6.4.恢复挂掉的主库
此时集群中并没有加入db01
start group_replication;
SELECT * FROM performance_schema.replication_group_members;
在db01上:
show variables like '%read_only%';
此时还是db03是主
7. MGR状态监控
7.1.Group Replication状态信息
Group Replication的状态信息被存储到了performance_schema中的几个表中:
replication_group_members
replication_group_member_stats
replication_applier_status
replication_connection_status
7.2.replication_group_members
存储着组内所有成员的基本信息,从任何一个成员上都能查询到这些基本信息。
CHANNEL_NAME:Group Replication执行Binlog Event的通道,值为group_replication_applier。
MEMBER_STATE:成员状态。
有以下5种状态:
OFFLINE:组复制插件没启动,为OFFLINE状态。
RECOVERING:当组复制插件启动时,首先设置为此状态,开始复制加入前的数据。
ONLINE:recover完之后,设置为此状态,开始对外提供服务。
ERROR:当本地成员发生错误时,设置为此状态。
UNREACHABLE:网络故障或宕机,设置为此状态。
replication_group_member_stats:
存储着本地成员的详细信息,每个成员上只能查询到自己的详细信息。
CHANNEL_NAME:Group Replication执行Binlog Event的通道,值为group_replication_applier。
VIEW_ID:组视图ID
COUNT_TRANSACTIONS_IN_QUEUE:队列中等待做全局事务认证的事务数量。
COUNT_TRANSACTIONS_CHECKED:做了全局事务认证的事务总数量。
COUNT_CONFLICTS_DETECTED:全局事务认证时,有冲突的事务总数量。
COUNT_TRANSACTIONS_ROWS_VALIDATING:冲突检测数据库的记录总行数。
TRANSACTIONS_COMMITTED_ALL_MEMBERS:在所有成员上已经执行的事务的GTID集合。不是实时的,每隔一段时间更新一次。
LAST_CONFLICT_FREE_TRANSACTION:最后一个没有冲突的事务的GTID。
replication_connection_status:
异步复制通道连接信息
group_replication_applier
group_replication_recovery
replication_applier_status:
db01 | db02 |
create table v3(id int primary key auto_increment,name varchar(20)); use v3; insert into v3 values(1, 'aa','aa'); begin; update v3 set c2='bbb' where id=1;
| use v3; begin; update v3 set c3='bbb' where id=1;
|
Commit(在攥写栏同时提交) | commit |
提交成功 | 提交失败,回滚 |
8. MGR客户端连接
适用条件:适用于单主模式,不适用多主模式,多主模式可以联合mycat实现负载均衡;
MGR(组复制)官方推荐用MySQL router中间件去做MGR高可用故障转移,但其多过了一层网络,性能会下降,并且需要额外维护一套中间件,运维成本过高。
https://github.com/hcymysql/mgr_failover_vip
/sbin/ifconfig ens33:1 192.168.3.230/24 (255.255.255.0)
/sbin/ifconfig ens33:1 down