一、MySQL 集群(一主多从)
基于 MySQL Router 搭建 MySQL 集群(一主多从),实现读写分离。
角色 | 作用 |
---|---|
MySQL Shell | 部署和运维 MySQL 集群的工具。 |
MySQL Router | MySQL 集群路由器,负责与客户端连接通讯,将客户端请求转发到 MySQL 集群。 |
官方来源:MySQL :: MySQL 8.0 Reference Manual :: 23 InnoDB Cluster
基于 MySQL Router 的集群架构,官方推荐不同应用对应一个 MySQL Router,毕竟一旦 MySQL Router 负载高,会宕机导致无法转发读写请求。
1、环境准备
主机名 | IP |
---|---|
node-04 | 192.168.241.154 |
node-05 | 192.168.241.155 |
node-06 | 192.168.241.156 |
1.1、MySQL 安装
使用 yum 安装方式,【MySQL】MySQL 安装
1.2、MySQL shell 安装
yum install mysql-shell
如果提示 No package mysql-shell available. Error: Nothing to do”,那需要添加 MySQL Yum 源,指引:MySQL :: A Quick Guide to Using the MySQL Yum Repository
1.3、MySQL Router 安装
yum install mysql-router-community
官方指引:MySQL :: MySQL Router 8.0 :: 2.1 Installing MySQL Router on Linux
2、配置
2.1、host
# 对所有节点添加 host 映射。
vim /etc/hosts
192.168.241.154 node-04
192.168.241.155 node-05
192.168.241.156 node-06
设置主机名
# 192.168.241.154
hostnamectl set-hostname node-04
# 192.168.241.155
hostnamectl set-hostname node-05
# 192.168.241.156
hostnamectl set-hostname node-06
2.2、端口
# 对所有 MySQL 实例开放端口
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload
2.3、授权
# 对所有 MySQL 实例授权
# 进入 mysql 命令行
mysql -uroot -p
# 授权
GRANT CLONE_ADMIN, CONNECTION_ADMIN, GROUP_REPLICATION_ADMIN, PERSIST_RO_VARIABLES_ADMIN, REPLICATION_APPLIER, REPLICATION_SLAVE_ADMIN, ROLE_ADMIN, SYSTEM_VARIABLES_ADMIN ON *.* TO 'root'@'%' WITH GRANT OPTION;
2.4、检查配置
官方指引:MySQL :: MySQL Shell 8.0 :: 7.4.1 Pre-Checking Instance Configuration for InnoDB Cluster Usage
# 对所有 MySQL 实例检查,以下以 node-06 为例
# 进入 mysql shell
mysqlsh
# 检查配置是否达标
dba.checkInstanceConfiguration('root@node-06:3306')
检查的结果
Clients and other cluster members will communicate with it through this address by default. If this is not correct, the report_host MySQL system variable should be changed.
Checking whether existing tables comply with Group Replication requirements...
No incompatible tables detected
Checking instance configuration...
NOTE: Some configuration options need to be fixed:
+----------------------------------------+---------------+----------------+--------------------------------------------------+
| Variable | Current Value | Required Value | Note |
+----------------------------------------+---------------+----------------+--------------------------------------------------+
| binlog_transaction_dependency_tracking | COMMIT_ORDER | WRITESET | Update the server variable |
| enforce_gtid_consistency | OFF | ON | Update read-only variable and restart the server |
| gtid_mode | OFF | ON | Update read-only variable and restart the server |
| server_id | 1 | <unique ID> | Update read-only variable and restart the server |
+----------------------------------------+---------------+----------------+--------------------------------------------------+
Some variables need to be changed, but cannot be done dynamically on the server.
NOTE: Please use the dba.configureInstance() command to repair these issues.
{
"config_errors": [
{
"action": "server_update",
"current": "COMMIT_ORDER",
"option": "binlog_transaction_dependency_tracking",
"required": "WRITESET"
},
{
"action": "server_update+restart",
"current": "OFF",
"option": "enforce_gtid_consistency",
"required": "ON"
},
{
"action": "server_update+restart",
"current": "OFF",
"option": "gtid_mode",
"required": "ON"
},
{
"action": "server_update+restart",
"current": "1",
"option": "server_id",
"required": "<unique ID>"
}
],
"status": "error"
}
2.5、修复配置
官方指引:MySQL :: MySQL Shell 8.0 :: 7.4.2 Configuring Production Instances for InnoDB Cluster Usage
# 对所有 MySQL 实例修复配置,以下以 node-06 为例
dba.configureInstance('root@node-06:3306')
再次检查的结果
dba.checkInstanceConfiguration('root@node-06:3306')
Checking whether existing tables comply with Group Replication requirements...
No incompatible tables detected
Checking instance configuration...
Instance configuration is compatible with InnoDB cluster
The instance 'node-07:3306' is valid to be used in an InnoDB cluster.
{
"status": "ok"
}
2.6、设置 id
集群中的 MySQL 实例是通过 server_id 和 server_uuid 区分。
主机名 | server_id | server_uuid |
---|---|---|
node-04 | 4 | 修复配置的环节,自动生成 |
node-05 | 5 | 修复配置的环节,自动生成 |
node-06 | 6 | 修复配置的环节,自动生成 |
server_id
# 对所有 MySQL实例设置 server_id
# 进入 mysql 命令行
mysql -uroot -p
# 查看 server_id 和 server_uuid
show variables like '%server_%'
# 自定义 server_id
SET GLOBAL server_id=6;
server_uuid
# 如果出现 server_uuid 相同的错误,那么生成和设置 uuid。
# 进入 mysql 命令行
mysql -uroot -p
# 获取 uuid
select uuid();
# 在 auto.cnf 设置 server_uuid
vim /var/lib/mysql/auto.cnf
server-uuid=84e88c72-4408-11ef-b454-000c2974c555
3、搭建集群
3.1、创建集群
官方指引:MySQL :: MySQL Shell 8.0 :: 7.4.3 Creating an InnoDB Cluster
# 进入任意一个实例的 mysql shell
mysqlsh
# 连接 node-06 实例
\connect root@node-06:3306
# 创建 mysql 集群,名称 mysqlcluster
var cluster = dba.createCluster('mysqlcluster')
# 如果已经创建了集群,那么直接获取
var cluster = dba.getCluster('mysqlcluster')
3.2、添加实例
官方指引:MySQL :: MySQL Shell 8.0 :: 7.4.4 Adding Instances to an InnoDB Cluster
# 添加 node-05 和 node-04 两个实例
cluster.addInstance('root@node-05:3306')
cluster.addInstance('root@node-04:3306')
# 选择 Clone(默认)
3.3、查看集群信息
cluster.status()
集群信息
{
"clusterName": "mysqlcluster",
"defaultReplicaSet": {
"name": "default",
"primary": "node-06:3306",
"ssl": "REQUIRED",
"status": "OK",
"statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
"topology": {
"node-04:3306": {
"address": "node-04:3306",
"memberRole": "SECONDARY",
"memberState": "(MISSING)",
"mode": "n/a",
"readReplicas": {},
"role": "HA",
"shellConnectError": "RuntimeError: Could not open connection to 'node-04:3306': The provided URI uses the X protocol, which is not supported by this command.",
"status": "ONLINE",
"version": "8.0.38"
},
"node-05:3306": {
"address": "node-05:3306",
"memberRole": "SECONDARY",
"mode": "R/O",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.38"
},
"node-06:3306": {
"address": "node-06:3306",
"memberRole": "PRIMARY",
"mode": "R/W",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.38"
}
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "node-06:3306"
}
检查实例是否添加到集群中
# 检查 node-05 是否添加到 mysqlcluster 集群中
cluster.checkInstanceState('root@node-05:3306')
# 提示
WARNING: This function is deprecated and will be removed in a future release of MySQL Shell.
Cluster.checkInstanceState: The instance 'node-05:3306' already belongs to the cluster: 'mysqlcluster'. (RuntimeError)
4、运行
4.1、初始化 MySQL Router
官方指引:MySQL :: MySQL Router 8.0 :: 3.1 Bootstrapping MySQL Router
# 在 node-06 初始化 MySQL Router,创建 mysqlrt 用户
mysqlrouter --bootstrap root@node-06:3306 --user=root --directory /tmp/myrouter --conf-use-sockets --account mysqlrt --account-create always
# 在其他节点复用 mysqlrt 用户
mysqlrouter --bootstrap root@node-06:3306 --user=root --directory /tmp/myrouter --conf-use-sockets --account mysqlrt
开放端口
# 默认 6446 端口
firewall-cmd --zone=public --add-port=6446/tcp --permanent
firewall-cmd --reload
MySQL Router 配置文件
/tmp/myrouter/mysqlrouter.conf
配置项说明:MySQL :: MySQL Router 8.0 :: 4.3.3 Configuration File Options
4.2、启动 MySQL Router
# 初始化 MySQL Router 成功后,启动 MySQL Router
/tmp/myrouter/start.sh
4.3、连接 MySQL Router
# 在 node-06
mysql -u root -h 192.168.241.156 -P 6446 -p
# 查询当前连接主节点的 server_id
SHOW VARIABLES LIKE 'server_id'
5、验证
5.1、读写验证
节点 | 操作 | 结果 |
---|---|---|
node-06(主) | 读 / 写 | 读成功、写成功,数据同步到所有从库 |
node-05(从) | 读 / 写 | 读成功、写失败 |
node-04(从) | 读 / 写 | 读成功、写失败 |
5.2、故障切换验证
停止 node-06
节点 | 状态 | 结果 |
---|---|---|
node-06(主) | 停止 | MySQL Router 依旧可以读写数据 主节点更换(从 node-05 和 node-06 选) |
node-05(从) | 运行 | / |
node-04(从) | 运行 | / |
恢复 node-06
节点 | 状态 | 结果 |
---|---|---|
node-06(从) | 恢复 | 主节点不变,node-06 节点添加到集群中,状态:只读 |
node-05(主) | 运行 | / |
node-04(从) | 运行 | / |
5.3、添加新节点
节点 | IP |
---|---|
node-07 | 192.168.241.157 |
补充 配置
进入 mysqlsh,连接 MySQL 集群中的任意一个可用节点,再添加 node-07 实例
节点 | 状态 | 结果 |
---|---|---|
node-06(主) | 运行 | / |
node-05(从) | 运行 | / |
node-04(从) | 运行 | / |
node-07(从) | 运行 | 加入到 MySQL 集群、状态:只读,主节点不变 |
二、MySQL 集群(对等)
官方文档
MySQL :: MySQL 8.0 Reference Manual :: 20.1.3.2 Multi-Primary Mode
MySQL :: MySQL 8.0 Reference Manual :: 20.1.3 Multi-Primary and Single-Primary Modes
MySQL :: MySQL 8.0 Reference Manual :: 20.1.1.2 Group Replication
MySQL :: MySQL 8.0 Reference Manual :: 20.5.1.2 Changing the Group Mode
1、切换多主模式(对等)
所有 MySQL 实例都支持读写。
# 进入任意一个实例,执行
mysql -uroot -p
SELECT group_replication_switch_to_multi_primary_mode();
设置对等模式后,需要重新扫描 MySQL 集群的实例。
mysqlsh
\connect root@node-06:3306
var cluster = dba.getCluster('mysqlcluster')
# 重新扫描集群节点
cluster.rescan()
集群状态信息
{
"clusterName": "mysqlcluster",
"defaultReplicaSet": {
"name": "default",
"ssl": "REQUIRED",
"status": "OK",
"statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
"topology": {
"node-04:3306": {
"address": "node-04:3306",
"instanceErrors": [
"WARNING: Incorrect recovery account (mysql_innodb_cluster_6) being used. Use Cluster.rescan() to repair."
],
"memberRole": "PRIMARY",
"mode": "R/W",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.38"
},
"node-05:3306": {
"address": "node-05:3306",
"instanceErrors": [
"WARNING: Incorrect recovery account (mysql_innodb_cluster_6) being used. Use Cluster.rescan() to repair."
],
"memberRole": "PRIMARY",
"mode": "R/W",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.38"
},
"node-06:3306": {
"address": "node-06:3306",
"memberRole": "PRIMARY",
"mode": "R/W",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.38"
},
"node-07:3306": {
"address": "node-07:3306",
"memberRole": "PRIMARY",
"mode": "R/W",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.38"
}
},
"topologyMode": "Multi-Primary"
},
"groupInformationSourceMember": "node-06:3306"
}
2、切换一主多从模式
# 进入任意一个实例,执行
mysql -uroot -p
SELECT group_replication_switch_to_single_primary_mode();
mysqlsh
\connect root@node-06:3306
var cluster = dba.getCluster('mysqlcluster')
# 重新扫描集群节点
cluster.rescan()
参考
MySQL集群搭建_dba.createcluster: the shell must be connected to -CSDN博客