You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 lines
8.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# MySQl组复制
### 组复制部署
**环境准备**
至少需要3台服务器每台服务器上已经完成MySQL 8.0安装
```
192.168.26.160 master
192.168.26.128 node1
192.168.26.130 node2
```
组复制可以以单主或多主模式运行默认是单主模式这里选取192.168.26.160主机名master作为单主读写服务器其他2台为只读服务器。
**查询主库uuid**
3台机器配置文件中的uuid需要一样,在主库使用select uuid()查询,使用主库的uuid即可
```bash
mysql> select uuid();
+--------------------------------------+
| uuid() |
+--------------------------------------+
| a71de24e-0bae-11f0-af42-000c29649a9e |
+--------------------------------------+
1 row in set (0.00 sec)
```
**修改配置文件**
组复制的事务传递是基于GTID的且与部分引擎不兼容因此需要修改相应的参数内容。
修改3台机器配置文件,新增下列参数:
```bash
#----------------认证插件-----------------------
#8.0默认使用的认证插件需要ssl认证,这里修改了认证插件不使用ssl
default_authentication_plugin=mysql_native_password
#----------------Storage_engine----------------
# 组复制的数据必须存储在事务型引擎中。在多主模式下,事务冲突监测的机制是乐观型,即先执行事务,再检测冲突。如果有冲突则所有的成员都必须回滚,因此无法执行回滚的非事务型的存储引擎和组复制不兼容,需要禁用。
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
#----------------Replication----------------
server_id=1 #三台机器不一样
gtid_mode=on
enforce_gtid_consistency=on
binlog_checksum=none
log_bin=mysql-bin
log_slave_updates=on
binlog_format=row
#----------------Group replication----------------
plugin_load_add='group_replication.so'
group_replication_group_name="6afcf923-0ba5-11f0-8fad-000c29649a9e"
group_replication_start_on_boot=off # 在MySQL启动时不会自动启动组复制
group_replication_local_address= "192.168.26.160:33061" #修改成每个节点的ip即可
group_replication_group_seeds= "192.168.26.160:33061, 192.168.26.128:33061, 192.168.26.130:33061"
group_replication_bootstrap_group=off # 设置是否引导组服务即创建一个组一定要设置为off否则每次重启都会引导一个新组出来。
```
**重启服务**
重启服务并通过show plugins命令确认组复制插件已安装
```bash
mysql> show plugins;
```
**设置分布式恢复服务的用户凭证**
当有新成员加入组复制时会通过分布式恢复进程Distributed Recovery Process来同步数据。分布式恢复进程会先找一个数据的捐赠者Donor,并通过一个名为group_replication_reocvery的通道将捐赠者binlog中的事务发送给新成员。在这里需要一个授权用户凭证来建立分布式恢复的连接。这个用户在所有的组成员上都必须存在。
在主库执行下列命令创建连接用户:
```sql
set sql_log_bin=0;
create user repuser@'%' identified with 'mysql_native_password' by 'reppassword';
grant replication slave on *.* to repuser@'%';
grant connection_admin on *.* to repuser@'%';
grant backup_admin on *.* to repuser@'%';
flush privileges;
set sql_log_bin=1;
```
创建好用户后,将用户凭证指定为分布式恢复进程使用:
```sql
change master to master_user='repuser', master_password='reppassword' for channel 'group_replication_recovery';
```
**组复制引导**
第一次启动组复制称作引导引导会创建一个组出来。通过group_replication_bootstrap_group参数来控制引导动作。引导组复制必须由单一服务器完成且只需要执行一次。如果group_replication_bootstrap_group设置为on则每次重启都会创建出一个同名新组这也是前面参数中将其设置为off的原因。
执行下列命令引导组复制:
```sql
set global group_replication_bootstrap_group=on;
start group_replication;
set global group_replication_bootstrap_group=off;
```
**注意**:只有在第一次启动组复制时才需要设置group_replication_bootstrap_group后续成员加入时都不能设置此变量否则会产生经典的分布式系统问题 --- 脑裂split brain
一旦start group_replication;语句成功返回后,组复制就成功启动了,可以通过下列语句确认引导结果:
------------------------------------------------
```sql
select * from performance_schema.replication_group_members;
```
查询结果显示member_state为onlinemember_role为primary说明组复制已经引导成功了。
在主库运行一些事务,mysql8.0默认开始事务:
```sql
create database test;
use test;
create table t1(id int auto_increment primary key);
insert into t1 values(null);
insert into t1 values(null);
insert into t1 values(null);
commit;
```
然后可以通过show binlog events in '日志名';查看二进制日志中的内容,可以看到日志已写入二进制日志此时主库可以作为捐赠者Donor可以将这些事务变更同步给后加入的成员。
**将其他成员加入组复制**
完成前面操作后已经创建出了一个组并且其中已有1台主库在运行了下面需将另外两个成员也加入组复制。
新成员加入组时会有一个数据恢复的动作如果加入时组内数据已经很大了那么这个过程可能会耗费很长时间并且如果主库purge过二进制日志那么恢复会失败。此时应使用备份恢复工具mysqldump/xtrabackup等将待加入的成员数据状态还原至离主库较近的时间点以缩短加入后的数据恢复时间。
本示例是全新环境,数据变更很少,且主库具有所有变更的日志,可以将新成员直接加入,由分布式恢复进程来同步数据。
所有从服务器重启服务并创建分布式恢复凭证
```
set sql_log_bin=0;
create user repuser@'%' identified with 'mysql_native_password' by 'reppassword';
grant replication slave on *.* to repuser@'%';
grant connection_admin on *.* to repuser@'%';
grant backup_admin on *.* to repuser@'%';
flush privileges;
set sql_log_bin=1;
change master to master_user='repuser', master_password='reppassword' for channel 'group_replication_recovery';
```
启动组复制,加入组
```sql
# 注意不需要再引导组了
mysql> start group_replication;
mysql> select * from performance_schema.replication_group_members;
------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | 0a7b9277-0bab-11f0-8d9d-000c29649a9e | master | 3306 | ONLINE | PRIMARY | 8.0.41 | XCom |
| group_replication_applier | aad69d1c-0bab-11f0-bee6-000c29f67e93 | node2 | 3306 | ONLINE | SECONDARY | 8.0.41 | XCom |
| group_replication_applier | b0021552-0baa-11f0-bd9f-000c29b36e90 | node1 | 3306 | ONLINE | SECONDARY | 8.0.41 | XCom |
+---------------------------+--------------------------------------+-------------+-------
```
此时我们看到第二和第三个成员已经成功加入组复制成员角色为secondary状态为online。
### 组复制容错测试
为了测试组复制的容错在主库上直接杀掉MySQL进程非正常关闭模拟服务器宕机。
```sql
killall mysqld
```
**观察角色切换**
在原来的从库上查询成员状态kill命令在两次查询之间执行注意此时服务器node1的角色自动从secondary变为primay表示其被提升为新的主库
```sql
select * from performance_schema.replication_group_members;
```
**原主库重新加入组复制**
将原主库重新启动并加入组复制注意此时宕机的主库将以从库的身份加入组复制不会自动恢复主库身份主库依然是上次切换的node1
```sql
#主库运行下列指令
start group_replication;
select * from performance_schema.replication_group_members;
```