MySQL 5.7 在InnoDB集群中使用MySQL路由器

在InnoDB集群中使用MySQL路由器
在InnoDB集群中使用MySQL Router实现高可用性。不管你部署的是沙盒还是生产集群,MySQL路由器都可以根据InnoDB集群的元数据使用——bootstrap选项来配置自己。这将自动配置MySQL路由器,将连接路由到集群的服务器实例。客户端应用程序连接到MySQL路由器提供的端口,而不需要知道InnoDB集群的拓扑结构。在发生意外故障时,InnoDB集群会自动调整,MySQL路由器会检测到变化。

不要尝试手动配置MySQL路由器来重定向到InnoDB集群的端口。始终使用–bootstrap选项,因为这确保MySQL路由器从InnoDB集群的元数据中获取配置。

MySQL Router推荐和应用部署在同一个主机上。当使用沙盒部署时,所有东西都运行在单个主机上,因此你将MySQL路由器部署到同一个主机上。当使用生产部署时,我们建议在每台主机上部署一个MySQL路由器实例。也可以将MySQL Router部署到应用实例连接的普通机器上。你需要InnoDB集群的主密钥来自动配置MySQL路由器。

假设已经安装了MySQL路由器(参见安装MySQL路由器),使用–bootstrap选项来提供属于InnoDB集群的服务器实例的位置。MySQL路由器使用包含的元数据缓存插件来获取InnoDB集群的元数据,该元数据由组成InnoDB集群的服务器实例地址列表及其在集群中的角色组成。你传入了服务器的URI类型字符串,MySQL路由器应该从该服务器获取InnoDB集群的元数据。例如:

[root@my239 ~]#   mysqlrouter --bootstrap root@my239:3310 --user=mysqlrouter
Please enter MySQL password for root:
WARNING: The MySQL server does not have SSL configured and metadata used by the router may be transmitted unencrypted.
# Bootstrapping system MySQL Router 8.0.41 (MySQL Community - GPL) instance...

- Creating account(s) (only those that are needed, if any)
Failed changing the authentication plugin for account 'mysql_router1_t79nbm0'@'%':  mysql_native_password which is deprecated is the default authentication plugin on this server.
- Verifying account (using it to run SQL queries that would be run by Router)
- Storing account in keyring
- Adjusting permissions of generated files
- Creating configuration /etc/mysqlrouter/mysqlrouter.conf

Existing configuration backed up to '/etc/mysqlrouter/mysqlrouter.conf.bak'

# MySQL Router configured for the InnoDB Cluster 'testCluster'

After this MySQL Router has been started with the generated configuration

    $ /etc/init.d/mysqlrouter restart
or
    $ systemctl start mysqlrouter
or
    $ mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf

InnoDB Cluster 'testCluster' can be reached by connecting to:

## MySQL Classic protocol

- Read/Write Connections: localhost:6446
- Read/Only Connections:  localhost:6447

## MySQL X protocol

- Read/Write Connections: localhost:6448
- Read/Only Connections:  localhost:6449

系统提示您输入MySQL Router使用的实例密码和加密密钥。此加密密钥用于加密MySQL路由器连接到集群时使用的实例密码。可以连接到InnoDB集群的端口也会显示出来。MySQL路由器引导过程创建了一个mysqlrouter.conf文件,该文件的设置基于从传递给–bootstrap选项的地址中检索到的集群元数据,在上面的例子中ic@mic1:3306。根据检索到的InnoDB集群元数据,MySQL Router自动创建了一个配置文件,其中包含一个metadata_cache部分,例如:

[root@my239 ~]# more /etc/mysqlrouter/mysqlrouter.conf
# File automatically generated during MySQL Router bootstrap
[DEFAULT]
name=system
user=mysqlrouter
keyring_path=/var/lib/mysqlrouter/keyring
master_key_path=/etc/mysqlrouter/mysqlrouter.key
connect_timeout=5
read_timeout=30
dynamic_state=/var/lib/mysqlrouter/state.json
client_ssl_cert=/var/lib/mysqlrouter/router-cert.pem
client_ssl_key=/var/lib/mysqlrouter/router-key.pem
client_ssl_mode=PREFERRED
server_ssl_mode=AS_CLIENT
server_ssl_verify=DISABLED
unknown_config_option=error

[logger]
level=INFO

[metadata_cache:bootstrap]
cluster_type=gr
router_id=1
user=mysql_router1_t79nbm0
metadata_cluster=testCluster
ttl=0.5
auth_cache_ttl=-1
auth_cache_refresh_interval=2
use_gr_notifications=0

[routing:bootstrap_rw]
bind_address=0.0.0.0
bind_port=6446
destinations=metadata-cache://testCluster/?role=PRIMARY
routing_strategy=first-available
protocol=classic

