配置复制组
更改primary
查看当前主节点
1
|
root@(none) 02:12: SELECT * FROM performance_schema.replication_group_members;
|
指定新的主节点进行切换
1
|
root@(none) 02:12: SELECT group_replication_set_as_primary('d1fbe050-5ecf-11eb-a88d-0050569c8f5e');
|
查看进度
1
|
root@(none) 02:12: SELECT event_name, work_completed, work_estimated FROM performance_schema.events_stages_current WHERE event_name LIKE "%stage/group_rpl%";
|
更改复制模式
更改为单主模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
###停止复制
mysql> stop group_replication;
###关闭一致性检查
mysql> set global group_replication_enforce_update_everywhere_checks=OFF;
###开启单主模式
mysql> set global group_replication_single_primary_mode=ON;
###主节点引导组复制
mysql> set global group_replication_bootstrap_group=ON;
mysql> start group_replication
mysql> set global group_replication_bootstrap_group=OFF;
###其它节点加入组复制
mysql> start group_replication
|
Tips:也可以采用SELECT group_replication_switch_to_single_primary_mode(member_uuid)直接进行切换
更改为多主模式
1
2
3
4
5
6
7
8
9
10
|
###停止复制
mysql> stop group_replication;
###关闭单主
mysql> set global group_replication_single_primary_mode=OFF;
###启动复制
mysql> set global group_replication_bootstrap_group=ON;
mysql> start group_replication;
mysql> set global group_replication_bootstrap_group=OFF;
|
Tips:也可以采用SELECT group_replication_switch_to_multi_primary_mode()直接进行切换
查看进度
1
|
mysql> SELECT event_name, work_completed, work_estimated FROM performance_schema.events_stages_current WHERE event_name LIKE "%stage/group_rpl%";
|
配置最大共识实例数
这个最大值被称为组的事件范围,是组可以并行执行的最大共识实例数。
查看复制组写入并发性
1
|
mysql> SELECT group_replication_get_write_concurrency();
|
配置写入并发(需要GROUP_REPLICATION_ADMIN权限)
1
|
mysql> SELECT group_replication_set_write_concurrency(instances);
|
设置组通信协议版本
从MySQL 8.0.16开始,组复制有了组通信协议的概念。可以显式管理组复制通信协议版本,并将其设置为适应您希望组支持的最老的MySQL Server版本。这使得组可以由不同MySQL Server版本的成员组成,同时确保向后兼容性。
查看当前通信协议版本
1
|
mysql> SELECT group_replication_get_communication_protocol();
|
修改通信协议版本
1
|
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 |
只读 |
现有如下表
1
2
3
4
5
6
7
8
9
10
|
root@test 04:19: show create table t1;\
+-------+-------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (
`id` int NOT NULL,
`r1` int DEFAULT NULL,
`r2` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
|
插入一条数据,其它节点也能正常读取到
1
2
3
4
5
6
7
8
9
|
root@test 04:21: insert into t1 values (1,2,@@server_id);
Query OK, 1 row affected (0.00 sec)
root@test 04:21: select * from t1;
+----+------+------+
| id | r1 | r2 |
+----+------+------+
| 1 | 2 | 2109 |
+----+------+------+
|
查看一致性级别
1
2
3
4
5
6
|
root@test 04:23: show variables like 'group_replication_consistency';
+-------------------------------+----------+
| Variable_name | Value |
+-------------------------------+----------+
| group_replication_consistency | EVENTUAL |
+-------------------------------+----------+
|
在节点2上手动添加read锁
1
2
|
root@test 04:21: lock table t1 read;
Query OK, 0 rows affected (0.00 sec)
|
再次插入新数据
1
2
|
root@test 04:21: insert into t1 values (2,3,@@server_id);
Query OK, 1 row affected (0.01 sec)
|
在节点2上并未读取到新插入的数据
1
2
3
4
5
6
|
root@test 04:23: select * from t1;
+----+------+------+
| id | r1 | r2 |
+----+------+------+
| 1 | 2 | 2109 |
+----+------+------+
|
释放锁之后就能读取最新数据
1
2
3
4
5
6
7
8
9
10
|
root@test 04:26: unlock tables;
Query OK, 0 rows affected (0.00 sec)
root@test 04:26: select * from t1;
+----+------+------+
| id | r1 | r2 |
+----+------+------+
| 1 | 2 | 2109 |
| 2 | 3 | 2109 |
+----+------+------+
|
下面将节点2的级别调整为before进行测试
1
|
root@test 04:26: set @@group_replication_consistency='before';
|
再次加锁
1
|
root@test 04:29: lock table t1 read;
|
节点1插入新数据
1
|
root@(test) 04:29: insert into t1 values (3,4,@@server_id);
|
这时发现,再去节点2查询表会hang住,需要等待本地数据完全应用。节点3则正常查询
下面将节点2的级别调整为AFTER
1
2
|
root@(test) 04:34: set @@group_replication_consistency='after';
Query OK, 0 rows affected (0.00 sec)
|
重复加锁的过程
1
|
root@(test) 04:35: lock table t1 read;
|
在节点1插入新数据
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一致性级别时,所有写操作都被挂起,但并不是所有读操作都被阻塞,我们任然可以执行一些运维管理命令。