前言
MySQL 常见的“集群”方案有很多种,比如主从复制、Group Replication、InnoDB Cluster、Galera Cluster、NDB Cluster 等。它们解决的问题并不完全相同。
如果你希望继续使用最常见的 InnoDB 存储引擎,同时又希望获得高可用、自动故障转移和较完整的官方管理工具,比较推荐使用 MySQL InnoDB Cluster。
MySQL InnoDB Cluster 底层基于 Group Replication,通常配合以下组件使用:
| 组件 | 作用 |
|---|---|
| MySQL Server | 真正存储数据的数据库实例 |
| Group Replication | 多节点复制和选主机制 |
| MySQL Shell | 官方集群管理工具,提供 AdminAPI |
| MySQL Router | 客户端访问入口,负责把请求路由到合适节点 |
本文以 3 台 Ubuntu 服务器为例,记录一套从安装到验证的部署流程。
集群规划
假设有 3 台服务器:
| 节点 | 主机名示例 | 内网 IP | 角色 |
|---|---|---|---|
| node1 | VM-0-8-ubuntu | 10.4.0.8 |
初始 PRIMARY 节点 |
| node2 | VM-0-7-ubuntu | 10.4.0.7 |
SECONDARY 节点 |
| node3 | VM-0-9-ubuntu | 10.4.0.9 |
SECONDARY 节点 |
需要放通的常用端口:
| 端口 | 说明 |
|---|---|
3306 |
MySQL 客户端连接端口 |
33060 |
MySQL X Protocol,MySQL Shell 可能会用到 |
33061 |
Group Replication 节点内部通信端口 |
如果服务器开启了防火墙,需要在 3 个节点之间放通这些端口。
安装 MySQL Server 和 MySQL Shell
以下命令需要在 3 个节点上都执行。
sudo apt update
sudo apt install -y mysql-server mysql-shell
安装完成后检查 MySQL 状态:
sudo systemctl status mysql
mysql --version
如果 MySQL 正常运行,可以看到 active (running)。
Ubuntu 默认安装的 MySQL 通常会把 root 用户配置为 auth_socket 认证方式,也就是没有一个固定的 root 默认密码。可以直接使用下面的命令登录:
sudo mysql -u root
登录后可以确认 root 认证插件:
SELECT user, host, plugin
FROM mysql.user
WHERE user = 'root';
如果看到:
root | localhost | auth_socket
说明 root 只能通过本机 sudo/socket 登录,而不是通过密码远程登录。
调整 MySQL 监听地址
Ubuntu 默认配置里常见如下内容:
bind-address = 127.0.0.1
mysqlx-bind-address = 127.0.0.1
这会导致其他节点无法通过内网 IP 连接当前 MySQL。需要修改为内网 IP 或 0.0.0.0。
编辑配置文件:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
建议修改为:
bind-address = 0.0.0.0
mysqlx-bind-address = 0.0.0.0
然后重启 MySQL:
sudo systemctl restart mysql
确认 3306 已监听:
ss -lntp | grep 3306
创建集群管理账号
不建议长期直接使用 root 管理集群。可以创建一个专用的集群管理账号。
在 3 个节点上分别执行:
sudo mysql -u root
创建账号:
CREATE USER 'clusterAdmin'@'%' IDENTIFIED BY '请替换为强密码';
GRANT ALL PRIVILEGES ON *.* TO 'clusterAdmin'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
生产环境可以按最小权限原则收敛权限。本文为了降低初次部署复杂度,先使用较宽的管理权限完成集群初始化。
测试从 node1 连接其他节点:
mysql -h 10.4.0.7 -u clusterAdmin -p
mysql -h 10.4.0.9 -u clusterAdmin -p
如果无法连接,优先检查:
bind-address是否仍是127.0.0.1。- 防火墙或安全组是否放通
3306。 clusterAdmin是否允许从%或对应内网网段登录。
使用 MySQL Shell 配置实例
下面操作可以在 node1 上执行。
进入 MySQL Shell:
mysqlsh clusterAdmin@10.4.0.8:3306
切换到 JavaScript 模式:
\js
依次检查并配置 3 个实例:
dba.configureInstance('clusterAdmin@10.4.0.8:3306')
dba.configureInstance('clusterAdmin@10.4.0.7:3306')
dba.configureInstance('clusterAdmin@10.4.0.9:3306')
dba.configureInstance() 会检查实例是否满足 InnoDB Cluster 要求,并提示需要修改哪些配置。常见会涉及:
server_idgtid_modeenforce_gtid_consistencybinlog_format- Group Replication 相关配置
- 是否需要重启 MySQL
如果 MySQL Shell 提示需要重启实例,可以在对应节点执行:
sudo systemctl restart mysql
然后重新执行 dba.configureInstance(),直到提示实例已经适合加入 InnoDB Cluster。
创建 InnoDB Cluster
在 node1 的 MySQL Shell 中创建集群:
var cluster = dba.createCluster('prodCluster')
添加 node2:
cluster.addInstance('clusterAdmin@10.4.0.7:3306')
添加 node3:
cluster.addInstance('clusterAdmin@10.4.0.9:3306')
查看集群状态:
cluster.status()
正常情况下,可以看到类似信息:
"status": "OK",
"topology": {
"10.4.0.8:3306": {
"memberRole": "PRIMARY",
"status": "ONLINE"
},
"10.4.0.7:3306": {
"memberRole": "SECONDARY",
"status": "ONLINE"
},
"10.4.0.9:3306": {
"memberRole": "SECONDARY",
"status": "ONLINE"
}
}
使用 SQL 验证 Group Replication 状态
也可以登录任意 MySQL 节点,通过 SQL 查看底层 Group Replication 状态。
mysql -h 10.4.0.8 -u clusterAdmin -p
查看当前主节点:
SHOW STATUS LIKE 'group_replication_primary_member';
查看集群成员:
SELECT *
FROM performance_schema.replication_group_members;
重点看这几个字段:
| 字段 | 说明 |
|---|---|
MEMBER_HOST |
成员节点主机名 |
MEMBER_PORT |
MySQL 端口,通常是 3306 |
MEMBER_STATE |
ONLINE 表示节点正常在线 |
MEMBER_ROLE |
PRIMARY 或 SECONDARY |
MEMBER_VERSION |
MySQL 版本 |
如果某个节点显示 RECOVERING,表示它正在恢复或同步。可以等待一段时间后再次查询。如果长时间不变,再查看错误日志。
sudo tail -n 200 /var/log/mysql/error.log
安装和引导 MySQL Router
MySQL Router 用来给应用提供统一访问入口。应用不需要直接关心当前哪个节点是主节点。
安装:
sudo apt install -y mysql-router
在 Router 所在机器执行 bootstrap:
sudo mysqlrouter --bootstrap clusterAdmin@10.4.0.8:3306 --user=mysqlrouter
启动并设置开机自启:
sudo systemctl enable --now mysqlrouter
sudo systemctl status mysqlrouter
常见 Router 端口如下,具体以 bootstrap 后生成的配置为准:
| 端口 | 用途 |
|---|---|
6446 |
读写端口,通常路由到 PRIMARY |
6447 |
只读端口,通常路由到 SECONDARY |
应用侧可以优先连接 Router 的 6446 端口,而不是直接连接某个 MySQL 节点。
手动配置 Group Replication 时的注意事项
如果不使用 MySQL Shell AdminAPI,而是手动写 mysqld.cnf 配置 Group Replication,要特别注意下面几个点。
不要写 group_replication = ON
有些教程会写:
group_replication = ON
这个配置可能导致 MySQL 启动失败,并在错误日志中出现:
unknown variable 'group_replication=ON'
更推荐使用插件加载配置:
plugin_load_add = group_replication.so
group_replication_group_name 必须是 UUID
不能写普通字符串,例如:
group_replication_group_name = "zhimengart-mysql-group"
否则启动时会看到类似错误:
The group_replication_group_name 'zhimengart-mysql-group' is not a valid UUID
应该生成一个 UUID:
uuidgen
或者在 MySQL 中生成:
SELECT UUID();
然后配置为:
group_replication_group_name = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
3 个节点必须使用同一个 group_replication_group_name。
group_replication_local_address 和 group_replication_group_seeds
group_replication_local_address 是当前节点用于集群内部通信的地址,通常使用 33061 端口。
示例:
group_replication_local_address = "10.4.0.8:33061"
group_replication_group_seeds 是种子节点列表,通常可以写所有节点的内部通信地址:
group_replication_group_seeds = "10.4.0.8:33061,10.4.0.7:33061,10.4.0.9:33061"
3 个节点建议保持一致,便于维护。
初次启动不要长期打开 bootstrap_group
第一个节点初始化集群时才需要:
SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;
其他节点只执行:
START GROUP_REPLICATION;
不要让多个节点同时以 bootstrap 模式启动,否则可能形成多个独立集群。
常见问题排查
root 密码是多少
Ubuntu 通过 apt install mysql-server 安装后,root 通常没有默认密码,而是使用 auth_socket:
sudo mysql -u root
如果需要确认:
SELECT user, host, plugin
FROM mysql.user
WHERE user = 'root';
如果确实要改成密码登录,可以执行:
ALTER USER 'root'@'localhost'
IDENTIFIED WITH caching_sha2_password BY '请替换为强密码';
FLUSH PRIVILEGES;
但做集群管理时,更推荐使用专门的 clusterAdmin,不要长期依赖 root。
MySQL 重启失败,unknown variable group_replication=ON
查看日志:
sudo tail -n 100 /var/log/mysql/error.log
如果看到:
unknown variable 'group_replication=ON'
说明配置文件里写了无效参数。删除:
group_replication = ON
改为:
plugin_load_add = group_replication.so
然后重启:
sudo systemctl restart mysql
START GROUP_REPLICATION 报 ERROR 3092
错误示例:
ERROR 3092 (HY000): The server is not configured properly to be an active member of the group.
优先看错误日志:
sudo tail -n 200 /var/log/mysql/error.log
常见原因包括:
group_replication_group_name不是合法 UUID。server-id重复。gtid_mode或enforce_gtid_consistency未开启。group_replication_local_address写成了127.0.0.1,其他节点无法访问。33061端口未放通。- Group Replication 插件未加载。
START GROUP_REPLICATION 报 ERROR 3093
错误示例:
ERROR 3093 (HY000): The START GROUP_REPLICATION command failed since the group is already running.
这说明当前节点的 Group Replication 已经运行,不需要重复启动。直接查询状态即可:
SELECT *
FROM performance_schema.replication_group_members;
节点一直是 RECOVERING
如果某个节点长时间停留在 RECOVERING:
SELECT *
FROM performance_schema.replication_group_members;
可以检查该节点日志:
sudo tail -n 200 /var/log/mysql/error.log
重点排查:
- 节点之间
33061是否互通。 - 数据目录是否已有冲突数据。
server_uuid是否重复,尤其是通过复制虚拟机镜像创建节点时。cluster.addInstance()时是否需要选择 clone 或 incremental recovery。
可视化和监控工具
MySQL InnoDB Cluster 可以配合以下工具管理或监控:
| 工具 | 适用场景 |
|---|---|
| MySQL Shell | 官方管理工具,适合创建集群、查看状态、切换主节点 |
| MySQL Workbench | 图形化连接数据库,适合日常查询和基础管理 |
| MySQL Router | 应用访问入口,不是监控工具,但生产集群通常需要 |
| Prometheus + Grafana | 指标采集和可视化监控 |
| Percona Monitoring and Management | 专业 MySQL 监控和查询分析 |
| ClusterControl | 更完整的数据库集群管理平台 |
日常检查集群状态,最直接的方式仍然是 MySQL Shell:
mysqlsh clusterAdmin@10.4.0.8:3306 -- cluster status
或者进入 MySQL Shell 后执行:
var cluster = dba.getCluster()
cluster.status()
总结
Ubuntu 上部署 MySQL InnoDB Cluster,建议优先使用 MySQL Shell 的 AdminAPI,而不是手动拼 Group Replication 配置。核心流程是:
- 3 个节点安装
mysql-server和mysql-shell。 - 修改监听地址,确保节点之间可以访问
3306、33060、33061。 - 创建专用集群管理账号。
- 使用
dba.configureInstance()检查并配置实例。 - 使用
dba.createCluster()创建集群。 - 使用
cluster.addInstance()添加其他节点。 - 使用
cluster.status()和performance_schema.replication_group_members验证状态。 - 生产环境通过 MySQL Router 提供统一访问入口。
部署过程中最容易踩坑的是 root 的 auth_socket 认证、bind-address 仍然绑定本地、group_replication_group_name 不是 UUID、以及误写 group_replication = ON。遇到启动失败时,优先看 /var/log/mysql/error.log,日志通常会直接指出具体配置问题。
文章标签
冬眠
博主专注于技术、阅读与思考。在这里记录学习、思考与生活。