[routing:bootstrap_ro]
bind_address=0.0.0.0
bind_port=6447
destinations=metadata-cache://testCluster/?role=SECONDARY
routing_strategy=round-robin-with-fallback
protocol=classic

[routing:bootstrap_x_rw]
bind_address=0.0.0.0
bind_port=6448
destinations=metadata-cache://testCluster/?role=PRIMARY
routing_strategy=first-available
protocol=x

[routing:bootstrap_x_ro]
bind_address=0.0.0.0
bind_port=6449
destinations=metadata-cache://testCluster/?role=SECONDARY
routing_strategy=round-robin-with-fallback
protocol=x

[http_server]
port=8443
ssl=1
ssl_cert=/var/lib/mysqlrouter/router-cert.pem
ssl_key=/var/lib/mysqlrouter/router-key.pem

[http_auth_realm:default_auth_realm]
backend=default_auth_backend
method=basic
name=default_realm

[rest_router]
require_realm=default_auth_realm

[rest_api]

[http_auth_backend:default_auth_backend]
backend=metadata_cache

[rest_routing]
require_realm=default_auth_realm

[rest_metadata_cache]
require_realm=default_auth_realm

生成的MySQL路由器配置创建了用于连接到集群的TCP端口。创建了使用经典MySQL协议和X协议与集群通信的端口。要使用X协议,服务器实例必须安装和配置X插件。对于沙盒部署,实例会自动设置X Plugin。对于生产部署,如果你想使用X协议,你需要在每个实例上安装和配置X插件
.6446用于经典的MySQL协议读写会话,MySQL路由器将传入的连接重定向到主服务器实例。

.6447对于经典的MySQL协议只读会话,MySQL路由器将传入的连接重定向到一个辅助服务器实例。

.6448对于X协议读写会话,MySQL路由器将传入的连接重定向到主服务器实例。

.6449对于X Protocol只读会话,MySQL路由器将传入的连接重定向到一个辅助服务器实例。

根据你的MySQL路由器配置,端口号可能与上面不同。例如,如果您使用–conf-base-port选项,或group_replication_single_primary_mode变量。当你启动MySQL路由器时,会列出确切的端口。

传入的连接被重定向的方式取决于所使用的集群类型。当使用单主集群时,读写会话被重定向到单主集群,而在多主集群中,读写会话被重定向到其中一个主集群实例。对于进入的只读连接,MySQL路由器以轮询方式将连接重定向到一个辅助实例。

一旦启动并配置后,启动MySQL路由器:

[root@my239 ~]#  mysqlrouter &
[1] 9670

[root@my239 ~]# netstat -ltnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:33101           0.0.0.0:*               LISTEN      24656/mysqld
tcp        0      0 0.0.0.0:6446            0.0.0.0:*               LISTEN      9670/mysqlrouter
tcp        0      0 0.0.0.0:6447            0.0.0.0:*               LISTEN      9670/mysqlrouter
tcp        0      0 0.0.0.0:6448            0.0.0.0:*               LISTEN      9670/mysqlrouter
tcp        0      0 0.0.0.0:6449            0.0.0.0:*               LISTEN      9670/mysqlrouter
tcp        0      0 0.0.0.0:33201           0.0.0.0:*               LISTEN      27539/mysqld
tcp        0      0 0.0.0.0:33301           0.0.0.0:*               LISTEN      27495/mysqld
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1625/sshd
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      2854/cupsd
tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN      9670/mysqlrouter
tcp6       0      0 :::3306                 :::*                    LISTEN      2566/mysqld
tcp6       0      0 :::33100                :::*                    LISTEN      24656/mysqld
tcp6       0      0 :::3310                 :::*                    LISTEN      24656/mysqld
tcp6       0      0 :::33200                :::*                    LISTEN      27539/mysqld
tcp6       0      0 :::33300                :::*                    LISTEN      27495/mysqld
tcp6       0      0 :::22                   :::*                    LISTEN      1625/sshd
tcp6       0      0 ::1:631                 :::*                    LISTEN      2854/cupsd
tcp6       0      0 :::3320                 :::*                    LISTEN      27539/mysqld
tcp6       0      0 :::3330                 :::*                    LISTEN      27495/mysqld
tcp6       0      0 :::33060                :::*                    LISTEN      2566/mysqld

或者设置一个服务,在系统启动时自动启动MySQL Router,参见启动MySQL Router。你现在可以连接一个MySQL客户端,例如MySQL Shell到一个MySQL路由器端口,如上所述,并看到客户端是如何透明地连接到一个InnoDB集群实例的。

[root@my239 ~]# mysqlsh --log-level=DEBUG3 --uri root@localhost:6446
Please provide the password for 'root@localhost:6446': ******
Save password for 'root@localhost:6446'? [Y]es/[N]o/Ne[v]er (default No):
MySQL Shell 8.0.41

