今天接着写写MGR的一些特性,开始之前,先回顾一下之前的一些内容:
MGR是MySQL官方开发的一个开源插件,和其他的异步复制和半同步复制不同,它是利用了MySQL的组复制技术来实现高可用的一种解决方案,保证了数据的强一致性。MySQL在5.7.17版本中正式引入。所谓的组是指多个MySQL服务器被Group Replication插件连接在一起,组内的成员通过组管理服务实现了自动化的管理功能。对于用户来讲,只需要将新的服务器加入到已有的组里面,或者从已有的组里面剔除故障服务器即可,组内的通信方式,用户可以无需关心。
当组内的成员出现切换的时候,用户不比使用change master等语句来修改复制关系,这个故障切换的过程会自动完成。
01
MGR服务模式
MGR对外提供服务的服务模式有两种,一种是单主模式,一种是多主模式。
单主模式其实类似我们的一主多从的服务模式,其中只有一个成员提供更新服务,其他的成员只提供查询服务,提供更新服务的成员我们称之为主成员,其他的称之为从成员;
如何选举第一个主成员?
当第一次搭建MGR环境的时候,第一个初始化的成员就是自动选举成为主成员,其他的成员就成为从成员。
主节点挂了怎么办?
单主模式下,如果主节点挂了,那么其他的成员会自动选举出新的主成员,成员之间可以通过配置权重来确定下一个主成员是谁,如果没有配置权重,则会对所有在线成员的UUID进行排序,然后选取UUID最小的成员作为主成员,用户在任意一个在线的成员上都能够查询到主成员的UUID,查询方法如下:
show global status like '%group_replica%';
+----------------------------------+--------------------------------------+
| Variable_name | Value |
+----------------------------------+--------------------------------------+
| Com_group_replication_start | 6 |
| Com_group_replication_stop | 2 |
| group_replication_primary_member | XXXXXXX-fba1-11e9-8397-00XXXXXXX3852 |
+----------------------------------+--------------------------------------+
3 rows in set (0.00 sec)
如何控制从成员只能读,不能写?
当一个成员加入组的时候,GR插件会自动将MySQL变成只读模式,只有被选取为主成员后才会自动切换回读写模式,这个功能是通过参数super_read_only来控制的。
多主模式,所有的组内成员对外提供读写服务,是真正意义上的并发,MGR对于高并发有很好的的处理能力。多主模式下,组内所有成员没有主从之分,对用户来说,就像在操作一个MySQL一样。
如何处理自增变量?
使用多主模式的时候,如何处理自增变量是一个必须考虑的问题,我们可以通过下面两个方法解决这个问题:
1、直接使用系统变量auto_increment_offset和auto_increment_increment两个参数来保证自增字段不重复
2、使用group_replication_auto_increment_increment的值来指定自增长的步长,这个参数的默认值是7。如果MySQL中的成员的server-id是顺序的,类似1,2,3,4,5这种,那么就不需要额外的配置,如果server-id不是顺序的,则会自动将server-id和group_replication_auto_increment_increment的值设置到auto_increment_offset和auto_increment_increment两个系统变量中,从而保证自增的值是不重复的。如果我们有三台服务器,然后server-id分别是1、2、3,而参数group_replication_auto_increment_increment=3,那么三台服务器上id的值将会是下面这样:
这种情况下,我们没有浪费一个自增值,但是存在一个潜在的问题,就是当我们的机器需要扩展的时候,我们发现无论第4个服务器设置成什么自增值,随着数据记录增多,必然和前面3个服务器中的某一个产生冲突。
所以,多主模式下,设置自增值的时候一定要提前规划,避免自增主键冲突的麻烦。
多主模式在下面的场景下存在一定的限制:
1、不支持串行的隔离级别
2、DDL语句并发执行的时候会存在问题。
也是由于这些缺点,建议的方法是将多主模式试做"不用切换的主从模式"来使用。这样可以避免出现DDL和其他语句的冲突。
02
通信模式
在MGR通信过程中,并不会使用binlog event的传输机制,也不使用MySQL的服务端口进行通信,而是通过一个独立的TCP端口来进行通信。各个MySQL上的GR插件通过这个端口连接在一起,例如MySQL的实例端口是4306,而通信端口的信息可能是44444,像下面这样:
show variables like '%group_replication_local_address%';
+---------------------------------+---------------------+
| Variable_name | Value |
+---------------------------------+---------------------+
| group_replication_local_address | 192.168.7.XXX:44444 |
+---------------------------------+---------------------+
1 row in set (0.00 sec)
实质上,MGR是使用Paxos协议构建了一个分布式的状态机复制机制,这是实现多主复制的核心技术,它的存在使得MGR不会出现脑裂现象,而且只要同时当家的成员不超过半数,数据便不会丢失,而且保证了只要binlog event没有被传输到半数以上的成员的情况下,本地成员不会将事务的binlog event写入到binlog,这样就避免了故障重启的时候,该故障机器上有其他组内成员不存在的数据。