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