Copyright (c) 2016, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.

Type '\help' or '\?' for help; '\quit' to exit.
Creating a session to 'root@localhost:6446'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 196
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  localhost:6446  JS >

要验证您实际连接到的实例,只需对主机名和端口状态变量发出一个SQL查询。

 MySQL  localhost:6446  SQL > SELECT @@hostname AS 'Host Name', @@port AS 'Port';
+-----------------------+------+
| Host Name             | Port |
+-----------------------+------+
| localhost.localdomain | 3310 |
+-----------------------+------+
1 row in set (0.0008 sec)

MySQL 5.7 使用组复制部署InnoDB集群

采用组复制部署InnoDB集群
如果您有一个现有的组复制部署,并且希望使用它来创建一个集群,请将adoptFromGR选项传递给dba.createCluster()函数。创建的InnoDB集 群匹配复制组是单主还是多主。这意味着不能将multiPrimary选项与adoptFromGR选项结合使用。

组复制成员可能包含MyISAM表。将所有这样的表转换为InnoDB,然后再将组纳入InnoDB集群。

我这里已经存在组复制了

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 07542900-d3b4-11ef-a088-005056a390e6 | mysqlcs     |        3308 | ONLINE       |
| group_replication_applier | f81625c0-d3b3-11ef-9c8d-005056a390e6 | mysqlcs     |        3306 | ONLINE       |
| group_replication_applier | ffc6ff15-d3b3-11ef-9e2d-005056a390e6 | mysqlcs     |        3307 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.01 sec)

要采用已有的组复制组,请使用MySQL Shell连接到组成员。使用dba.createCluster()创建一个集群,传入adoptFromGR选项。例如:

[root@mysqlcs ~]# mysqlsh --log-level=DEBUG3 root@localhost
Please provide the password for 'root@localhost': ******
Save password for 'root@localhost'? [Y]es/[N]o/Ne[v]er (default No):
MySQL Shell 8.0.41

Copyright (c) 2016, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.

Type '\help' or '\?' for help; '\quit' to exit.
Creating a session to 'root@localhost'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 94 (X protocol)
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.


 MySQL  localhost:33060+  JS > var cluster = dba.createCluster('prodCluster', {adoptFromGR: true})
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
A new InnoDB Cluster will be created based on the existing replication group on instance 'mysqlcs:3306'.

Creating InnoDB Cluster 'prodCluster' on 'mysqlcs:3306'...

Adding Seed Instance...
Adding Instance 'mysqlcs:3308'...
Adding Instance 'mysqlcs:3306'...
Adding Instance 'mysqlcs:3307'...
Resetting distributed recovery credentials across the cluster...
WARNING: Instance 'mysqlcs:3308' cannot persist configuration since MySQL version 5.7.26 does not support the SET PERSIST  command (MySQL version >= 8.0.11 required). Please use the dba.configureLocalInstance() command locally to persist the  changes.
WARNING: Instance 'mysqlcs:3306' cannot persist configuration since MySQL version 5.7.26 does not support the SET PERSIST  command (MySQL version >= 8.0.11 required). Please use the dba.configureLocalInstance() command locally to persist the  changes.
WARNING: Instance 'mysqlcs:3307' cannot persist configuration since MySQL version 5.7.26 does not support the SET PERSIST  command (MySQL version >= 8.0.11 required). Please use the dba.configureLocalInstance() command locally to persist the  changes.
Cluster successfully created based on existing replication group.

连接并对其发出dba.createCluster()的组复制成员用作创建组的种子实例。


 MySQL  localhost:33060+  JS > cluster.status()
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
{
    "clusterName": "prodCluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "mysqlcs:3306",
        "ssl": "DISABLED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "mysqlcs:3306": {
                "address": "mysqlcs:3306",
                "memberRole": "PRIMARY",
                "mode": "R/W",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            },
            "mysqlcs:3307": {
                "address": "mysqlcs:3307",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            },
            "mysqlcs:3308": {
                "address": "mysqlcs:3308",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "mysqlcs:3306"
}
 MySQL  localhost:33060+  JS >


 MySQL  localhost:33060+  JS > cluster.describe();
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
{
    "clusterName": "prodCluster",
    "defaultReplicaSet": {
        "name": "default",
        "topology": [
            {
                "address": "mysqlcs:3308",
                "label": "mysqlcs:3308",
                "role": "HA"
            },
            {
                "address": "mysqlcs:3306",
                "label": "mysqlcs:3306",
                "role": "HA"
            },
            {
                "address": "mysqlcs:3307",
                "label": "mysqlcs:3307",
                "role": "HA"
            }
        ],
        "topologyMode": "Single-Primary"
    }
}
 MySQL  localhost:33060+  JS >