今天接着写一些MGR的细节内容吧。
MGR对外提供服务的时候有2种服务模式,分别是单主模式和双主模式。
单主模式:只有一个成员对外提供服务。单主模式和异步模式比较类似,有了主从复制的经验,维护单主模式的MGR其实并不难,下面的图说明了单主模式下的一些特点:
多主模式:所有成员同时对外提供写服务,都是master,彼此之间会自动进行数据复制。
多主模式下,需要注意以下几个问题:
1、数据冲突问题
MGR在多主模式下,为了避免冲突,自增主键的设置需要格外注意。针对同一个表,如果存在并发,需要使用auto_increment_offset参数和auto_increment_increment参数来控制自增的起始值和步长。其中:
auto_increment_offset是自增值的起始值
auto_increment_increment是自增长的步长值
例如,一个组里面有3个成员,最合理的方法是设置:
成员A自增值:1、4、7、10
成员B自增值:2、5、8、11
成员C自增值:3、6、9、12
三个成员的自增列起始值分别为1、2、3,但是自增长的值都是3.
这种设计方法,需要提前对自增值进行规划,如果没有提前规划,例如我们的例子,想要加入第四个节点,必然会发生主键冲突。
2、DDL的并发执行问题
多主模式下,一般通过冲突检测来辨别有冲突的事务,冲突之后进行回滚操作。但是由于DDL操作无法回滚。因此MGR中没有多DDL做冲突检测。包含DDL的语句,需要在同一台服务器上执行,否则容易造成数据的不一致问题。
举例:
成员A
begin; insert into t xxx;
成员B
truncate t;
成员A
commit;
此时,成员A的执行顺序是:
begin;insert into t xxx;truncate t;commit
成员B的执行顺序是:
truncate t;begin;insert into t xxx;commit
必然造成数据的不一致。
3、应用层需要将请求分发到多个成员
如果app层需要使用多主模式的MGR,需要能够将应用层的请求分发到多个成员上。可以通过下面几个方法来解决:
a、备用连接,如果主连接无法访问数据库服务,可以使用备用连接进行访问。
b、域名访问,主服务宕机之后,主动将域名映射到新的可用的MySQL服务上。
c、要去控制DDL的使用,当有DDL要更新的时候,需要将所有的写请求转移到同一台MySQL上执行。
d、将多主模式当成单主模式来用,这样可以避免DDL的冲突,而且还能规避脑裂的问题
e、应用分级,将不同的应用分布到多主模式不同的MySQL服务上面。
单主模式和多主模式的切换:
Binlog Event的多线程执行
MGR创建的时候,会自动创建一个通道来执行接收到的Binlog Event,通道名字是group_replication_applier,当加入组时,GR插件会自动启动该通道的执行线程,也及时Applier Thread,当然,用户也可以手工来开启和停止这个通道的执行线程:
start slave sql_thread for channel 'group_replication_applier';
stop slave sql_thread for channel 'group_replication_applier';
多线程执行,少不了多线程执行的三个关键参数:
1、set global slave_parallel_type='logical_clock';
2、set global slave_parallel_workers=N;
3、set global slave_preserve_commit_order=ON;
其中:
参数type是设置并行复制类型的,可以设置为database,表示建荣MySQL5.6的按照库级别并行的方案,设置为logical_clock表示按照事务是否同时处于prepare和commit阶段来决定是否可以并行提交。
workers参数是指代并行的队列数量,
order参数打开之后可以保证applier上执行事务的提交顺序和源MySQL服务器上的提交顺序相同。一般情况下,建议打开。
MGR一些基本参数:
1、group_reolication_group_name
这个是MGR的名字,如果不同的成员的组名称不同,则不能加入到一个组里面。一般要求是一个UUID,所有成员共用。
set group_reolication_group_name=<UUID>
2、group_replication_local_address
每个成员都要有一个独立的TCP端口,成员之间通过这个端口进行通信,该参数就是天蝎成员的IP地址和相关端口
set group_replication_local_address=<IP:PORT>
3、group_replication_group_seeds
当某个成员加入一个组的时候,新成员必须和组内的成员进行通信来加入组,这些组内的成员我们称之为种子成员,这个参数就是用来设置种子成员的地址
set global group_replication_group_seeds=<ip:port>,<ip:port>
这个变量配置的是其他成员的group_replication_local_address的内容。
4、group_replication_whitelist
设置成员IP白名单,MGR通过白名单来控制哪些IP地址的MySQL服务能够加入到组里面来,白名单的值可以是一个地址列表,也可以是具体的IP,也可以是网段。
set group_replication_whitelist=<ip:net,...>
如果不配置白名单,MGR会自动识别本机网口上配置的私网地址和私网网段,只允许和自己在同私网网段的MySQL服务器连接到自己的端口。同时,127.0.0.1本机的连接始终是被允许的。
5、group_replication_force_members
当某些故障导致MGR一半以上的节点无法访问的时候,为了强制恢复MySQL服务,可以使用上述参数来强制指定某几个成员来组成MGR,而放弃其他成员,注意,慎用这个参数,使用前需要确保其他MySQL不会对外提供服务,否则可能导致脑裂现象。