MySQL组复制(二)
配置复制组
更改primary
查看当前主节点
root@(none) 02:12: SELECT * FROM performance_schema.replication_group_members; |
指定新的主节点进行切换
root@(none) 02:12: SELECT group_replication_set_as_primary('d1fbe050-5ecf-11eb-a88d-0050569c8f5e'); |
查看进度
root@(none) 02:12: SELECT event_name, work_completed, work_estimated FROM performance_schema.events_stages_current WHERE event_name LIKE "%stage/group_rpl%"; |
更改复制模式
更改为单主模式
###停止复制 |
Tips:也可以采用SELECT group_replication_switch_to_single_primary_mode(member_uuid)直接进行切换
更改为多主模式
###停止复制 |
Tips:也可以采用SELECT group_replication_switch_to_multi_primary_mode()直接进行切换
查看进度
mysql> SELECT event_name, work_completed, work_estimated FROM performance_schema.events_stages_current WHERE event_name LIKE "%stage/group_rpl%"; |
配置最大共识实例数
这个最大值被称为组的事件范围,是组可以并行执行的最大共识实例数。
查看复制组写入并发性
mysql> SELECT group_replication_get_write_concurrency(); |
配置写入并发(需要GROUP_REPLICATION_ADMIN权限)
mysql> SELECT group_replication_set_write_concurrency(instances); |
设置组通信协议版本
从MySQL 8.0.16开始,组复制有了组通信协议的概念。可以显式管理组复制通信协议版本,并将其设置为适应您希望组支持的最老的MySQL Server版本。这使得组可以由不同MySQL Server版本的成员组成,同时确保向后兼容性。
查看当前通信协议版本
mysql> SELECT group_replication_get_communication_protocol(); |
修改通信协议版本
SELECT group_replication_set_communication_protocol("5.7.25"); |
Tips:当升级组复制成员MySQL Version后,通信协议并不会自动更新,我们可以手动升级协议版本
事务一致性保证
就分布式一致性保证而言,无论是在正常或故障修复的情况下,组复制始终是一个最终一致性的系统。与系统一致性相关的事件包含控制操作和数据流操作,对于组复制,可以根据一致性评估的控制操作为:
- 成员加入或离开
- 网络故障
- 单主模式下,主节点故障切换或通过group_replication_set_as_primary()重新选主
在单主模式下,当主节点发生故障进行转移时,新的主节点可以立即应用程序流量,不管有多少事务复制积压。这种情况写一致性得到了保证,但是在新节点应用backlog中的事务前可能检索到过时数据,无法保证读一致性。如果采用8.0.14或更高版本时,可以在主节点故障切换期间使用group_replication_consistency变量配置成员提供的事务一致性保证级别。该参数有下列选择
- EVENTUAL:RO和RW事务在执行之前都不等待前面的事务被应用(8.0.14前的唯一选择)
- BEFORE:确保本地强一致性,并不保证其它节点数据实时同步,可能造成当前节点读延迟
- AFTER:确保全局一致性,可以保证所有节点数据实时同步,可能造成所有节点都延迟
- BEFORE_AND_AFTER:最高级别,结合BEFORE和AFTER来确保本地和全局强一致性
- BEFOR_ON_PRIMARY_FAILOVER: 确保新主的本地一致性,在新选出的主节点上保存新事务,直到应用完积压事务为止
一致性级别的影响
围绕一致性级别对事务的影响我们通过下列案例来重点说明EVENTUAL、BEFORE和AFTER选项的影响
节点 | 角色 |
---|---|
节点1 | 主 |
节点2 | 只读 |
节点3 | 只读 |
现有如下表
root@test 04:19: show create table t1;\ |
插入一条数据,其它节点也能正常读取到
root@test 04:21: insert into t1 values (1,2,@@server_id); |
查看一致性级别
root@test 04:23: show variables like 'group_replication_consistency'; |
在节点2上手动添加read锁
root@test 04:21: lock table t1 read; |
再次插入新数据
root@test 04:21: insert into t1 values (2,3,@@server_id); |
在节点2上并未读取到新插入的数据
root@test 04:23: select * from t1; |
释放锁之后就能读取最新数据
root@test 04:26: unlock tables; |
下面将节点2的级别调整为before进行测试
root@test 04:26: set @@group_replication_consistency='before'; |
再次加锁
root@test 04:29: lock table t1 read; |
节点1插入新数据
root@(test) 04:29: insert into t1 values (3,4,@@server_id); |
这时发现,再去节点2查询表会hang住,需要等待本地数据完全应用。节点3则正常查询
下面将节点2的级别调整为AFTER
root@(test) 04:34: set @@group_replication_consistency='after'; |
重复加锁的过程
root@(test) 04:35: lock table t1 read; |
在节点1插入新数据
root@(test) 04:35: insert into t1 values (3,4,@@server_id); |
这时会发现插入处于等待状态,并没有完成,因为节点2上的表被锁了,无法完成日志应用。节点2查询成功,但都为陈旧数据。节点3上的查询也需要等待其它从节点日志应用完成才能返回结果,而不是返回陈旧数据。当节点2释放锁之后,节点1的插入完成,节点3的查询也返回了最新数据。
单主模式发生故障转移后,为避免在EVENTUAL选项下RO事务可能读取到过时数据导致的一致性问题,建议使用适当的流控设置,减小事务积压的可能。并将一致性级别设置为BEFORE_ON_PRIMARY_FAILOVER。尽管在使用BEFORE_ON_PRIMARY_FAILOVER一致性级别时,所有写操作都被挂起,但并不是所有读操作都被阻塞,我们任然可以执行一些运维管理命令。