1、介绍
MySQL InnoDB Cluster(MIC)是基于 MySQL Group Replication(MGR)的高可用性解决方案,结合 MySQL Shell 和 MySQL Router,提供自动故障转移和读写分离功能,非常适合生产环境
2、部署
2.1 环境准备
三台 Ubuntu 20.04 服务器(IP 分别为 192.168.100.61、192.168.100.62 和 192.168.100.63)
修改主机名称,添加域名解析
每台服务器都要执行
hostnamectl set-hostname mysql1
bash
cat >>/etc/hosts<<EOF
192.168.100.61 mysql1
192.168.100.62 mysql2
192.168.100.63 mysql3
EOF
2.2 mysql部署(所有节点都要执行)
MIC 依赖 MySQL 8.0 的特性,因此需要安装 MySQL Server 8.0
2.2.1 安装相关工具
bash
apt update
#部署mysql
apt install mysql-server -y
#MySQL Shell 是 MIC 的管理工具,提供集群创建和维护的功能
apt install mysql-shell -y
#
apt install mysql-router -y
2.2.2 修改root用户密码
sql
ALTER USER 'root'@'localhost' IDENTIFIED WITH 'mysql_native_password' BY 'Admin@2025!';
CREATE USER 'root'@'%' IDENTIFIED WITH 'mysql_native_password' BY 'Admin@2025!';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
2.2.3 修改配置文件
/etc/mysql/mysql.conf.d/mysqld.cnf
bash
[mysqld]
#每台服务器的唯一标识符,必须不同(例如 1、2、3)
server_id = 1
#允许远程连接
bind-address = 0.0.0.0
#gtid_mode = ON 和 enforce_gtid_consistency = ON:启用全局事务 ID(GTID),确保事务一致性
gtid_mode = ON
enforce_gtid_consistency = ON
#设置为行格式,支持 Group Replication
binlog_format = ROW
#启用二进制日志,记录数据库变更
log_bin = mysql-bin
#从节点记录主节点的更新
log_slave_updates = ON
#master_info_repository = TABLE 和 relay_log_info_repository = TABLE:将主从信息存储在表中,提高可靠性
master_info_repository = TABLE
relay_log_info_repository = TABLE
#加载 Group Replication 插件
plugin_load_add = group_replication.so
#定义集群组名,需一致
group_replication_group_name = "my_group"
#避免服务启动时自动加入集群
group_replication_start_on_boot = off
#本节点的 MGR 通信地址
group_replication_local_address = "192.168.100.61:33061"
#集群所有节点的通信地址列表
group_replication_group_seeds = "192.168.100.61:33061,192.168.100.62:33061,192.168.100.63:33061"
#仅在首次创建集群时启用
group_replication_bootstrap_group = off
systemctl restart mysql
其他节点仅修改 server_id,group_replication_local_address即可
2.2.4 配置集群
shell
mysqlsh --uri [email protected]:3306
#检查和配置每个实例以支持 Group Replication,可能需要输入root账号 密码
dba.configureInstance('[email protected]:3306')
dba.configureInstance('[email protected]:3306')
dba.configureInstance('[email protected]:3306')
#创建并扩展集群
var cluster = dba.createCluster('my_cluster')
cluster.addInstance('[email protected]:3306')
cluster.addInstance('[email protected]:3306')
#验证集群状态
cluster.status()
2.2.4 测试集群数据同步功能
在mysql1上写一些测试数据,然后观察mysql2 mysql3是有有同步数据
sql
CREATE DATABASE test_db;
USE test_db;
CREATE TABLE test_table (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50));
INSERT INTO test_table (name) VALUES ('test1');
2.2.5 router配置
功能
- 读写分离:客户端连接6446端口访问主节点(读写),连接6447端口访问从节点(只读)。
- 高可用性:若主节点故障,Router自动将请求路由到新的主节点(依赖集群的故障转移机制)。
- 负载均衡:在只读模式下,Router可将请求分发到多个从节点
这里部署在mysql2主机上,用于测试功能,大家有时间可以改成Keepalived 和 HAProxy 组合实现router的高可用
shell
# 初始化和配置MySQL Router,使其能够与MySQL InnoDB Cluster(或其他高可用架构)集成
mysqlrouter --bootstrap [email protected]:3306 --directory /etc/mysqlrouter --user=root
cat >>/etc/systemd/system/mysqlrouter.service<<EOF
[Unit]
Description=MySQL Router Service
Documentation=https://dev.mysql.com/doc/mysql-router/8.0/en/
After=network.target mysql.service
[Service]
Type=simple
ExecStart=/usr/bin/mysqlrouter --config /etc/mysqlrouter/mysqlrouter.conf
ExecReload=/bin/kill -HUP
Restart=on-failure
RestartSec=5s
PIDFile=/var/run/mysqlrouter/mysqlrouter.pid
PrivateTmp=true
LimitNOFILE=65535
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable mysqlrouter && systemctl start mysqlrouter
mysql -h 192.168.100.62 -P 6446 -u root -p
2.2.5 验证高可用
1、停止mysql1的服务
systemctl stop mysql
2、查看变化
mysqlsh --uri [email protected]:3306
var cluster = dba.getCluster('my_cluster');
cluster.status()
bash
{
"clusterName": "my_cluster",
"defaultReplicaSet": {
"name": "default",
"primary": "mysql3:3306",
"ssl": "REQUIRED",
"status": "OK_NO_TOLERANCE_PARTIAL",
"statusText": "Cluster is NOT tolerant to any failures. 1 member is not active.",
"topology": {
"mysql1:3306": {
"address": "mysql1:3306",
"memberRole": "SECONDARY",
"mode": "n/a",
"readReplicas": {},
"role": "HA",
"shellConnectError": "MySQL Error 2003: Could not open connection to 'mysql1:3306': Can't connect to MySQL server on 'mysql1:3306' (111)",
"status": "(MISSING)"
},
"mysql2:3306": {
"address": "mysql2:3306",
"memberRole": "SECONDARY",
"mode": "R/O",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.41"
},
"mysql3:3306": {
"address": "mysql3:3306",
"memberRole": "PRIMARY",
"mode": "R/W",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.41"
}
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "mysql3:3306"
}
可以看到mysql1 的状态变成MISSING ,mysql3 变成主节点了
3、测试是否可以写入数据
mysql -h 192.168.100.62 -P 6446 -u root -p'Admin@2025!'
mysql> create database test_ha;
mysql> show databases;
结果可以成功写入
现在恢复mysql1
systemctl start mysql
重复步骤2再次查看集群状态,发现mysql1的状态变成ONLINE, "replicationLag"表示复制延迟状态,applier_queue_applied 表示数据已同步完成。如果有延迟,可能会显示具体的时间差
查看mysql1丢失的数据是否存在
powershell
root@mysql1:~# mysql -u root -p'Admin@2025!'
mysql> show databases;
发现已经成功同步了之前丢失的数据