0. 内容提纲
• 1. 部署环境及初始化
• 2. 利用MySQL Shell构建MGR集群
• 3. 对在线的MGR集群添加一个新节点
• 4. 部署MySQL Router,实现读写分离以及故障自动转移
MySQL InnoDB Cluster(简称MIC)是MySQL推出的整套解决方案,由几个部分组成:
• MySQL Server,核心是Group Replication(组复制),简称MGR。
• MySQL Shell,可编程的高级客户端,支持标准SQL语法、JavaScript语法、Python语法,以及API接口,可以更方便的管理和使用MySQL服务器。
• MySQL Router,轻量级中间件,支持透明路由规则(读写分离及读负载均衡)。
本文详细介绍如何利用MIC和GreatSQL构建MGR集群,并结合MySQL Router实现读写分离、读负载均衡以及故障自动转移架构。
为了简单起见,这个MGR集群采用单主(single-primary)模式,不采用多主(multi-primary)模式。
整体系统架构如下图所示:

1. 部署环境及初始化
为了简单起见,建议用yum方式标准化安装MySQL Shell、Router以及社区版。
如果还没MySQL官方的yum源,需要先下载安装repo包,下载地址:
选择正确对应OS的版本下载并安装即可,例如:
之后就可以用yum安装MySQL相关的软件包了。
除了MySQL官方社区版本外,如果想体验更可靠、稳定、高效的MGR,推荐使用GreatSQL版本。本文采用GreatSQL 8.0.22版本,关于这个版本的说明详见 GreatSQL,打造更好的MGR生态。
GreatSQL二进制包放在 /usr/local/ 下,即 basedir = /usr/local/GreatSQL-8.0.22。
MGR集群由三个实例构成,按下面规划分配:

另外,为了mysqld服务管理方便,我直接修改系统systemd里关于mysqld服务的配置文件约第52行:
修改完,保存退出,执行下面的命令让systemd重新加载配置文件:
这样就可以利用systemd来管理mysqld服务了。
由于 /usr/bin/mysqld_pre_systemd 中需要调用 /usr/sbin/mysqld 二进制文件,因此这个也要替换掉:
为了能让mysqld改用jemalloc,也同时编辑文件:
这是一份配置参考(可自行根据实际情况适当调整):
最后直接启动mysqld服务即可(首次启动会自行完成初始化):
初始化时会为root账号生成一个临时密码,例如这样的:
首次用这个密码登入后,就要立即进行修改,否则其他什么也做不了:
用同样的方法,完成其他节点的MySQL实例初始化,确认运行的GreatSQL版本号。
2. 利用MySQL Shell构建MGR集群
利用MySQL Shell构建MGR集群主要简单几个命令就可以了,确实是要比手动方式部署便捷很多。
只需三步就好:
• 检查实例是否满足条件。
• 创建并初始化一个集群。
• 逐个添加实例。
想要使用MySQL Shell构建MGR集群,除了需要先满足MGR的基本要求(必须InnoDB表,且必须要有主键等)之外,还要满足其他几个条件:
• Python版本 >= 2.7。
• 启用PFS(performance_schema)。
• 各节点的server_id要唯一。
接下来就可以开始了。
MySQL实例启动后,利用 mysqlsh 这个MySQL Shell客户端工具连接到服务器端:
tips: mysqlsh 也可以像 mysql 客户端那样使用 pager:
1、检查实例是否满足安装MGR集群的条件 接下来,执行 dba.configureInstance() 命令开始检查当前实例是否准备好了,可以作为MGR集群的一个节点:
上述 dba.configureInstance() 方法同样在其他节点上也执行一遍。
2、创建一个MGR集群 各节点初始化完毕后,用mysqlsh客户端,用新建MGR的管理账号登入PRIMARY节点,准备创建MGR集群:
集群已经创建并初始化完毕,接下来就是继续添加其他节点了。
3、添加其他节点 可以在PRIMARY节点上直接添加其他节点,也可以用mysqlsh客户端登入其他节点执行添加节点操作,这里采用前者:
同样的操作,也在 GreatSQL-03:3306 节点上执行一遍,将其加入MGR集群中。
当所有节点都加入MGR集群后,查看集群状态:
# 查看线程列表
MySQL 172.16.16.10:3306 ssl JS > \sql show processlist;
+-------+----------------------------+-------------------+------+---------+-------+--------------------------------------------------------+----------------------------------+-----------+---------------+
| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined |
+-------+----------------------------+-------------------+------+---------+-------+--------------------------------------------------------+----------------------------------+-----------+---------------+
| 9 | system user | | NULL | Connect | 19935 | waiting for handler commit | Group replication applier module | 0 | 0 |
| 12 | system user | | NULL | Query | 5 | Slave has read all relay log; waiting for more updates | NULL | 0 | 0 |
| 13 | system user | | NULL | Query | 5 | Waiting for an event from Coordinator | NULL | 0 | 0 |
| 14 | system user | | NULL | Connect | 19934 | Waiting for an event from Coordinator | NULL | 0 | 0 |
| 20425 | mic | GreatSQL-01:42678 | NULL | Query | 0 | init | show processlist | 0 | 0 |
| 38381 | mysql_router1_2ya0m3z4582s | GreatSQL-01:54034 | NULL | Sleep | 1 | | NULL | 4 | 4 |
+-------+----------------------------+-------------------+------+---------+-------+--------------------------------------------------------+----------------------------------+-----------+---------------+
# 查看集群结构
MySQL 172.16.16.10:3306 ssl JS > mic.describe();
{
"clusterName": "greatsqlMGR",
"defaultReplicaSet": {
"name": "default",
"topology": [
{
"address": "GreatSQL-01:3306",
"label": "GreatSQL-01:3306",
"role": "HA"
},
{
"address": "GreatSQL-02:3306",
"label": "GreatSQL-02:3306",
"role": "HA"
},
{
"address": "GreatSQL-03:3306",
"label": "GreatSQL-03:3306",
"role": "HA"
}
],
"topologyMode": "Single-Primary"
}
}
#查看集群详细状态
MySQL 172.16.16.10:3306 ssl JS > mic.status();
{
"clusterName": "greatsqlMGR",
"defaultReplicaSet": {
"name": "default",
"primary": "GreatSQL-01:3306",
"ssl": "REQUIRED",
"status": "OK",
"statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
"topology": {
"GreatSQL-01:3306": {
"address": "GreatSQL-01:3306",
"memberRole": "PRIMARY",
"mode": "R/W",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.22"
},
"GreatSQL-02:3306": {
"address": "GreatSQL-02:3306",
"memberRole": "SECONDARY",
"mode": "R/O",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.22"
},
... <-- 其余信息略过
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "GreatSQL-02:3306"
}
#或者可以加上 {extended:1} 扩展属性,会打印更多信息
MySQL 172.16.16.10:3306 ssl JS > mic.status({extended:1});
{
"clusterName": "greatsqlMGR",
"defaultReplicaSet": {
"GRProtocolVersion": "8.0.16",
"groupName": "fbc510f0-c5ba-11eb-bfaf-5254002eb6d6",
"groupViewId": "16228692455693206:28",
"name": "default",
"primary": "GreatSQL-01:3306",
"ssl": "REQUIRED",
"status": "OK",
"statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
"topology": {
"GreatSQL-01:3306": {
"address": "GreatSQL-01:3306",
"applierWorkerThreads": 2,
"fenceSysVars": [],
"memberId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb1",
"memberRole": "PRIMARY",
"memberState": "ONLINE",
"mode": "R/W",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.22"
},
"GreatSQL-02:3306": {
"address": "GreatSQL-02:3306",
"applierWorkerThreads": 2,
"fenceSysVars": [
"read_only",
"super_read_only"
],
"memberId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb2",
"memberRole": "SECONDARY",
"memberState": "ONLINE",
"mode": "R/O",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.22"
},
... <-- 其余信息略过
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "GreatSQL-01:3306",
"metadataServer": "GreatSQL-01:3306",
"metadataVersion": "2.0.0"
}
#也可以用SQL命令行方式查看
MySQL 172.16.16.10:3306 ssl JS > \sql select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb1 | GreatSQL-01 | 3306 | ONLINE | PRIMARY | 8.0.22 |
| group_replication_applier | bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb2 | GreatSQL-02 | 3306 | ONLINE | SECONDARY | 8.0.22 |
| group_replication_applier | bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb3 | GreatSQL-03 | 3306 | ONLINE | SECONDARY | 8.0.22 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
到这里,利用MySQL Shell就轻松构建一个三节点的MGR集群了。
3. 对在线的MGR集群添加一个新节点
上面的MGR集群已经上线了,现在想添加一个新节点 GreatSQL-04:3306,步骤和上面基本上一样,三步走:
• 用有管理权限的账号登入MySQL实例(用mysqlsh客户端)。
• 执行 dba.configureInstance() 函数预处理。
• 执行 cluster.addInstance() 函数加入集群。
详细过程就不赘述了,自行操作。
如果是想删除一个节点,则改成执行 cluster.removeInstance() 函数即可。
4. 部署MySQL Router,实现读写分离以及故障自动转移
MySQL Router是一个轻量级的中间件,它采用多端口的方案实现读写分离以及读负载均衡,而且同时支持mysql和mysql x协议。
1、mysqlrouter初始化 MySQL Router对应的服务器端程序文件是 /usr/bin/mysqlrouter,第一次启动时要先进行初始化:
2、启动mysqlrouter服务 这就初始化完毕了,按照上面的提示,直接启动 mysqlrouter 服务即可:
可以看到 mysqlrouter 服务正常启动了。
mysqlrouter 初始化时自动生成的配置文件是 /etc/mysqlrouter/mysqlrouter.conf,主要是关于R/W、RO不同端口的配置,例如:
可以根据需要自行修改绑定的IP地址和端口。
3、确认读写分离效果 现在,用客户端连接到6446(读写)端口,确认连接的是PRIMARY节点:
同样地,连接6447(只读)端口,确认连接的是SECONDARY节点:
4、确认只读负载均衡效果 该连接保持住不退出,继续新建到6447端口的连接,查看 server_uuid,应该会发现读取到的是 GreatSQL-03 节点的值,因为 mysqlrouter 的读负载均衡机制是在几个只读节点间自动轮询(只读请求是不会打到PRIMARY节点的)。
5、确认故障自动转移功能 接下来模拟PRIMARY节点宕机或切换时,mysqlrouter 也能实现自动故障转移。
登入MGR集群任意节点:
回到前面连接6446端口的那个会话,再次查询 server_uuid,此时会发现连接自动断开了:
这就实现了自动故障转移。
再次查看切换后的MGR集群状态:
至此,利用InnoDB Cluster配合GreatSQL构建一套支持读写分离、读负载均衡以及故障自动转移的MGR集群就部署完毕了。
本文转载自公共号GreatSQL社区。