【MySQL】MySQL 集群

一、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博客

创作不易,转载请注明出处: 【MySQL】MySQL 集群
上一篇
下一篇