MySQL 5.7 检查InnoDB集群状态

检查InnoDB集群状态
Cluster对象提供了status()方法,让你能够检查集群的运行情况。在你检查InnoDB集群的状态之前,你需要通过连接到它的任何一个实例来 获取对InnoDB集群对象的引用。但是,如果您想要更改集群的配置,则必须连接到“R/W”实例。执行status()函数可以根据所连接的服务器 实例所感知到的集群视图获取集群状态,并输出状态报告。

集群中的实例状态直接影响状态报告中提供的信息。离开集群的实例与属于集群的实例相比,提供了集群的不同视图。因此,请确保连接到的实 例的状态为在线。

要了解InnoDB集群的运行情况,请使用集群的status()方法:

 MySQL  JS > \connect root@localhost:3320
Creating a session to 'root@localhost:3320'
Please provide the password for 'root@localhost:3320': ******
Save password for 'root@localhost:3320'? [Y]es/[N]o/Ne[v]er (default No):
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 35
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.

 MySQL  localhost:3330  JS > var cluster = dba.getCluster()
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
 MySQL  localhost:3330  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": "testCluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "127.0.0.1:3310",
        "ssl": "DISABLED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "127.0.0.1:3310": {
                "address": "127.0.0.1:3310",
                "memberRole": "PRIMARY",
                "mode": "R/W",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            },
            "127.0.0.1:3320": {
                "address": "127.0.0.1:3320",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            },
            "127.0.0.1:3330": {
                "address": "127.0.0.1:3330",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "127.0.0.1:3310"
}


cluster.status()的输出信息包括以下信息:
.clusterName:在dba.createCluster()过程中分配给集群的名称。

.ssl:集群是否使用安全连接。显示REQUIRED或DISABLED的值,取决于在createCluster()或addInstance()期间如何配置memberSslMode选项 。此参数返回的值对应于实例上的group_replication_ssl_mode服务器变量的值。

.status:集群中该元素的状态。对于整个集群,本文描述了该集群提供的高可用性。例如,状态参见下面的详细信息

.topology:已加入集群的实例。

.Host name of instance:实例的主机名,例如127.0.0.1:3310。

.mode:请参阅下面对mode的描述。

实例状态是下列之一。
.ONLINE:实例在线并参与集群。

.OFFLINE:实例已失去与其他实例的连接。

.RECOVERING:实例正在通过检索它成为联机成员之前需要的事务来尝试与集群同步。

.UNREACHABLE:实例失去了与集群的通信。

.ERROR:实例在恢复阶段或应用事务时遇到错误。

.(MISSING):一个实例的状态,它是已配置集群的一部分,但目前不可用。

MISSING状态是InnoDB集群特有的,它不是由组复制产生的状态。MySQL Shell使用这种状态来表示在元数据中注册的实例,但在实时集群视图中 找不到。

在实例进入ERROR状态后,super_read_only选项将设置为ON。要脱离ERROR状态,必须手动配置该实例为super_read_only=OFF。

模式为R/W(可读可写)或R/O(只读)。在单主模式下,只有标记为“R/W”的实例才能执行更新数据库的事务,因此它是主模式。如果该实例 由于任何原因(如意外停机)变得不可访问,则剩余的一个“R/O”实例自动取代它的位置,并成为新的“R/W”主实例。在多主模式下,多个实 例被标记为“R/W”,并且没有选举的主实例。

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 >

MySQL 5.7使用MySQL Shell部署生产环境InnoDB集群

生产环境部署InnoDB集群
当在生产环境中工作时,组成InnoDB集群的MySQL服务器实例在多台主机上作为网络的一部分运行,而不是在单台机器上。在执行这些步骤之前 ,用户必须为每台作为服务器实例添加到集群中的机器安装所需的软件。

与沙盒部署不同的是,所有的实例都部署在本地的一台机器上,在生产部署中,你必须连接到每台机器并在本地运行MySQL Shell,然后在实例 上执行dba.configureLocalInstance()。这确保了任何配置更改都持久化到实例的mysql.cfg文件中。这还要求用户有访问服务器的权限和执 行MySQL Shell所需的权限。

用户权限
用于管理实例的用户帐户不一定是root帐户,但是除了MySQL管理员的权限(SUPER、GRANT OPTION、CREATE、DROP等)之外,还需要给用户分配 InnoDB集群元数据表的完全读写权限。给用户ic权限来管理InnoDB集群问题:

mysql> create user 'ic'@'%' identified by "123456";
Query OK, 0 rows affected (1.31 sec)

mysql> GRANT ALL PRIVILEGES ON mysql_innodb_cluster_metadata.* TO ic@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.07 sec)

mysql> GRANT RELOAD, SHUTDOWN, PROCESS, FILE, SUPER, REPLICATION SLAVE, REPLICATION CLIENT,CREATE USER ON *.* TO ic@'%' WITH  GRANT OPTION;
Query OK, 0 rows affected (1.00 sec)


mysql> GRANT SELECT ON performance_schema.* TO ic@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SELECT ON *.* TO ic@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON mysql.* TO ic@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON mysql.* TO ic@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)

如果只需要读操作(例如用于监控),则可以使用具有更多限制权限的帐户。给用户your_user权限来监控InnoDB集群问题:

mysql> GRANT SELECT ON performance_schema.global_status TO ic@'%';
Query OK, 0 rows affected (0.08 sec)

mysql> GRANT SELECT ON performance_schema.replication_applier_configuration TO ic@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SELECT ON performance_schema.replication_applier_status TO ic@'%';
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT SELECT ON performance_schema.replication_applier_status_by_coordinator TO ic@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SELECT ON performance_schema.replication_applier_status_by_worker TO ic@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SELECT ON performance_schema.replication_connection_configuration TO ic@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SELECT ON performance_schema.replication_connection_status TO ic@'%';
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT SELECT ON performance_schema.replication_group_member_stats TO ic@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SELECT ON performance_schema.replication_group_members TO ic@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;


Query OK, 0 rows affected (0.07 sec)

对于每个实例重复上面的操作

配置主机名
组成集群的生产实例在不同的机器上运行,因此每台机器必须有唯一的主机名,并且能够解析集群中运行服务器实例的其他机器的主机名。如果 不是这样,你可以:
.配置每台机器,将每台机器的IP映射到主机名。详情请参阅操作系统文档。这是推荐的解决方案。
.设置DNS服务
.在每个实例的MySQL配置中配置report_host变量

下面对三台服务器进行配置

[root@localhost ~]# hostnamectl set-hostname mic1
[root@mic1 ~]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.18.13.238 mic3
10.18.13.237 mic2
10.18.13.236 mic1


[root@localhost ~]# hostnamectl set-hostname mic2
[root@mic2 ~]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.18.13.238 mic3
10.18.13.237 mic2
10.18.13.236 mic1


[root@localhost mysql]# hostnamectl set-hostname mic3
[root@localhost mysql]#
Last login: Fri Mar 28 09:43:16 2025 from 10.18.13.242

[root@mic3 ~]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.18.13.238 mic3
10.18.13.237 mic2
10.18.13.236 mic1

[root@mic1 ~]# ping mic3
PING mic3 (10.18.13.238) 56(84) bytes of data.
64 bytes from mic3 (10.18.13.238): icmp_seq=1 ttl=64 time=0.830 ms
64 bytes from mic3 (10.18.13.238): icmp_seq=2 ttl=64 time=0.418 ms
^C
--- mic3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.418/0.624/0.830/0.206 ms
[root@mic1 ~]# ping mic2
PING mic2 (10.18.13.237) 56(84) bytes of data.
64 bytes from mic2 (10.18.13.237): icmp_seq=1 ttl=64 time=0.473 ms
64 bytes from mic2 (10.18.13.237): icmp_seq=2 ttl=64 time=0.307 ms
64 bytes from mic2 (10.18.13.237): icmp_seq=3 ttl=64 time=0.300 ms
^C
--- mic2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.300/0.360/0.473/0.079 ms
[root@mic1 ~]# ping mic1
PING mic1 (10.18.13.236) 56(84) bytes of data.
64 bytes from mic1 (10.18.13.236): icmp_seq=1 ttl=64 time=0.097 ms
64 bytes from mic1 (10.18.13.236): icmp_seq=2 ttl=64 time=0.062 ms
^C
--- mic1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.062/0.079/0.097/0.019 ms

[mysql@mic1 mysql]$ vi my.cnf
report_host=10.18.13.236
[mysql@mic2 mysql]$ vi my.cnf
report_host=10.18.13.237
[mysql@mic3 mysql]$ vi my.cnf
report_host=10.18.13.238

[root@mic1 /]# service mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL.. SUCCESS!

[root@mic2 /]# service mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL.. SUCCESS!

[root@mic3 /]# service mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL.. SUCCESS!

详细日志
当使用生产部署时,为MySQL Shell配置详细的日志记录是很有用的,日志中的信息可以帮助您发现和解决在准备服务器实例作为InnoDB集群的 一部分时可能发生的任何问题。要用详细的日志级别启动MySQL Shell,使用–log-level选项:

[root@mic1 /]# mysqlsh --log-level=DEBUG3
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.
 MySQL  JS >

建议使用DEBUG3,更多信息请参见–log-level。当设置了DEBUG3时,MySQL Shell日志文件包含这样的行:Debug: execute_sql(…)其中包含 作为每个AdminAPI调用的一部分执行的SQL查询。MySQL Shell生成的日志文件在unix系统中位于~/.mysqlsh/mysqlsh.log;在Microsoft Windows系统中,它位于%APPDATA%\MySQL\mysqlsh\mysqlsh.log中。

除了启用MySQL Shell日志级别之外,您还可以配置AdminAPI在MySQL Shell中每次调用API后提供的输出数量。要启用AdminAPI输出的数量,请 在MySQL Shell中发出:

 MySQL  JS > dba.verbose=2
2
 MySQL  JS >

这将启用AdminAPI调用的最大输出。可用的输出级别如下:
.默认值为0或OFF。这提供了最小输出,在不进行故障排除时是推荐的级别。

.1或ON添加每次对AdminAPI调用的详细输出。

.2在详细输出中添加调试输出,提供每次调用AdminAPI执行的全部信息。

检查实例配置
在服务器实例创建生产部署之前,需要使用dba.checkInstanceConfiguration()函数检查每个实例上的MySQL是否正确配置。下面演示了如何 在MySQL Shell中执行这个命令:

 MySQL  JS > dba.checkInstanceConfiguration('ic@mic1:3306')
Please provide the password for 'ic@mic1:3306': ******
Save password for 'ic@mic1:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3306 for use in an InnoDB cluster...
ERROR: The account 'ic'@'%' is missing privileges required to manage an InnoDB cluster:
GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX,  INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata_bkp.* TO 'ic'@'%' WITH GRANT  OPTION;
GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX,  INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata_previous.* TO 'ic'@'%' WITH GRANT  OPTION;
For more information, see the online documentation.
Dba.checkInstanceConfiguration: The account 'ic'@'%' is missing privileges required to manage an InnoDB cluster.  (RuntimeError)

上面提示缺少相关权限,在三个实例上执行上面的授权语句:

mysql> GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE,  INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata_bkp.* TO 'ic'@'%' WITH  GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE,  INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata_previous.* TO 'ic'@'%'  WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)

授权后再次执行检测实例的命令

 MySQL  JS > dba.checkInstanceConfiguration('ic@mic1:3306')
Please provide the password for 'ic@mic1:3306': ******
Save password for 'ic@mic1:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as 10.18.13.236:3306

Checking whether existing tables comply with Group Replication requirements...
ERROR: The following tables do not have a Primary Key or equivalent column:
jycs.t_cs

Group Replication requires tables to use InnoDB and have a PRIMARY KEY or PRIMARY KEY Equivalent (non-null unique key). Tables  that do not follow these requirements will be readable but not updateable when used with Group Replication. If your  applications make updates (INSERT, UPDATE or DELETE) to these tables, ensure they use the InnoDB storage engine and have a  PRIMARY KEY or PRIMARY KEY Equivalent.
If you can't change the tables structure to include an extra visible key to be used as PRIMARY KEY, you can make use of the  INVISIBLE COLUMN feature available since 8.0.23: https://dev.mysql.com/doc/refman/8.0/en/invisible-columns.html

Checking instance configuration...

NOTE: Some configuration options need to be fixed:
+----------------------------------+---------------+----------------+------------------------------------------------+
| Variable                         | Current Value | Required Value | Note                                           |
+----------------------------------+---------------+----------------+------------------------------------------------+
| binlog_checksum                  | CRC32         | NONE           | Update the server variable and the config file |
| binlog_format                    | MIXED         | ROW            | Update the server variable and the config file |
| enforce_gtid_consistency         | OFF           | ON             | Update the config file and restart the server  |
| gtid_mode                        | OFF           | ON             | Update the config file and restart the server  |
| log_slave_updates                | OFF           | ON             | Update the config file and restart the server  |
| transaction_write_set_extraction | OFF           | XXHASH64       | Update the config file and restart the server  |
+----------------------------------+---------------+----------------+------------------------------------------------+

Some variables need to be changed, but cannot be done dynamically on the server: an option file is required.
NOTE: Please use the dba.configureInstance() command to repair these issues.

{
    "config_errors": [
        {
            "action": "server_update+config_update",
            "current": "CRC32",
            "option": "binlog_checksum",
            "required": "NONE"
        },
        {
            "action": "server_update+config_update",
            "current": "MIXED",
            "option": "binlog_format",
            "required": "ROW"
        },
        {
            "action": "config_update+restart",
            "current": "OFF",
            "option": "enforce_gtid_consistency",
            "required": "ON"
        },
        {
            "action": "config_update+restart",
            "current": "OFF",
            "option": "gtid_mode",
            "required": "ON"
        },
        {
            "action": "config_update+restart",
            "current": "OFF",
            "option": "log_slave_updates",
            "required": "ON"
        },
        {
            "action": "config_update+restart",
            "current": "OFF",
            "option": "transaction_write_set_extraction",
            "required": "XXHASH64"
        }
    ],
    "status": "error"
}
 MySQL  JS >

检查实例给出了要修改的参数,下面对每个实例修改相关参数

[mysql@mic1 ~]$ vi /mysqlsoft/mysql/my.cnf
binlog_checksum=NONE
binlog_format = row
enforce_gtid_consistency=ON
gtid_mode=ON
log_slave_updates=ON
transaction_write_set_extraction=XXHASH64

[mysql@mic2 ~]$ vi /mysqlsoft/mysql/my.cnf
binlog_checksum=NONE
binlog_format = row
enforce_gtid_consistency=ON
gtid_mode=ON
log_slave_updates=ON
transaction_write_set_extraction=XXHASH64


[mysql@mic3 ~]$ vi /mysqlsoft/mysql/my.cnf
binlog_checksum=NONE
binlog_format = row
enforce_gtid_consistency=ON
gtid_mode=ON
log_slave_updates=ON
transaction_write_set_extraction=XXHASH64

[root@mic1 ~]# service mysqld restart
Shutting down MySQL. SUCCESS!
Starting MySQL.. SUCCESS!


[root@mic2 ~]# service mysqld restart
Shutting down MySQL. SUCCESS!
Starting MySQL.. SUCCESS!


[root@mic3 ~]# service mysqld restart
Shutting down MySQL. SUCCESS!
Starting MySQL.. SUCCESS!

再次执行检测实例命令

 MySQL  JS > dba.checkInstanceConfiguration('ic@mic1:3306')
Please provide the password for 'ic@mic1:3306': ******
Save password for 'ic@mic1:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as 10.18.13.236:3306

Checking whether existing tables comply with Group Replication requirements...
ERROR: The following tables do not have a Primary Key or equivalent column:
jycs.t_cs

Group Replication requires tables to use InnoDB and have a PRIMARY KEY or PRIMARY KEY Equivalent (non-null unique key). Tables  that do not follow these requirements will be readable but not updateable when used with Group Replication. If your  applications make updates (INSERT, UPDATE or DELETE) to these tables, ensure they use the InnoDB storage engine and have a  PRIMARY KEY or PRIMARY KEY Equivalent.
If you can't change the tables structure to include an extra visible key to be used as PRIMARY KEY, you can make use of the  INVISIBLE COLUMN feature available since 8.0.23: https://dev.mysql.com/doc/refman/8.0/en/invisible-columns.html

Checking instance configuration...

{
    "status": "error"
}

上面提示是说jycs.t_cs表没有主键,下面对jycs._t_cs表添加主键

mysql> ALTER TABLE jycs.t_cs MODIFY COLUMN id INT PRIMARY KEY;
Query OK, 0 rows affected (1.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

再次执行检测实例命令

 MySQL  JS > dba.checkInstanceConfiguration('ic@mic1:3306')
Please provide the password for 'ic@mic1:3306': ******
Save password for 'ic@mic1:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as 10.18.13.236: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 '10.18.13.236:3306' is valid to be used in an InnoDB cluster.

{
    "status": "ok"
}

检测通过,下面对另外两个实例执行检测命令

[root@mic2 ~]# mysqlsh --log-level=DEBUG3
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.
 MySQL  JS > dba.checkInstanceConfiguration('ic@mic2:3306')
Please provide the password for 'ic@mic2:3306': ******
Save password for 'ic@mic2:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as 10.18.13.237: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 '10.18.13.237:3306' is valid to be used in an InnoDB cluster.

{
    "status": "ok"
}

[root@mic3 ~]# mysqlsh --log-level=DEBUG3
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.
 MySQL  JS > dba.checkInstanceConfiguration('ic@mic3:3306')
Please provide the password for 'ic@mic3:3306': ******
Save password for 'ic@mic3:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as 10.18.13.238: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 '10.18.13.238:3306' is valid to be used in an InnoDB cluster.

{
    "status": "ok"
}

检测全部通过。

配置实例
如果在针对实例运行dba.checkInstanceConfiguration()生成的报告中发现了配置问题,请连接到计算机并重新配置服务器实例。AdminAPI提 供了dba.configureLocalInstance()函数来查找MySQL服务器的配置文件并修改它,以确保该实例是正确配置InnoDB集群的。或者,根据报告 中的信息手动更改实例的选项文件。无论您以何种方式更改配置,都可能需要重新启动MySQL以确保检测到配置更改。

推荐的方法是登录远程机器,以root用户运行MySQL Shell,然后连接到本地MySQL服务器:

[root@mic1 ~]# mysqlsh --log-level=DEBUG3

dba.configureLocalInstance()方法验证一个适合集群使用的用户,该用户用于集群成员之间的连接。默认情况下,root用户不能进行远程登 录,因此您有三个选项来继续配置:为root用户启用远程连接、创建新用户或以上两个选项都不使用。下面的示例演示了第二个选项,即为集群 创建一个新用户。

 MySQL  JS > dba.configureLocalInstance('ic@mic1:3306')
WARNING: This function is deprecated and will be removed in a future release of MySQL Shell, use dba.configureInstance()  instead.
Please provide the password for 'ic@mic1:3306': ******
Save password for 'ic@mic1:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Configuring local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as 10.18.13.236:3306

The instance '10.18.13.236:3306' is valid to be used in an InnoDB cluster.
The instance '10.18.13.236:3306' is already ready to be used in an InnoDB cluster.


 MySQL  JS > dba.configureLocalInstance('ic@mic2:3306')
WARNING: This function is deprecated and will be removed in a future release of MySQL Shell, use dba.configureInstance()  instead.
Please provide the password for 'ic@mic2:3306': ******
Save password for 'ic@mic2:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Configuring local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as 10.18.13.237:3306

The instance '10.18.13.237:3306' is valid to be used in an InnoDB cluster.
The instance '10.18.13.237:3306' is already ready to be used in an InnoDB cluster.




 MySQL  JS > dba.configureLocalInstance('ic@mic3:3306')
WARNING: This function is deprecated and will be removed in a future release of MySQL Shell, use dba.configureInstance()  instead.
Please provide the password for 'ic@mic3:3306': ******
Save password for 'ic@mic3:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Configuring local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as 10.18.13.238:3306

The instance '10.18.13.238:3306' is valid to be used in an InnoDB cluster.
The instance '10.18.13.238:3306' is already ready to be used in an InnoDB cluster.

创建群集
准备好实例后,请使用dba。createCluster函数,用于创建集群。运行MySQL Shell的机器被用作集群的种子实例。seed实例会被复制到你添加 到集群中的其他实例上,使它们成为seed实例的副本。登录实例并在本地运行MySQL Shell。

[root@mic1 /]# mysqlsh --uri ic@mic1:3306
Please provide the password for 'ic@mic1:3306': ******
Save password for 'ic@mic1:3306'? [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 'ic@mic1:3306'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 8
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  mic1:3306  JS >

使用dba.createCluster(name)函数创建集群,并将返回的集群分配给一个名为cluster的变量:

 MySQL  mic1:3306  JS > var cluster = dba.createCluster('prodCluster')
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 on instance '10.18.13.236:3306'.

Validating instance configuration at mic1:3306...

This instance reports its own address as 10.18.13.236:3306

Instance configuration is suitable.
NOTE: TLS not available at '10.18.13.236:3306', assuming memberSslMode to be DISABLED
NOTE: Group Replication will communicate with other members using '10.18.13.236:33061'. Use the localAddress option to  override.

* Checking connectivity and SSL configuration...

WARNING: Instance '10.18.13.236:3306' cannot persist Group Replication 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.
Creating InnoDB Cluster 'prodCluster' on '10.18.13.236:3306'...

Adding Seed Instance...
Cluster successfully created. Use Cluster.addInstance() to add MySQL instances.
At least 3 instances are needed for the cluster to be able to withstand up to
one server failure.

 MySQL  mic1:3306  JS >

如果遇到与元数据不可访问相关的错误,可能是配置了环回网络接口。为了保证InnoDB集群的正确使用,请关闭环回接口。

要检查集群是否已创建,请使用集群实例的status()函数

 MySQL  mic1:3306  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": "10.18.13.236:3306",
        "ssl": "DISABLED",
        "status": "OK_NO_TOLERANCE",
        "statusText": "Cluster is NOT tolerant to any failures.",
        "topology": {
            "10.18.13.236:3306": {
                "address": "10.18.13.236:3306",
                "memberRole": "PRIMARY",
                "mode": "R/W",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "10.18.13.236:3306"
}
 MySQL  mic1:3306  JS >

一旦服务器实例属于一个集群,重要的是只使用MySQL Shell和AdminAPI管理它们。不支持在实例添加到集群后手动更改组复制的配置。类似地 ,不支持在AdminAPI配置实例后修改对InnoDB集群至关重要的服务器变量,如server_uuid。

使用cluster. addinstance (instance)函数向集群添加更多实例,其中instance是连接到本地实例的URI类型字符串。这些实例必须已经配置 为集群使用。集群中至少需要3个实例才能容忍其中一个实例的故障。添加更多的实例可以提高对实例失败的容忍度。添加一个实例到集群问题 :


 MySQL  mic1:3306  JS > cluster.addInstance('ic@mic2:3306');
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
ERROR: Unable to connect to the target instance 'mic2:3306'. Please verify the connection settings, make sure the instance is  available and try again.
Cluster.addInstance: Could not open connection to 'mic2:3306': Can't connect to MySQL server on 'mic2:3306' (113) (MySQL Error  2003)
 MySQL  mic1:3306  JS > cluster.addInstance('ic@mic2:3306');
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely  overwrite the state of '10.18.13.237:3306' with a physical snapshot from an existing cluster member. To use this method by  default, set the 'recoveryMethod' option to 'clone'.

The incremental state recovery may be safely used if you are sure all updates ever executed in the cluster were done with  GTIDs enabled, there are no purged transactions and the new instance contains the same GTID set as the cluster or a subset of  it. To use this method by default, set the 'recoveryMethod' option to 'incremental'.

Incremental state recovery was selected because it seems to be safely usable.

Validating instance configuration at mic2:3306...

This instance reports its own address as 10.18.13.237:3306

Instance configuration is suitable.
ERROR: RuntimeError: Cannot add an instance with the same server UUID (684e1f7d-6f47-11ef-a6d5-005056a3a162) of an active  member of the cluster '10.18.13.236:3306'. Please change the server UUID of the instance to add, all members must have a  unique server UUID.
Cluster.addInstance: Cannot add an instance with the same server UUID (684e1f7d-6f47-11ef-a6d5-005056a3a162) of an active  member of the cluster '10.18.13.236:3306'. Please change the server UUID of the instance to add, all members must have a  unique server UUID. (RuntimeError)

在${data_dir}/auto.cnf中的server-uuid值是一样的,要处理该问题只需要删除auto.cnf文件,就会自动创建和生成新的server-uuid值。

[root@mic2 mysql]# cat auto.cnf
[auto]
server-uuid=684e1f7d-6f47-11ef-a6d5-005056a3a162
[root@mic2 mysql]# rm -rf auto.cnf
[root@mic2 mysql]# service mysqld restart
Shutting down MySQL.... SUCCESS!
Starting MySQL.. SUCCESS!
[root@mic2 mysql]# cat auto.cnf
[auto]
server-uuid=c9f76f9e-0de1-11f0-9924-005056b9de82


[root@mic3 mysql]# rm -rf auto.cnf
[root@mic3 mysql]# service mysqld restart
Shutting down MySQL.... SUCCESS!
Starting MySQL.. SUCCESS!
[root@mic3 mysql]# cat auto.cnf
[auto]
server-uuid=ccdd7fe7-0de1-11f0-9436-005056b9890f

 MySQL  mic1:3306  JS > cluster.addInstance('ic@mic2:3306');
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely  overwrite the state of '10.18.13.237:3306' with a physical snapshot from an existing cluster member. To use this method by  default, set the 'recoveryMethod' option to 'clone'.

The incremental state recovery may be safely used if you are sure all updates ever executed in the cluster were done with  GTIDs enabled, there are no purged transactions and the new instance contains the same GTID set as the cluster or a subset of  it. To use this method by default, set the 'recoveryMethod' option to 'incremental'.

Incremental state recovery was selected because it seems to be safely usable.

Validating instance configuration at mic2:3306...

This instance reports its own address as 10.18.13.237:3306

Instance configuration is suitable.
NOTE: Group Replication will communicate with other members using '10.18.13.237:33061'. Use the localAddress option to  override.

* Checking connectivity and SSL configuration...
A new instance will be added to the InnoDB Cluster. Depending on the amount of
data on the cluster this might take from a few seconds to several hours.

WARNING: Instance '10.18.13.237:3306' cannot persist Group Replication 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.
Adding instance to the cluster...

Monitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.
Incremental state recovery is now in progress.

* Waiting for distributed recovery to finish...
NOTE: '10.18.13.237:3306' is being recovered from '10.18.13.236:3306'
* Distributed recovery has finished

WARNING: Instance '10.18.13.236: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.
The instance '10.18.13.237:3306' was successfully added to the cluster.

 MySQL  mic1:3306  JS > cluster.addInstance('ic@mic3:3306');
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely  overwrite the state of '10.18.13.238:3306' with a physical snapshot from an existing cluster member. To use this method by  default, set the 'recoveryMethod' option to 'clone'.

The incremental state recovery may be safely used if you are sure all updates ever executed in the cluster were done with  GTIDs enabled, there are no purged transactions and the new instance contains the same GTID set as the cluster or a subset of  it. To use this method by default, set the 'recoveryMethod' option to 'incremental'.

Incremental state recovery was selected because it seems to be safely usable.

Validating instance configuration at mic3:3306...

This instance reports its own address as 10.18.13.238:3306

Instance configuration is suitable.
NOTE: Group Replication will communicate with other members using '10.18.13.238:33061'. Use the localAddress option to  override.

* Checking connectivity and SSL configuration...
A new instance will be added to the InnoDB Cluster. Depending on the amount of
data on the cluster this might take from a few seconds to several hours.

WARNING: Instance '10.18.13.238:3306' cannot persist Group Replication 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.
Adding instance to the cluster...

Monitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.
Incremental state recovery is now in progress.

* Waiting for distributed recovery to finish...
NOTE: '10.18.13.238:3306' is being recovered from '10.18.13.236:3306'
* Distributed recovery has finished

WARNING: Instance '10.18.13.236: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 '10.18.13.237: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.
The instance '10.18.13.238:3306' was successfully added to the cluster.

在这个阶段,服务器实例已经被添加到集群中,但是对InnoDB集群元数据的更改只在您当前连接的实例上进行。为了让集群中所有实例的配置更 改持久化,用户必须连接到每个实例,并在添加的每个实例上本地运行dba.configureLocalInstance()。这对于确保实例在离开集群时重新加 入集群是至关重要的。

要将InnoDB集群的元数据持久化到所有的实例中,请登录到你添加到集群中的每个实例,并在本地运行MySQL Shell。

  MySQL  mic1:3306  JS > dba.checkInstanceConfiguration('ic@mic1:3306')
Please provide the password for 'ic@mic1:3306': ******
Save password for 'ic@mic1:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as 10.18.13.236: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 '10.18.13.236:3306' is valid to be used in an InnoDB cluster.

{
    "status": "ok"
}
 MySQL  mic1:3306  JS >

[root@mic2 ~]# mysqlsh --log-level=DEBUG3
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.
 MySQL  JS > dba.checkInstanceConfiguration('ic@mic2:3306')
Please provide the password for 'ic@mic2:3306': ******
Save password for 'ic@mic2:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as 10.18.13.237: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 '10.18.13.237:3306' is valid to be used in an InnoDB cluster.

{
    "status": "ok"
}




[root@mic3 ~]# mysqlsh --log-level=DEBUG3
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.
 MySQL  JS > dba.checkInstanceConfiguration('ic@mic3:3306')
Please provide the password for 'ic@mic3:3306': ******
Save password for 'ic@mic3:3306'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as 10.18.13.238: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 '10.18.13.238:3306' is valid to be used in an InnoDB cluster.

{
    "status": "ok"
}

对添加到集群中的每个服务器实例重复此过程。类似地,如果你修改了集群的结构,例如改变了实例的数量,你需要对每个服务器实例重复这个 过程,以相应地更新集群中每个实例的InnoDB集群元数据。

要检查集群是否已创建,请使用集群实例的status()函数。

 MySQL  mic1:3306  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": "10.18.13.236:3306",
        "ssl": "DISABLED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "10.18.13.236:3306": {
                "address": "10.18.13.236:3306",
                "memberRole": "PRIMARY",
                "mode": "R/W",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            },
            "10.18.13.237:3306": {
                "address": "10.18.13.237:3306",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            },
            "10.18.13.238:3306": {
                "address": "10.18.13.238:3306",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "10.18.13.236:3306"
}

下面来测试一个集群的同步功能
在主库上向jycs库的t_cs表插入记录

mysql> insert into t_cs values(6,'hi');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t_cs;
+----+------+
| id | name |
+----+------+
|  1 | cs   |
|  2 | ab   |
|  3 | cd   |
|  4 | ef   |
|  5 | gh   |
|  6 | hi   |
+----+------+
6 rows in set (0.00 sec)

查看第二、第三个实例是否已经同步

 MySQL  mic2:3306  JS > \sql
Switching to SQL mode... Commands end with ;
Fetching global names for auto-completion... Press ^C to stop.
 MySQL  mic2:3306  SQL > select * from jycs.t_cs;
+----+------+
| id | name |
+----+------+
|  1 | cs   |
|  2 | ab   |
|  3 | cd   |
|  4 | ef   |
|  5 | gh   |
|  6 | hi   |
+----+------+
6 rows in set (0.0006 sec)
 MySQL  mic2:3306  SQL >


 MySQL  mic3:3306  JS > \sql
Switching to SQL mode... Commands end with ;
Fetching global names for auto-completion... Press ^C to stop.
 MySQL  mic3:3306  SQL > select * from jycs.t_cs;
+----+------+
| id | name |
+----+------+
|  1 | cs   |
|  2 | ab   |
|  3 | cd   |
|  4 | ef   |
|  5 | gh   |
|  6 | hi   |
+----+------+
6 rows in set (0.0008 sec)
 MySQL  mic3:3306  SQL >

至此使用MySQL Shell部署生产环境InnoDB集群完成。

MySQL 5.7使用MySQL Shell 部署沙箱InnoDB集群

InnoDB集群
MySQL InnoDB集群为MySQL提供了一个完整的高可用解决方案。MySQL Shell包含AdminAPI,它允许您轻松配置和管理一组至少三个MySQL服务器 实例,以发挥InnoDB集群的功能。每个MySQL server实例运行MySQL Group Replication,它提供了在InnoDB集群中复制数据的机制,具有内置 的故障转移。AdminAPI消除了在InnoDB集群中直接使用组复制的需要,但更多信息请参见第17章,其中详细说明了组复制。MySQL Router可以根 据你部署的集群自动配置自己,透明地将客户端应用程序连接到服务器实例。在服务器实例出现意外故障时,集群将自动重新配置。在默认的单 主模式下,一个InnoDB集群有一个读写服务器实例–主。多个辅助服务器实例是主服务器的副本。当主节点故障时,从节点自动升级为主节点 。MySQL路由器检测到这一点并将客户端应用程序转发给新的主服务器。高级用户还可以配置一个集群以拥有多个主用服务器。

使用AdminAPI
MySQL Shell包含AdminAPI,可以通过dba全局变量及其相关方法访问。dba变量的方法使你能够部署、配置和管理InnoDB集群。例如,使用 dba.createCluster()方法创建一个InnoDB集群。MySQL Shell为AdminAPI提供在线帮助。要列出所有可用的dba命令,请使用dba.help()方法。要获得关于特定方法的在线帮助,请使用通用格 式object.help(’methodname’)。例如:

 MySQL  localhost:33060+  world_x  JS > dba.help('getCluster')
NAME
      getCluster - Returns an object representing a Cluster.

SYNTAX
      dba.getCluster([name][, options])

WHERE
      name: Parameter to specify the name of the Cluster to be returned.
      options: Dictionary with additional options.

RETURNS
      The Cluster object identified by the given name or the default Cluster.

DESCRIPTION
      If name is not specified or is null, the default Cluster will be
      returned.

      If name is specified, and no Cluster with the indicated name is found, an
      error will be raised.

      The options dictionary may contain the following attributes:

      - connectToPrimary: boolean value used to indicate if Shell should
        automatically connect to the primary member of the Cluster or not.
        Deprecated and ignored, Shell will attempt to connect to the primary by
        default and fallback to a secondary when not possible.


创建InnoDB集群
这里将介绍创建InnoDB集群的不同方法,对服务器实例的要求以及部署集群需要安装的软件。

部署场景
InnoDB集群支持以下部署场景:
.沙箱部署:如果你想在部署到生产环境之前测试一下InnoDB集群,它提供的沙盒特性可以让你在本地机器上快速设置集群。沙盒服务器实例是根 据需要配置创建的,你可以尝试使用InnoDB集群来熟悉所使用的技术

.生产环境部署:如果你想在一个完整的生产环境中使用InnoDB集群,你需要配置所需的机器数量,然后将服务器实例部署到这些机器上。生产环 境的部署可以让你充分利用InnoDB集群的高可用性特性。

InnoDB集群要求
在安装InnoDB集群的生产部署之前,请确保您打算使用的服务器实例满足以下要求。
.InnoDB集群使用组复制,因此您的服务器实例必须满足相同的要求。AdminAPI提供dba.checkInstanceConfiguration()方法来验证实例是否 满足组复制要求,并提供dba.configureLocalInstance()方法来配置实例以满足要求。
 MySQL  localhost:33060+  world_x  JS > dba.checkInstanceConfiguration()
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3306 for use in an InnoDB cluster...

This instance reports its own address as mysqlcs: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...
Instance configuration is compatible with InnoDB cluster

The instance 'mysqlcs:3306' is valid to be used in an InnoDB cluster.

{
    "status": "ok"
}


[root@mysqlcs ~]# mysqlsh root@localhost:3307/
Please provide the password for 'root@localhost:3307': ******
Save password for 'root@localhost:3307'? [Y]es/[N]o/Ne[v]er (default No): n
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:3307'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 26
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  localhost:3307  JS > dba.checkInstanceConfiguration()
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3307 for use in an InnoDB cluster...

This instance reports its own address as mysqlcs:3307
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...
Instance configuration is compatible with InnoDB cluster

The instance 'mysqlcs:3307' is valid to be used in an InnoDB cluster.

{
    "status": "ok"
}


[root@mysqlcs ~]# mysqlsh root@localhost:3308/
Please provide the password for 'root@localhost:3308': ******
Save password for 'root@localhost:3308'? [Y]es/[N]o/Ne[v]er (default No): n
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:3308'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 22
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  localhost:3308  JS > dba.checkInstanceConfiguration()
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
Validating local MySQL instance listening at port 3308 for use in an InnoDB cluster...

This instance reports its own address as mysqlcs:3308
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...
Instance configuration is compatible with InnoDB cluster

The instance 'mysqlcs:3308' is valid to be used in an InnoDB cluster.

{
    "status": "ok"
}

当使用沙盒部署时,实例被配置为自动满足这些需求。

。MySQL Shell用于在InnoDB集群中配置服务器的配置脚本需要使用Python 2.7版本。对于沙盒部署,需要在部署所用的单机上安装Python,而 生产环境部署则需要在每个服务器实例上安装Python
在Windows上,MySQL Shell包含Python,不需要用户配置。在Unix中,Python必须是shell环境的一部分。要检查系统是否正确配置了Python, 请执行以下命令:

[root@mysqlcs ~]# /usr/bin/env python
Python 2.7.5 (default, Nov  1 2018, 03:12:47)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36.0.1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
[root@mysqlcs ~]#

如果Python解释器启动,则不需要进一步操作。如果前面的命令失败,在/usr/bin/python和您选择的Python二进制文件之间创建一个软链接。

安装方法
安装InnoDB集群的方法取决于你打算使用的部署类型。对于沙盒部署,将InnoDB集群的组件安装到单机上。沙盒部署是在一台机器上进行的,因 此只需要在本地机器上安装一次。类似地,也不需要单独连接到实例进行配置,沙盒实例是本地的。对于生产环境部署,要将组件安装到要添加 到集群的每台机器上。生产部署使用多台远程主机运行MySQL server实例,因此需要使用SSH或Windows remote desktop等工具连接到每台机器 ,以执行安装组件和配置server实例等任务。InnoDB集群的安装方法如下:

.使用以下文档下载和安装组件
.MySQL服务器-参见第2章,安装和升级MySQL
.MySQL Shell -参见第19.3.1节“安装MySQL Shell”。
.MySQL路由器-参见安装MySQL路由器

.在Windows上,你可以使用MySQL安装程序进行沙盒部署

InnoDB集群的沙盒部署
这里介绍如何设置沙盒环境下的InnoDB集群部署。你可以使用MySQL Shell和AdminAPI来创建和管理你的InnoDB集群。

最初部署和使用MySQL的本地沙箱实例是探索InnoDB集群的好方法。在部署到生产服务器之前,你可以在本地完全测试InnoDB集群。MySQL Shell 内置了创建沙盒实例的功能,这些沙盒实例经过正确配置,可以在本地部署的场景中使用组复制。

沙盒实例只适合在本地机器上部署和运行,用于测试。在生产环境中,MySQL Server实例部署在网络上的各种主机上。

本教程展示了如何使用MySQL Shell创建一个由三个MySQL服务器实例组成的InnoDB集群。
.部署沙盒实例
.创建InnoDB沙箱集群
.向InnoDB集群添加实例
.持久化配置

部署沙盒实例
MySQL Shell包含添加dba全局变量的AdminAPI,它提供了管理沙盒实例的函数。在这个示例设置中,使用dba.deploySandboxInstance()创建 了三个沙盒实例。

通过执行下面的命令,从命令提示符启动MySQL Shell:

[root@localhost /]# mysqlsh
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.
 MySQL  JS >

MySQL Shell除了原生的SQL模式外,还提供了JavaScript和Python两种脚本语言模式。在本指南中,MySQL Shell主要用于JavaScript模式。 MySQL Shell启动时默认是JavaScript模式。通过执行\js命令切换JavaScript模式,执行\py命令切换Python模式,执行\sql命令切换sql模式。 执行\js命令,确保你处于JavaScript模式,然后执行:

 MySQL  JS > dba.deploySandboxInstance(3310)
A new MySQL sandbox instance will be created on this host in
/root/mysql-sandboxes/3310

Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.

Please enter a MySQL root password for the new instance: ******

Deploying new MySQL instance...

Instance localhost:3310 successfully deployed and started.
Use shell.connect('root@localhost:3310') to connect to the instance.

 MySQL  JS >

要部署更多的沙盒服务器实例,请重复上述步骤,并选择不同的端口号。对于每个额外的沙盒实例执行:

 MySQL  JS > dba.deploySandboxInstance(3320)
A new MySQL sandbox instance will be created on this host in
/root/mysql-sandboxes/3320

Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.

Please enter a MySQL root password for the new instance: ******

Deploying new MySQL instance...

Instance localhost:3320 successfully deployed and started.
Use shell.connect('root@localhost:3320') to connect to the instance.

 MySQL  JS > dba.deploySandboxInstance(3330)
A new MySQL sandbox instance will be created on this host in
/root/mysql-sandboxes/3330

Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.

Please enter a MySQL root password for the new instance: ******

Deploying new MySQL instance...

Instance localhost:3330 successfully deployed and started.
Use shell.connect('root@localhost:3330') to connect to the instance.

提示输入实例的root密码。


[root@localhost ~]# mysql -h 10.18.13.239 -P 3310 -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

[root@localhost /]# mysql -h 10.18.13.239 -P 3320 -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.25 sec)

mysql> exit
Bye
[root@localhost /]# mysql -h 10.18.13.239 -P 3330 -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql>

在JavaScript和Python模式中不需要用分号结束命令。

传递给deploySandboxInstance()的参数是MySQL服务器监听连接的TCP端口号。默认情况下,沙盒在Unix系统中创建在$HOME/mysqlsandboxes/ port目录下。对于Microsoft Windows系统,该目录是%userprofile% \MySQL\ MySQL -sandboxes\port。

[root@localhost ~]# ls -lrt
total 24
-rw-r--r--. 1 root root 2174 Oct 11  2017 initial-setup-ks.cfg
-rw-------. 1 root root 2126 Oct 12  2017 anaconda-ks.cfg
drwxr-xr-x. 2 root root    6 Jun 10  2019 Videos
drwxr-xr-x. 2 root root    6 Jun 10  2019 Templates
drwxr-xr-x. 2 root root    6 Jun 10  2019 Public
drwxr-xr-x. 2 root root    6 Jun 10  2019 Pictures
drwxr-xr-x. 2 root root    6 Jun 10  2019 Music
drwxr-xr-x. 2 root root    6 Jun 10  2019 Downloads
drwxr-xr-x. 2 root root    6 Jun 10  2019 Documents
drwxr-xr-x. 2 root root    6 Jun 10  2019 Desktop
drwxr-xr-x. 2 root root    6 Jun 17  2019 perl5
-rw-r--r--. 1 root root 1069 Aug 19  2020 viewmemory.c
-rwxrwxrwx. 1 root root 8784 Aug 19  2020 viewmemory
drwxr-xr-x. 3 root root   17 Mar 26 15:35 mysql-sandboxes


[root@localhost mysql-sandboxes]# pwd
/root/mysql-sandboxes
[root@localhost mysql-sandboxes]# ll
total 12
drwxr-xr-x. 5 root root 4096 Mar 26 15:35 3310
drwxr-xr-x. 5 root root 4096 Mar 26 15:48 3320
drwxr-xr-x. 5 root root 4096 Mar 26 15:48 3330

每个实例都有自己的密码。在本教程中,为所有沙盒定义相同的密码会使其更容易,但请记住在生产部署中为每个实例使用不同的密码。
要记住一点,一定要删除ssl相关的文件

 MySQL  JS > dba.stopSandboxInstance(3310)
The MySQL sandbox instance on this host in
3320 will be stopped

Please enter the MySQL root password for the instance 'localhost:3320': ******

Stopping MySQL instance...

Instance localhost:3310 successfully stopped.
 MySQL  JS > dba.stopSandboxInstance(3320)
The MySQL sandbox instance on this host in
3320 will be stopped

Please enter the MySQL root password for the instance 'localhost:3320': ******

Stopping MySQL instance...

Instance localhost:3320 successfully stopped.

 MySQL  JS > dba.stopSandboxInstance(3330)
The MySQL sandbox instance on this host in
3330 will be stopped

Please enter the MySQL root password for the instance 'localhost:3330': ******

Stopping MySQL instance...

Instance localhost:3330 successfully stopped.

 MySQL  JS > dba.startSandboxInstance(3330)

Starting MySQL instance...

Instance localhost:3330 successfully started.

 MySQL  JS > dba.startSandboxInstance(3320)

Starting MySQL instance...

Instance localhost:3320 successfully started.

[root@localhost mysql-sandboxes]# cd 3310/sandboxdata/
[root@localhost sandboxdata]# ll
total 110684
-rw-r-----. 1 root root       56 Mar 27 11:27 auto.cnf
-rw-------. 1 root root     1675 Mar 27 11:28 ca-key.pem
-rw-r--r--. 1 root root     1107 Mar 27 11:28 ca.pem
-rw-r--r--. 1 root root     1107 Mar 27 11:28 client-cert.pem
-rw-------. 1 root root     1675 Mar 27 11:28 client-key.pem
-rw-r-----. 1 root root    10335 Mar 27 11:37 error.log
-rw-r-----. 1 root root      356 Mar 27 11:37 ib_buffer_pool
-rw-r-----. 1 root root 12582912 Mar 27 11:37 ibdata1
-rw-r-----. 1 root root 50331648 Mar 27 11:37 ib_logfile0
-rw-r-----. 1 root root 50331648 Mar 27 11:27 ib_logfile1
-rw-r-----. 1 root root      169 Mar 27 11:27 localhost-bin.000001
-rw-r-----. 1 root root      169 Mar 27 11:37 localhost-bin.000002
-rw-r-----. 1 root root       46 Mar 27 11:28 localhost-bin.index
drwxr-x---. 2 root root     4096 Mar 27 11:27 mysql
drwxr-x---. 2 root root     8192 Mar 27 11:27 performance_schema
-rw-------. 1 root root     1679 Mar 27 11:28 private_key.pem
-rw-r--r--. 1 root root      451 Mar 27 11:28 public_key.pem
-rw-r--r--. 1 root root     1107 Mar 27 11:28 server-cert.pem
-rw-------. 1 root root     1679 Mar 27 11:28 server-key.pem
drwxr-x---. 2 root root     8192 Mar 27 11:27 sys
[root@localhost sandboxdata]# rm -rf *pem
[root@localhost sandboxdata]# ll
total 110652
-rw-r-----. 1 root root       56 Mar 27 11:27 auto.cnf
-rw-r-----. 1 root root    10335 Mar 27 11:37 error.log
-rw-r-----. 1 root root      356 Mar 27 11:37 ib_buffer_pool
-rw-r-----. 1 root root 12582912 Mar 27 11:37 ibdata1
-rw-r-----. 1 root root 50331648 Mar 27 11:37 ib_logfile0
-rw-r-----. 1 root root 50331648 Mar 27 11:27 ib_logfile1
-rw-r-----. 1 root root      169 Mar 27 11:27 localhost-bin.000001
-rw-r-----. 1 root root      169 Mar 27 11:37 localhost-bin.000002
-rw-r-----. 1 root root       46 Mar 27 11:28 localhost-bin.index
drwxr-x---. 2 root root     4096 Mar 27 11:27 mysql
drwxr-x---. 2 root root     8192 Mar 27 11:27 performance_schema
drwxr-x---. 2 root root     8192 Mar 27 11:27 sys

[root@localhost mysql-sandboxes]# cd 3320/sandboxdata/
[root@localhost sandboxdata]# ll
total 110684
-rw-r-----. 1 root root       56 Mar 27 11:27 auto.cnf
-rw-------. 1 root root     1675 Mar 27 11:28 ca-key.pem
-rw-r--r--. 1 root root     1107 Mar 27 11:28 ca.pem
-rw-r--r--. 1 root root     1107 Mar 27 11:28 client-cert.pem
-rw-------. 1 root root     1675 Mar 27 11:28 client-key.pem
-rw-r-----. 1 root root    10335 Mar 27 11:37 error.log
-rw-r-----. 1 root root      356 Mar 27 11:37 ib_buffer_pool
-rw-r-----. 1 root root 12582912 Mar 27 11:37 ibdata1
-rw-r-----. 1 root root 50331648 Mar 27 11:37 ib_logfile0
-rw-r-----. 1 root root 50331648 Mar 27 11:27 ib_logfile1
-rw-r-----. 1 root root      169 Mar 27 11:27 localhost-bin.000001
-rw-r-----. 1 root root      169 Mar 27 11:37 localhost-bin.000002
-rw-r-----. 1 root root       46 Mar 27 11:28 localhost-bin.index
drwxr-x---. 2 root root     4096 Mar 27 11:27 mysql
drwxr-x---. 2 root root     8192 Mar 27 11:27 performance_schema
-rw-------. 1 root root     1679 Mar 27 11:28 private_key.pem
-rw-r--r--. 1 root root      451 Mar 27 11:28 public_key.pem
-rw-r--r--. 1 root root     1107 Mar 27 11:28 server-cert.pem
-rw-------. 1 root root     1679 Mar 27 11:28 server-key.pem
drwxr-x---. 2 root root     8192 Mar 27 11:27 sys
[root@localhost sandboxdata]# rm -rf *pem
[root@localhost sandboxdata]# ll
total 110652
-rw-r-----. 1 root root       56 Mar 27 11:27 auto.cnf
-rw-r-----. 1 root root    10335 Mar 27 11:37 error.log
-rw-r-----. 1 root root      356 Mar 27 11:37 ib_buffer_pool
-rw-r-----. 1 root root 12582912 Mar 27 11:37 ibdata1
-rw-r-----. 1 root root 50331648 Mar 27 11:37 ib_logfile0
-rw-r-----. 1 root root 50331648 Mar 27 11:27 ib_logfile1
-rw-r-----. 1 root root      169 Mar 27 11:27 localhost-bin.000001
-rw-r-----. 1 root root      169 Mar 27 11:37 localhost-bin.000002
-rw-r-----. 1 root root       46 Mar 27 11:28 localhost-bin.index
drwxr-x---. 2 root root     4096 Mar 27 11:27 mysql
drwxr-x---. 2 root root     8192 Mar 27 11:27 performance_schema
drwxr-x---. 2 root root     8192 Mar 27 11:27 sys

[root@localhost mysql-sandboxes]# cd 3330/sandboxdata/
[root@localhost sandboxdata]# ll
total 110684
-rw-r-----. 1 root root       56 Mar 27 11:27 auto.cnf
-rw-------. 1 root root     1675 Mar 27 11:28 ca-key.pem
-rw-r--r--. 1 root root     1107 Mar 27 11:28 ca.pem
-rw-r--r--. 1 root root     1107 Mar 27 11:28 client-cert.pem
-rw-------. 1 root root     1675 Mar 27 11:28 client-key.pem
-rw-r-----. 1 root root    10335 Mar 27 11:37 error.log
-rw-r-----. 1 root root      356 Mar 27 11:37 ib_buffer_pool
-rw-r-----. 1 root root 12582912 Mar 27 11:37 ibdata1
-rw-r-----. 1 root root 50331648 Mar 27 11:37 ib_logfile0
-rw-r-----. 1 root root 50331648 Mar 27 11:27 ib_logfile1
-rw-r-----. 1 root root      169 Mar 27 11:27 localhost-bin.000001
-rw-r-----. 1 root root      169 Mar 27 11:37 localhost-bin.000002
-rw-r-----. 1 root root       46 Mar 27 11:28 localhost-bin.index
drwxr-x---. 2 root root     4096 Mar 27 11:27 mysql
drwxr-x---. 2 root root     8192 Mar 27 11:27 performance_schema
-rw-------. 1 root root     1679 Mar 27 11:28 private_key.pem
-rw-r--r--. 1 root root      451 Mar 27 11:28 public_key.pem
-rw-r--r--. 1 root root     1107 Mar 27 11:28 server-cert.pem
-rw-------. 1 root root     1679 Mar 27 11:28 server-key.pem
drwxr-x---. 2 root root     8192 Mar 27 11:27 sys
[root@localhost sandboxdata]# rm -rf *pem
[root@localhost sandboxdata]# ll
total 110652
-rw-r-----. 1 root root       56 Mar 27 11:27 auto.cnf
-rw-r-----. 1 root root    10335 Mar 27 11:37 error.log
-rw-r-----. 1 root root      356 Mar 27 11:37 ib_buffer_pool
-rw-r-----. 1 root root 12582912 Mar 27 11:37 ibdata1
-rw-r-----. 1 root root 50331648 Mar 27 11:37 ib_logfile0
-rw-r-----. 1 root root 50331648 Mar 27 11:27 ib_logfile1
-rw-r-----. 1 root root      169 Mar 27 11:27 localhost-bin.000001
-rw-r-----. 1 root root      169 Mar 27 11:37 localhost-bin.000002
-rw-r-----. 1 root root       46 Mar 27 11:28 localhost-bin.index
drwxr-x---. 2 root root     4096 Mar 27 11:27 mysql
drwxr-x---. 2 root root     8192 Mar 27 11:27 performance_schema
drwxr-x---. 2 root root     8192 Mar 27 11:27 sys

MySQL  JS > dba.startSandboxInstance(3330)

Starting MySQL instance...

Instance localhost:3330 successfully started.

 MySQL  JS > dba.startSandboxInstance(3320)

Starting MySQL instance...

Instance localhost:3320 successfully started.

 MySQL  JS > dba.startSandboxInstance(3310)

Starting MySQL instance...

Instance localhost:3320 successfully started.

创建沙箱InnoDB集群
下一步是创建InnoDB集群,同时连接到seed MySQL服务器实例。seed实例包含要复制到其他实例的数据。在这个例子中,沙盒实例是空的,因此 我们可以选择任何实例。

将MySQL Shell连接到种子实例,在本例中是端口3310的实例:

 MySQL  JS > \connect root@localhost:3310
Creating a session to 'root@localhost:3310'
Please provide the password for 'root@localhost:3310': ******
Save password for 'root@localhost:3310'? [Y]es/[N]o/Ne[v]er (default No):
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 6
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  localhost:3310  JS >

如果不禁用ssl就会出现如下错误:

 MySQL  JS > \connect root@localhost:3310
Creating a session to 'root@localhost:3310'
Please provide the password for 'root@localhost:3310': ******
MySQL Error 2026 (HY000): SSL connection error: error:14077102:SSL routines:SSL23_GET_SERVER_HELLO:unsupported protocol

上面报错信息是使用了SSL连接,协议不支持,下面使用–ssl-mode来禁用SSL连接。

 MySQL  JS > \connect root@localhost:3310 --ssl-mode=DISABLED
Creating a session to 'root@localhost:3310?ssl-mode=disabled'
Please provide the password for 'root@localhost:3310': ******
Save password for 'root@localhost:3310'? [Y]es/[N]o/Ne[v]er (default No): n
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 13
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  localhost:3310  JS >

\connect MySQL Shell命令是shell.connect()方法的快捷方式:

 MySQL  JS > shell.connect("root@localhost:3310?ssl-mode=DISABLED");
Creating a session to 'root@localhost:3310?ssl-mode=DISABLED'
Please provide the password for 'root@localhost:3310': ******
Save password for 'root@localhost:3310'? [Y]es/[N]o/Ne[v]er (default No): n
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 15
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.

 MySQL  localhost:3310  JS >

连接之后,AdminAPI可以写入本地实例的选项文件。这与生产部署不同,在生产部署中,需要连接到远程实例并在实例上本地运行MySQL Shell 应用程序,然后AdminAPI才能写入实例的选项文件。

使用dba.createCluster()方法创建以当前连接实例为种子的InnoDB集群:

 MySQL  localhost:3310  JS > var cluster = dba.createCluster('testCluster')
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 on instance '127.0.0.1:3310'.

Validating instance configuration at localhost:3310...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3310

Instance configuration is suitable.
NOTE: Group Replication will communicate with other members using '127.0.0.1:33101'. Use the localAddress option to override.

* Checking connectivity and SSL configuration...

WARNING: Instance '127.0.0.1:3310' cannot persist Group Replication 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.
Creating InnoDB Cluster 'testCluster' on '127.0.0.1:3310'...

Adding Seed Instance...
Cluster successfully created. Use Cluster.addInstance() to add MySQL instances.
At least 3 instances are needed for the cluster to be able to withstand up to
one server failure.

 MySQL  localhost:3310  JS >

createCluster()方法将InnoDB集群元数据部署到选中的实例上,并添加当前连接的实例作为种子实例。createCluster()方法返回创建的簇 ,在上面的例子中,this被赋值给cluster变量。传递给createCluster()方法的参数是这个InnoDB集群的符号名称,在本例中是testCluster 。

向InnoDB集群添加实例
下一步是向InnoDB集群添加更多的实例。在添加种子实例时,每个辅助实例都会重新执行由种子实例执行的任何事务。本教程使用之前在端口 3320和3330上创建的沙盒实例。

这个例子中的seed实例是最近创建的,所以它几乎是空的。因此,几乎没有数据需要从种子实例复制到辅助实例。在生产环境中,如果在seed实 例上有一个现有的数据库,可以使用MySQL Enterprise Backup之类的工具,在复制开始之前确保从服务器有匹配的数据。这避免了数据从主服 务器复制到辅助服务器时可能出现的长时间延迟。

添加第二个实例到InnoDB集群:

 MySQL  localhost:3310  JS > cluster.addInstance('root@localhost:3320')
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell

NOTE: The target instance '127.0.0.1:3320' has not been pre-provisioned (GTID set is empty). The Shell is unable to decide  whether incremental state recovery can correctly provision it.
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely  overwrite the state of '127.0.0.1:3320' with a physical snapshot from an existing cluster member. To use this method by  default, set the 'recoveryMethod' option to 'clone'.

The incremental state recovery may be safely used if you are sure all updates ever executed in the cluster were done with  GTIDs enabled, there are no purged transactions and the new instance contains the same GTID set as the cluster or a subset of  it. To use this method by default, set the 'recoveryMethod' option to 'incremental'.


Please select a recovery method [I]ncremental recovery/[A]bort (default Incremental recovery):
Validating instance configuration at localhost:3320...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3320

Instance configuration is suitable.
NOTE: Group Replication will communicate with other members using '127.0.0.1:33201'. Use the localAddress option to override.

* Checking connectivity and SSL configuration...
A new instance will be added to the InnoDB Cluster. Depending on the amount of
data on the cluster this might take from a few seconds to several hours.

WARNING: Instance '127.0.0.1:3320' cannot persist Group Replication 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.
Adding instance to the cluster...

Monitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.
Incremental state recovery is now in progress.

* Waiting for distributed recovery to finish...
NOTE: '127.0.0.1:3320' is being recovered from '127.0.0.1:3310'
* Distributed recovery has finished

WARNING: Instance '127.0.0.1:3310' 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.
The instance '127.0.0.1:3320' was successfully added to the cluster.

记住,如果不禁用ssl,在向集群添加实例时总是会报错,比如:

 MySQL  localhost:3310  JS > cluster.addInstance('root@localhost:3320', {memberSslMode: 'DISABLED'})
WARNING: Option 'memberSslMode' is deprecated for this operation and it will be removed in a future release. This option is  not needed because the SSL mode is automatically obtained from the cluster. Please do not use it here.

WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell

NOTE: The target instance '127.0.0.1:3320' has not been pre-provisioned (GTID set is empty). The Shell is unable to decide  whether incremental state recovery can correctly provision it.
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely  overwrite the state of '127.0.0.1:3320' with a physical snapshot from an existing cluster member. To use this method by  default, set the 'recoveryMethod' option to 'clone'.

The incremental state recovery may be safely used if you are sure all updates ever executed in the cluster were done with  GTIDs enabled, there are no purged transactions and the new instance contains the same GTID set as the cluster or a subset of  it. To use this method by default, set the 'recoveryMethod' option to 'incremental'.


Please select a recovery method [I]ncremental recovery/[A]bort (default Incremental recovery): I
Validating instance configuration at localhost:3320...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3320

Instance configuration is suitable.
ERROR: RuntimeError: The cluster has TLS (encryption) enabled. To add the instance '127.0.0.1:3320' to the cluster either  disable TLS on the cluster, remove the memberSslMode option or use it with any of 'AUTO', 'REQUIRED', 'VERIFY_CA' or  'VERIFY_IDENTITY'.
Cluster.addInstance: The cluster has TLS (encryption) enabled. To add the instance '127.0.0.1:3320' to the cluster either  disable TLS on the cluster, remove the memberSslMode option or use it with any of 'AUTO', 'REQUIRED', 'VERIFY_CA' or  'VERIFY_IDENTITY'. (RuntimeError)

那怕你使用cluster.addInstance(‘root@localhost:3320’, {memberSslMode: ‘DISABLED’})命令,通过{memberSslMode: ‘DISABLED’}选项来禁 用ssl都不会起作用。

添加第三个实例:

 MySQL  localhost:3310  JS > cluster.addInstance('root@localhost:3330')
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell

NOTE: The target instance '127.0.0.1:3330' has not been pre-provisioned (GTID set is empty). The Shell is unable to decide  whether incremental state recovery can correctly provision it.
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely  overwrite the state of '127.0.0.1:3330' with a physical snapshot from an existing cluster member. To use this method by  default, set the 'recoveryMethod' option to 'clone'.

The incremental state recovery may be safely used if you are sure all updates ever executed in the cluster were done with  GTIDs enabled, there are no purged transactions and the new instance contains the same GTID set as the cluster or a subset of  it. To use this method by default, set the 'recoveryMethod' option to 'incremental'.


Please select a recovery method [I]ncremental recovery/[A]bort (default Incremental recovery):
Validating instance configuration at localhost:3330...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3330

Instance configuration is suitable.
NOTE: Group Replication will communicate with other members using '127.0.0.1:33301'. Use the localAddress option to override.

* Checking connectivity and SSL configuration...
A new instance will be added to the InnoDB Cluster. Depending on the amount of
data on the cluster this might take from a few seconds to several hours.

WARNING: Instance '127.0.0.1:3330' cannot persist Group Replication 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.
Adding instance to the cluster...

Monitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.
State recovery already finished for '127.0.0.1:3330'

WARNING: Instance '127.0.0.1:3310' 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 '127.0.0.1:3320' 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.
The instance '127.0.0.1:3330' was successfully added to the cluster.

至此,您已经创建了一个包含三个实例的集群:一个主实例和两个从实例。

只有当实例是沙盒实例时,才能在addInstance()中指定localhost。这一点同样适用于执行createCluster()函数后的addInstance()函数 。

持久化配置
一旦沙盒实例被添加到集群中,InnoDB集群所需的配置必须持久化到每个实例的选项文件中。连接到每个实例并发出 dba.configureLocalInstance(instance)。

 MySQL  JS > \connect root@localhost:3310
Creating a session to 'root@localhost:3310'
Please provide the password for 'root@localhost:3310': ******
Save password for 'root@localhost:3310'? [Y]es/[N]o/Ne[v]er (default No):
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 43
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  localhost:3310  JS >

执行dba.configureLocalInstance(instance):

 MySQL  localhost:3310  JS > dba.configureLocalInstance('root@localhost:3310')
WARNING: This function is deprecated and will be removed in a future release of MySQL Shell, use dba.configureInstance()  instead.
Please provide the password for 'root@localhost:3310': ******
Save password for 'root@localhost:3310'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
The instance '127.0.0.1:3310' belongs to an InnoDB cluster.
Sandbox MySQL configuration file at: /root/mysql-sandboxes/3310/my.cnf
Persisting the cluster settings...
The instance '127.0.0.1:3310' was configured for use in an InnoDB cluster.

The instance cluster settings were successfully persisted.

如果连接到实例时没有发出dba.configureLocalInstance(),则配置不会持久化到选项文件中。这并不会阻止实例最初加入集群,例如在停止后 ,但它确实意味着实例不能自动重新加入集群。

重复连接到集群中添加的每个沙盒实例并持久化配置的过程。在本例中,我们在3310、3320和3330端口添加了沙盒实例。因此,对端口3320和 3330执行以下命令:

 MySQL  localhost:3310  JS > \disconnect
 MySQL  JS > \connect root@localhost:3320
Creating a session to 'root@localhost:3320'
Please provide the password for 'root@localhost:3320': ******
Save password for 'root@localhost:3320'? [Y]es/[N]o/Ne[v]er (default No):
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 36
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  localhost:3320  JS > dba.configureLocalInstance('root@localhost:3320')
WARNING: This function is deprecated and will be removed in a future release of MySQL Shell, use dba.configureInstance()  instead.
Please provide the password for 'root@localhost:3320': ******
Save password for 'root@localhost:3320'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
The instance '127.0.0.1:3320' belongs to an InnoDB cluster.
Sandbox MySQL configuration file at: /root/mysql-sandboxes/3320/my.cnf
Persisting the cluster settings...
The instance '127.0.0.1:3320' was configured for use in an InnoDB cluster.

The instance cluster settings were successfully persisted.
 MySQL  localhost:3320  JS > \disconnect


 MySQL  JS > \connect root@localhost:3330
Creating a session to 'root@localhost:3330'
Please provide the password for 'root@localhost:3330': ******
Save password for 'root@localhost:3330'? [Y]es/[N]o/Ne[v]er (default No):
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 25
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  localhost:3330  JS > dba.configureLocalInstance('root@localhost:3330')
WARNING: This function is deprecated and will be removed in a future release of MySQL Shell, use dba.configureInstance()  instead.
Please provide the password for 'root@localhost:3330': ******
Save password for 'root@localhost:3330'? [Y]es/[N]o/Ne[v]er (default No):
WARNING: Support for AdminAPI operations in MySQL version 5.7 is deprecated and will be removed in a future release of MySQL  Shell
The instance '127.0.0.1:3330' belongs to an InnoDB cluster.
Sandbox MySQL configuration file at: /root/mysql-sandboxes/3330/my.cnf
Persisting the cluster settings...
The instance '127.0.0.1:3330' was configured for use in an InnoDB cluster.

The instance cluster settings were successfully persisted.

要检查集群是否已创建,请使用集群实例的status()函数。

 MySQL  localhost:3330  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": "testCluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "127.0.0.1:3310",
        "ssl": "DISABLED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "127.0.0.1:3310": {
                "address": "127.0.0.1:3310",
                "memberRole": "PRIMARY",
                "mode": "R/W",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            },
            "127.0.0.1:3320": {
                "address": "127.0.0.1:3320",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            },
            "127.0.0.1:3330": {
                "address": "127.0.0.1:3330",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE",
                "version": "5.7.26"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "127.0.0.1:3310"
}

下面来测试一个集群的同步功能
在主库上创建jycs库并创建一个test表

 MySQL  JS > \connect root@localhost:3310
Creating a session to 'root@localhost:3310'
Please provide the password for 'root@localhost:3310': ******
Save password for 'root@localhost:3310'? [Y]es/[N]o/Ne[v]er (default No):
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 47
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  localhost:3310  JS > \sql
Switching to SQL mode... Commands end with ;
Fetching global names for auto-completion... Press ^C to stop.
 MySQL  localhost:3310  SQL > show databases;
+-------------------------------+
| Database                      |
+-------------------------------+
| information_schema            |
| mysql                         |
| mysql_innodb_cluster_metadata |
| performance_schema            |
| sys                           |
+-------------------------------+
5 rows in set (0.0009 sec)
 MySQL  localhost:3310  SQL > create database jycs;
Query OK, 1 row affected (0.0038 sec)
 MySQL  localhost:3310  SQL > show databases;
+-------------------------------+
| Database                      |
+-------------------------------+
| information_schema            |
| jycs                          |
| mysql                         |
| mysql_innodb_cluster_metadata |
| performance_schema            |
| sys                           |
+-------------------------------+
6 rows in set (0.0009 sec)
 MySQL  localhost:3310  SQL > use jycs
Default schema set to `jycs`.
Fetching global names, object names from `jycs` for auto-completion... Press ^C to stop.
 MySQL  localhost:3310  jycs  SQL >  create table test(id int(20),name varchar(50));
Query OK, 0 rows affected (0.0150 sec)
 MySQL  localhost:3310  jycs  SQL > show tables;
+----------------+
| Tables_in_jycs |
+----------------+
| test           |
+----------------+
1 row in set (0.0009 sec)
;
 MySQL  localhost:3310  jycs  SQL > insert into test values(1,'jy');
ERROR: 3098 (HY000): The table does not comply with the requirements by an external plugin.

上面报错是因为MySQL Group Replication (MGR) 等插件要求所有表必须包含主键(Primary Key),若表未定义主键,执行 DML 操作时会触发 此错误。

下面修改test表将id列作为主键。

 MySQL  localhost:3310  jycs  SQL > ALTER TABLE test MODIFY COLUMN id INT PRIMARY KEY;
Query OK, 0 rows affected (0.0255 sec)

Records: 0  Duplicates: 0  Warnings: 0
 MySQL  localhost:3310  jycs  SQL > insert into test values(1,'jy');
Query OK, 1 row affected (0.0048 sec)

 MySQL  localhost:3310  jycs  SQL > \js
Switching to JavaScript mode...
 MySQL  localhost:3310  jycs  JS > \disconnect

登录第二个实例,查看jycs库与test表是否存在

 MySQL  JS > \connect root@localhost:3320
Creating a session to 'root@localhost:3320'
Please provide the password for 'root@localhost:3320': ******
Save password for 'root@localhost:3320'? [Y]es/[N]o/Ne[v]er (default No):
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 40
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  localhost:3320  JS > \sql
Switching to SQL mode... Commands end with ;
 MySQL  localhost:3320  SQL > show databases;
+-------------------------------+
| Database                      |
+-------------------------------+
| information_schema            |
| jycs                          |
| mysql                         |
| mysql_innodb_cluster_metadata |
| performance_schema            |
| sys                           |
+-------------------------------+
6 rows in set (0.0008 sec)
 MySQL  localhost:3320  SQL > use jycs
Default schema set to `jycs`.
Fetching global names, object names from `jycs` for auto-completion... Press ^C to stop.
 MySQL  localhost:3320  jycs  SQL > show tables
                                 -> ;
+----------------+
| Tables_in_jycs |
+----------------+
| test           |
+----------------+
1 row in set (0.0006 sec)

 MySQL  localhost:3320  jycs  SQL > select * from test;
+----+------+
| id | name |
+----+------+
|  1 | jy   |
+----+------+
1 row in set (0.0012 sec)


 MySQL  localhost:3320  jycs  SQL > \js
Switching to JavaScript mode...
 MySQL  localhost:3320  jycs  JS > \disconnect

登录第三个实例,查看jycs库与test表是否存在

 MySQL  JS > \connect root@localhost:3330
Creating a session to 'root@localhost:3330'
Please provide the password for 'root@localhost:3330': ******
Save password for 'root@localhost:3330'? [Y]es/[N]o/Ne[v]er (default No):
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 29
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  localhost:3330  JS > \sql
Switching to SQL mode... Commands end with ;
 MySQL  localhost:3330  SQL > show databases
                           -> ;
+-------------------------------+
| Database                      |
+-------------------------------+
| information_schema            |
| jycs                          |
| mysql                         |
| mysql_innodb_cluster_metadata |
| performance_schema            |
| sys                           |
+-------------------------------+
6 rows in set (0.0009 sec)
 MySQL  localhost:3330  SQL > use jycs
Default schema set to `jycs`.
Fetching global names, object names from `jycs` for auto-completion... Press ^C to stop.
 MySQL  localhost:3330  jycs  SQL > show tables;
+----------------+
| Tables_in_jycs |
+----------------+
| test           |
+----------------+
1 row in set (0.0007 sec)
 MySQL  localhost:3330  jycs  SQL > select * from test;
+----+------+
| id | name |
+----+------+
|  1 | jy   |
+----+------+
1 row in set (0.0013 sec)

 MySQL  localhost:3330  jycs  SQL > \js
Switching to JavaScript mode...
 MySQL  localhost:3330  jycs  JS > \disconnect
 MySQL  JS >

至此使用MySQL Shell部署沙箱InnoDB集群完成。

Linux下安装MySQL Router

Linux下安装MySQL Router
MySQL路由器的二进制发行版可用于多个Linux变体,包括Fedora、Oracle Linux、Red Hat和Ubuntu。

安装选项包括:
.官方MySQL Yum或APT存储库软件包:这些二进制文件是由MySQL发布团队构建的。有关安装这些工具的其他信息,请参阅使用Yum或APT安装它们 的快速指南。

.下载MySQL官方软件包:下载地址是https://dev.mysql.com/downloads/router。使用你喜欢的包管理器下载和安装。另外,在MySQL Router 8.0.13版本中,MySQL Router包含在MySQL Server的源代码和单体二进制包中。

.下载源代码并自己编译:源代码是MySQL服务器的一部分,网址是https://dev.mysql.com/downloads/mysql。或者,源代码也可以在GitHub上 获得(特别是在router目录中)。有关编译MySQL路由器的信息,请参见从源代码安装MySQL路由器。

在Linux上安装的过程取决于您的Linux发行版。

使用官方的DEB或RPM包安装MySQL Router会在MySQL Router默认运行的主机上创建一个名为mysqlrouter的本地系统用户和组。有关更多信息, 请参见系统用户的配置选项。

安装DEB包
在Ubuntu和其他使用Debian软件包方案的系统上,您可以下载并安装.deb软件包,也可以使用APT软件包管理器。

使用APT包管理器
1.请参考MySQL APT库文档安装MySQL APT库。例如:
从这里下载APT配置包。https://dev.mysql.com/downloads/repo/apt/

$> sudo dpkg -i mysql-apt-config_0.8.30-1_all.deb

请选择需要安装的MySQL Server系列,例如MySQL Server 8.0。这个选项还决定了从MySQL存储库中安装的MySQL路由器版本。

2.更新APT存储库:

$> sudo apt-get update

3.安装MySQL路由器。例如:

sudo apt-get install mysql-router-community

手动安装软件包
您也可以下载.deb包并从命令行安装它,类似于

$> sudo dpkg -i package.deb

package.deb是MySQL路由器包的名称;例如:MySQL – Router -community-version-1ubuntu24.04_amd64.deb,其中version表示MySQL路由器的 版本号。

安装RPM包
在基于RPM的系统上,您可以下载并安装RPM包,也可以使用Yum包管理器。
.首先,按照MySQL Yum repository文档中的描述安装MySQL Yum repository。例如:从这里下载Yum配置包。https://dev.mysql.com/downloads/repo/yum/

$> sudo rpm -Uvh mysql84-community-release-el7-1.noarch.rpm

.接下来,可选择更改active MySQL Server版本,默认为MySQL 8.4 LTS。例如,将8.4版本修改为8.0,用于MySQL Server (MySQL)和MySQL Router (MySQL -tools的一部分)子仓库:

$> sudo yum-config-manager --disable mysql-8.4-lts-community
$> sudo yum-config-manager --enable  mysql80-community

$> sudo yum-config-manager --disable mysql-tools-8.4-lts-community
$> sudo yum-config-manager --enable  mysql-tools-community

.接下来,安装MySQL Router。例如:

$> sudo yum install mysql-router-community

手动安装RPM包

$> sudo rpm -i package.rpm

package.rpm是MySQL路由器包的名称;例如:mysql-router-community-version-el7.x86_64。其中version是MySQL路由器的版本号。

[root@mysqlcs soft]# rpm -ivh mysql-router-community-8.0.41-1.el7.x86_64.rpm
warning: mysql-router-community-8.0.41-1.el7.x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID a8d3785c: NOKEY
Preparing...                          ################################# [100%]
Updating / installing...
   1:mysql-router-community-8.0.41-1.e################################# [100%]
[root@mysqlcs soft]# id mysqlrouter
uid=987(mysqlrouter) gid=982(mysqlrouter) groups=982(mysqlrouter)

卸载
在Linux上卸载MySQL Router的过程取决于您使用的软件包。

卸载DEB包
要卸载Debian软件包,使用以下命令:

$> sudo dpkg -r mysql-router

该命令不删除配置文件。要同时删除它们和data目录,可以使用:

$> sudo dpkg --purge mysql-router

或者,使用apt-get remove mysql-router或apt-get purge mysql-router。

卸载RPM包
要卸载RPM包,使用以下命令:

$> sudo rpm -e mysql-router-community

类似地,也可以使用yum remove mysql-router-community。

该命令不会删除配置文件。

没有删除的内容
当不清除时,卸载过程不会删除配置文件。在Debian系统上,可能包含如下文件:

/etc/init.d/mysqlrouter
/etc/mysqlrouter/mysqlrouter.conf
/etc/apparmor.d/usr.sbin.mysqlrouter

MySQL Shell for Python来对关系表进行操作

MySQL Shell for Python来对关系表进行操作
MySQL Shell不仅可以操作JSON文档,还可以操作关系表。在MySQL中,每个关系表都与特定的存储引擎相关联。本节中的例子使用world_x数据库中的InnoDB表。

确认模式
要显示分配给模式变量的值,请输入db。

 MySQL  localhost:33060+  world_x  Py > db

如果schema值不是schema:world_x数据库,则设置db变量如下:

mysql-py> \use world_x

显示所有表
要显示world_x数据库中的所有关系表,可以在schema对象上使用get_tables()方法。

 MySQL  localhost:33060+  world_x  Py > db.get_tables()
[
    ,
    ,
    
]

基本表操作
表的基本操作包括:
db.name.insert():insert()方法将一条或多条记录插入到指定表中。
db.name.select():select()方法返回指定表中的部分或全部记录。
db.name.update():update()方法更新指定表中的记录。
db.name.delete():delete()方法从指定的表中删除一条或多条记录。

向表中插入记录
可以结合values()方法使用insert()方法将记录插入到现有的关系表中。insert()方法接受单个列或表中的所有列作为参数。使用一个或 多个values()方法指定要插入的值。

插入完整记录
要插入完整的记录,向insert()方法传递表中的所有列。然后向values()方法传递每一列的一个值。例如,要向world_x数据库中的city表 中添加一条新记录,插入下面的记录并按两次Enter键。

 MySQL  localhost:33060+  world_x  Py > db.city.insert("ID", "Name", "CountryCode", "District", "Info").values(None,  "Olympia", "USA", "Washington", '{"Population": 5000}')
Query OK, 1 item affected (0.0081 sec)

city表有5列:ID、Name、CountryCode、District和Info。每个值必须与它表示的列的数据类型匹配。

插入部分记录
下面的示例将值插入city表的ID、Name和CountryCode列。

 MySQL  localhost:33060+  world_x  Py > db.city.insert("ID", "Name", "CountryCode").values(None, "Little Falls",  "USA").values(None, "Happy Valley", "USA")
Query OK, 2 items affected (0.0055 sec)

Records: 2  Duplicates: 0  Warnings: 0

使用insert()方法指定列时,值的数量必须与列的数量匹配。在前面的例子中,必须提供三个值来匹配指定的三列。

查询表记录
你可以使用select()方法从数据库的表中查询并返回记录。X DevAPI提供了与select()方法一起使用的其他方法,用于过滤和排序返回的记 录。

MySQL提供了以下操作符来指定搜索条件:OR (||), AND (&&), XOR, IS, NOT,BETWEEN, IN, LIKE, !=, <>, >, >=, < , <=, &, |, <<, >>, +, -, *, /, ~, 和 %。

查询所有记录
要查询已存在表中的所有记录,只需使用select()方法,而无需指定搜索条件。下面的示例从world_x数据库中的city表中选择所有记录。

 MySQL  localhost:33060+  world_x  Py > db.city.select()
+----+----------------+-------------+----------+------------------------+
| ID | Name           | CountryCode | District | Info                   |
+----+----------------+-------------+----------+------------------------+
|  2 | Qandahar       | AFG         | Qandahar | {"Population": 237500} |
|  3 | Herat          | AFG         | Herat    | {"Population": 186800} |
|  4 | Mazar-e-Sharif | AFG         | Balkh    | {"Population": 127800} |
...........
| 4078 | Nablus                         | PSE         | Nablus               | {"Population": 100231}  |
| 4079 | Rafah                          | PSE         | Rafah                | {"Population": 92020}   |
| 4089 | Little Falls                   | USA         |                      | NULL                    |
| 4096 | Happy Valley                   | USA         |                      | NULL                    |
| 4103 | San Francisco                  | USA         | California           | {"Population": 830000}  |
| 4124 | Olympia                        | USA         | Washington           | {"Population": 5000}    |
| 4131 | Little Falls                   | USA         |                      | NULL                    |
| 4138 | Happy Valley                   | USA         |                      | NULL                    |
+------+--------------------------------+-------------+----------------------+-------------------------+
4083 rows in set (0.0056 sec)

过滤搜索
要执行一个返回一组表列的查询,可以使用select()方法,并在方括号中指定要返回的列。这个查询返回city表中的Name和CountryCode列。

 MySQL  localhost:33060+  world_x  Py > db.city.select(["Name", "CountryCode"])
+--------------------------------+-------------+
| Name                           | CountryCode |
+--------------------------------+-------------+
| Qandahar                       | AFG         |
| Herat                          | AFG         |
| Mazar-e-Sharif                 | AFG         |
| Little Falls                   | USA         |
| Happy Valley                   | USA         |
| San Francisco                  | USA         |
.............
| Olympia                        | USA         |
| Little Falls                   | USA         |
| Happy Valley                   | USA         |
+--------------------------------+-------------+
4083 rows in set (0.0019 sec)

要查询返回符合特定搜索条件的行,可以使用where()方法来包含这些条件。例如,下面的示例返回以字母Z开头的城市的名称和国家代码。

 MySQL  localhost:33060+  world_x  Py > db.city.select(["Name", "CountryCode"]).where("Name like 'Z%'")
+-----------------+-------------+
| Name            | CountryCode |
+-----------------+-------------+
| Zaanstad        | NLD         |
| Zoetermeer      | NLD         |
| Zwolle          | NLD         |
| Zenica          | BIH         |
| Zagazig         | EGY         |
| Zaragoza        | ESP         |
| Zamboanga       | PHL         |
| Zahedan         | IRN         |
| Zanjan          | IRN         |
| Zabol           | IRN         |
| Zama            | JPN         |
| Zhezqazghan     | KAZ         |
| Zhengzhou       | CHN         |
| Zibo            | CHN         |
| Zhangjiakou     | CHN         |
| Zhuzhou         | CHN         |
| Zhangjiang      | CHN         |
| Zigong          | CHN         |
| Zaozhuang       | CHN         |
| Zhenjiang       | CHN         |
| Zhongshan       | CHN         |
| Zunyi           | CHN         |
| Zhaoqing        | CHN         |
| Zhangzhou       | CHN         |
| Zhaodong        | CHN         |
| Zhuhai          | CHN         |
| Zaoyang         | CHN         |
| Zhoushan        | CHN         |
| Zhoukou         | CHN         |
| Zalantun        | CHN         |
| Zhumadian       | CHN         |
| Zixing          | CHN         |
| Zhucheng        | CHN         |
| Zhangjiagang    | CHN         |
| Zagreb          | HRV         |
| Zapopan         | MEX         |
| Zamora          | MEX         |
| Zitácuaro       | MEX         |
| Zacatecas       | MEX         |
| Zinacantepec    | MEX         |
| Zumpango        | MEX         |
| Zinder          | NER         |
| Zaria           | NGA         |
| Zabrze          | POL         |
| Zielona Góra    | POL         |
| Zwickau         | DEU         |
| Ziguinchor      | SEN         |
| Zürich          | CHE         |
| Zanzibar        | TZA         |
| Zonguldak       | TUR         |
| Zaporizzja      | UKR         |
| Zytomyr         | UKR         |
| Zelenograd      | RUS         |
| Zlatoust        | RUS         |
| Zelenodolsk     | RUS         |
| Zeleznodoroznyi | RUS         |
| Zeleznogorsk    | RUS         |
| Zukovski        | RUS         |
| Zeleznogorsk    | RUS         |
+-----------------+-------------+
59 rows in set (0.0050 sec)

可以使用bind()方法将值与搜索条件分开。例如,不使用“Name = ‘Z%’ ”作为条件,而是使用冒号和以字母开头的名称组成的命名占位符, 例如Name。然后在bind()方法中包含占位符和值,如下所示:

 MySQL  localhost:33060+  world_x  Py > db.city.select(["Name", "CountryCode"]).where("Name like :name").bind("name", "Z%")
+-----------------+-------------+
| Name            | CountryCode |
+-----------------+-------------+
| Zaanstad        | NLD         |
| Zoetermeer      | NLD         |
| Zwolle          | NLD         |
| Zenica          | BIH         |
| Zagazig         | EGY         |
| Zaragoza        | ESP         |
| Zamboanga       | PHL         |
| Zahedan         | IRN         |
| Zanjan          | IRN         |
| Zabol           | IRN         |
| Zama            | JPN         |
| Zhezqazghan     | KAZ         |
| Zhengzhou       | CHN         |
| Zibo            | CHN         |
| Zhangjiakou     | CHN         |
| Zhuzhou         | CHN         |
| Zhangjiang      | CHN         |
| Zigong          | CHN         |
| Zaozhuang       | CHN         |
| Zhenjiang       | CHN         |
| Zhongshan       | CHN         |
| Zunyi           | CHN         |
| Zhaoqing        | CHN         |
| Zhangzhou       | CHN         |
| Zhaodong        | CHN         |
| Zhuhai          | CHN         |
| Zaoyang         | CHN         |
| Zhoushan        | CHN         |
| Zhoukou         | CHN         |
| Zalantun        | CHN         |
| Zhumadian       | CHN         |
| Zixing          | CHN         |
| Zhucheng        | CHN         |
| Zhangjiagang    | CHN         |
| Zagreb          | HRV         |
| Zapopan         | MEX         |
| Zamora          | MEX         |
| Zitácuaro       | MEX         |
| Zacatecas       | MEX         |
| Zinacantepec    | MEX         |
| Zumpango        | MEX         |
| Zinder          | NER         |
| Zaria           | NGA         |
| Zabrze          | POL         |
| Zielona Góra    | POL         |
| Zwickau         | DEU         |
| Ziguinchor      | SEN         |
| Zürich          | CHE         |
| Zanzibar        | TZA         |
| Zonguldak       | TUR         |
| Zaporizzja      | UKR         |
| Zytomyr         | UKR         |
| Zelenograd      | RUS         |
| Zlatoust        | RUS         |
| Zelenodolsk     | RUS         |
| Zeleznodoroznyi | RUS         |
| Zeleznogorsk    | RUS         |
| Zukovski        | RUS         |
| Zeleznogorsk    | RUS         |
+-----------------+-------------+
59 rows in set (0.0042 sec)

在程序中,绑定使您能够在表达式中指定占位符,这些占位符在执行之前被填充值,并且可以根据需要从自动转义中获益。

始终使用绑定来清理输入。使用字符串连接避免在查询中引入值,这会产生无效的输入,在某些情况下,可能会导致安全问题。

要使用AND操作符进行查询,在where()方法的搜索条件之间添加操作符。

 MySQL  localhost:33060+  world_x  Py > db.city.select(["Name", "CountryCode"]).where("Name like 'Z%' and CountryCode =  'CHN'")
+--------------+-------------+
| Name         | CountryCode |
+--------------+-------------+
| Zhengzhou    | CHN         |
| Zibo         | CHN         |
| Zhangjiakou  | CHN         |
| Zhuzhou      | CHN         |
| Zhangjiang   | CHN         |
| Zigong       | CHN         |
| Zaozhuang    | CHN         |
| Zhenjiang    | CHN         |
| Zhongshan    | CHN         |
| Zunyi        | CHN         |
| Zhaoqing     | CHN         |
| Zhangzhou    | CHN         |
| Zhaodong     | CHN         |
| Zhuhai       | CHN         |
| Zaoyang      | CHN         |
| Zhoushan     | CHN         |
| Zhoukou      | CHN         |
| Zalantun     | CHN         |
| Zhumadian    | CHN         |
| Zixing       | CHN         |
| Zhucheng     | CHN         |
| Zhangjiagang | CHN         |
+--------------+-------------+
22 rows in set (0.0044 sec)

要指定多个条件运算符,可以将搜索条件放在括号中以更改运算符的优先级。下面的例子演示了AND和OR操作符的位置。

 MySQL  localhost:33060+  world_x  Py > db.city.select(["Name", "CountryCode"]).where("Name like 'Z%' and (CountryCode = 'CHN'  or CountryCode = 'RUS')")
+-----------------+-------------+
| Name            | CountryCode |
+-----------------+-------------+
| Zhengzhou       | CHN         |
| Zibo            | CHN         |
| Zhangjiakou     | CHN         |
| Zhuzhou         | CHN         |
| Zhangjiang      | CHN         |
| Zigong          | CHN         |
| Zaozhuang       | CHN         |
| Zhenjiang       | CHN         |
| Zhongshan       | CHN         |
| Zunyi           | CHN         |
| Zhaoqing        | CHN         |
| Zhangzhou       | CHN         |
| Zhaodong        | CHN         |
| Zhuhai          | CHN         |
| Zaoyang         | CHN         |
| Zhoushan        | CHN         |
| Zhoukou         | CHN         |
| Zalantun        | CHN         |
| Zhumadian       | CHN         |
| Zixing          | CHN         |
| Zhucheng        | CHN         |
| Zhangjiagang    | CHN         |
| Zelenograd      | RUS         |
| Zlatoust        | RUS         |
| Zelenodolsk     | RUS         |
| Zeleznodoroznyi | RUS         |
| Zeleznogorsk    | RUS         |
| Zukovski        | RUS         |
| Zeleznogorsk    | RUS         |
+-----------------+-------------+
29 rows in set (0.0042 sec)

限制、排序和偏移结果
可以应用limit()、order_by()和offset()方法来管理select()方法返回的记录的数量和顺序。

要指定结果集中包含的记录数,可以在limit()方法后面添加一个值给select()方法。例如,下面的查询返回country表中的前5条记录。

 MySQL  localhost:33060+  world_x  Py > db.country.select(["Code", "Name"]).limit(5)
+------+-------------+
| Code | Name        |
+------+-------------+
| ABW  | Aruba       |
| AFG  | Afghanistan |
| AGO  | Angola      |
| AIA  | Anguilla    |
| ALB  | Albania     |
+------+-------------+
5 rows in set (0.0029 sec)

要指定结果的顺序,请将order_by()方法添加到select()方法后面。向order_by()方法传递一个列表,其中包含一个或多个用于排序的列 ,还可以根据需要传递降序(desc)或升序(asc)属性。升序是默认的排序类型。

例如,下面的查询按Name列对所有记录进行排序,然后按降序返回前三条记录。

 MySQL  localhost:33060+  world_x  Py > db.country.select(["Code", "Name"]).order_by(["Name desc"]).limit(3)
+------+------------+
| Code | Name       |
+------+------------+
| ZWE  | Zimbabwe   |
| ZMB  | Zambia     |
| YUG  | Yugoslavia |
+------+------------+
3 rows in set (0.0017 sec)

默认情况下,limit()方法从表中的第一条记录开始。可以使用offset()方法修改起始记录。例如,要忽略第一条记录并返回符合条件的后 三条记录,可以向offset()方法传递一个值1。

 MySQL  localhost:33060+  world_x  Py > db.country.select(["Code", "Name"]).order_by(["Name desc"]).limit(3).offset(1)
+------+------------+
| Code | Name       |
+------+------------+
| ZMB  | Zambia     |
| YUG  | Yugoslavia |
| YEM  | Yemen      |
+------+------------+
3 rows in set (0.0015 sec)

更新表记录
可以使用update()方法修改表中的一条或多条记录。update()方法的工作原理是过滤一个查询,只包含需要更新的记录,然后对这些记录应 用指定的操作。

要替换city表中的城市名,向set()方法传递新的城市名。然后,向where()方法传递要定位和替换的城市名。下面的例子将北京这个城市替 换为北京。

 MySQL  localhost:33060+  world_x  Py > db.city.update().set("Name", "Beijing").where("Name = 'Peking'")
Query OK, 1 items affected (0.0093 sec)

Rows matched: 1  Changed: 1  Warnings: 0

使用select()方法验证更改。

 MySQL  localhost:33060+  world_x  Py > db.city.select(["ID", "Name", "CountryCode", "District", "Info"]).where("Name =  'Beijing'")
+------+---------+-------------+----------+-------------------------+
| ID   | Name    | CountryCode | District | Info                    |
+------+---------+-------------+----------+-------------------------+
| 1891 | Beijing | CHN         | Peking   | {"Population": 7472000} |
+------+---------+-------------+----------+-------------------------+
1 row in set (0.0072 sec)

删除表记录
你可以使用delete()方法从数据库的一张表中删除部分或全部记录。X DevAPI提供了额外的方法与delete()方法一起使用,用于过滤和排序 要删除的记录。

使用条件删除记录
下面的例子将搜索条件传递给delete()方法。所有符合条件的记录都将从city表中删除。在这个例子中,只有一条记录符合条件。
MySQL localhost:33060+ world_x Py > db.city.delete().where(“Name = ‘Olympia'”)
Query OK, 1 item affected (0.0146 sec)

删除第一条记录
要删除city表中的第一条记录,可以使用limit()方法将值设为1。
MySQL localhost:33060+ world_x Py > db.city.delete().limit(1)
Query OK, 1 item affected (0.0043 sec)

删除表中的所有记录
可以删除表中的所有记录。为此,可以使用delete()方法,但不指定搜索条件。
MySQL localhost:33060+ world_x Py > db.city.delete()
Query OK, 4080 item affected (0.0043 sec)

表中的文档
在MySQL中,表可以包含传统的关系型数据、JSON值,或者两者都包含。你可以把传统数据和JSON文档结合起来,把文档存储在原生JSON数据类 型的列中。

本示例使用world_x数据库中的city表。

city表描述
city表有五个列(或字段)。
mysql> desc city;
+————-+———-+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+————-+———-+——+—–+———+—————-+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| Name | char(35) | NO | | | |
| CountryCode | char(3) | NO | | | |
| District | char(20) | NO | | | |
| Info | json | YES | | NULL | |
+————-+———-+——+—–+———+—————-+
5 rows in set (0.01 sec)

插入记录
要向表的列中插入一个文档,只需按正确的顺序向values()方法传递一个格式良好的JSON文档。在下面的示例中,文档作为要插入Info列的最 终值被传递。
MySQL localhost:33060+ world_x Py > db.city.insert().values(None, “San Francisco”, “USA”, “California”, ‘{“Population”:830000}’)
Query OK, 1 item affected (0.0093 sec)

查询记录
你可以使用搜索条件进行查询,计算表达式中的文档值。

MySQL localhost:33060+ world_x Py > db.city.select([“ID”, “Name”, “CountryCode”, “District”, “Info”]).\
-> where(“CountryCode = :country and Info->’$.Population’ > 1000000”).\
-> bind(‘country’, ‘USA’)
->
+——+————–+————-+————–+————————-+
| ID | Name | CountryCode | District | Info |
+——+————–+————-+————–+————————-+
| 3793 | New York | USA | New York | {“Population”: 8008278} |
| 3794 | Los Angeles | USA | California | {“Population”: 3694820} |
| 3795 | Chicago | USA | Illinois | {“Population”: 2896016} |
| 3796 | Houston | USA | Texas | {“Population”: 1953631} |
| 3797 | Philadelphia | USA | Pennsylvania | {“Population”: 1517550} |
| 3798 | Phoenix | USA | Arizona | {“Population”: 1321045} |
| 3799 | San Diego | USA | California | {“Population”: 1223400} |
| 3800 | Dallas | USA | Texas | {“Population”: 1188580} |
| 3801 | San Antonio | USA | Texas | {“Population”: 1144646} |
+——+————–+————-+————–+————————-+
9 rows in set (0.0077 sec)
MySQL localhost:33060+ world_x Py >

MySQL Shell for Python来对文档与集合进行操作

MySQL Shell for Python来对文档与集合进行操作

启动MySQL Shell
安装并启动MySQL server后,将MySQL Shell连接到server实例。默认情况下,MySQL Shell使用X协议连接。
在运行server实例的系统上,打开一个终端窗口,并使用以下命令启动MySQL Shell:

[root@mysqlcs ~]# mysqlsh root@localhost/world_x --py
Please provide the password for 'root@localhost': ******
Save password for 'root@localhost'? [Y]es/[N]o/Ne[v]er (default No): N
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/world_x'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 84 (X protocol)
Server version: 5.7.26-log Source distribution
Default schema `world_x` accessible through db.
 MySQL  localhost:33060+  world_x  Py >

创建、列出和删除集合
在MySQL Shell中,你可以创建新的集合,获取模式中已存在集合的列表,或者从模式中删除已存在的集合。集合名称区分大小写,每个集合名 称必须唯一。

确认模式
要显示分配给模式变量的值,请输入db。

 MySQL  localhost:33060+  world_x  Py > db

如果schema值不是schema:world_x,则设置db变量如下:

 MySQL  localhost:33060+  world_x  Py >\use world_x

创建集合
要在现有模式中创建新集合,可以使用create_collection()方法。下面的示例在world_x数据库中创建一个名为flags的集合。

 MySQL  localhost:33060+  world_x  Py > db.create_collection("flags");

显示集合
要显示world_x数据库中的所有集合,可以在schema对象上使用get_collections()方法。服务器返回的集合出现在括号中。

 MySQL  localhost:33060+  world_x  Py > db.get_collections()
[
    
]

删除集合
要从数据库中删除现有集合,可以在session对象上调用drop_collection()方法。例如,要从world_x数据库中删除flags集合,输入:

 MySQL  localhost:33060+  world_x  Py > db.drop_collection("flags");

添加文档
使用MySQL Shell,可以使用add()方法将一个文档或一个列表文档插入到现有的集合中。本节中的所有示例都使用flags集合。
将下面的文档插入countryinfo集合。按两次Enter键插入文档。

 MySQL  localhost:33060+  world_x  Py > db.flags.add(
                                     -> {
                                     ->   "GNP": .6,
                                     ->   "IndepYear": 1967,
                                     ->   "Name": "Sealand",
                                     ->   "_id": "SEA",
                                     ->   "demographics": {
                                     ->      "LifeExpectancy": 79,
                                     ->      "Population": 27
                                     ->   },
                                     ->   "geography": {
                                     ->      "Continent": "Europe",
                                     ->      "Region": "British Islands",
                                     ->      "SurfaceArea": 193
                                     ->   },
                                     ->   "government": {
                                     ->      "GovernmentForm": "Monarchy",
                                     ->      "HeadOfState": "Michael Bates"
                                     ->   }
                                     ->  }
                                     -> )
                                     ->
Query OK, 1 item affected (0.0106 sec)

该方法返回操作的状态。

每个文档都需要一个名为_id的标识符字段。_id字段的值必须在同一个集合中的所有文档中唯一。如果传递给add()方法的文档不包含_id字段 ,MySQL Shell会自动在文档中插入一个字段,并设置该字段的值为生成的UUID (universal unique identifier,通用唯一标识符)。

查找文档
可以使用find()方法从数据库中的集合中查询并返回文档。MySQL Shell为find()方法提供了额外的方法来过滤和排序返回的文档。MySQL提供了以下操作符来指定搜索条件:OR (||), AND (&&), XOR, IS, NOT,BETWEEN, IN, LIKE, !=, <>, >, >=, < , <=, &, |, <<, >>, +, -, *, /, ~, 和 %.

查找集合中的所有文档
要返回集合中的所有文档,可以使用find()方法,但不指定搜索条件。例如,下面的操作返回countryinfo集合中的所有文档。

 MySQL  localhost:33060+  world_x  Py > db.flags.find()
{
    "GNP": 828,
    "_id": "ABW",
    "Name": "Aruba",
    "IndepYear": 1972,
    "geography": {
        "Region": "Caribbean",
        "Continent": "North America",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Beatrix",
        "GovernmentForm": "Nonmetropolitan Territory of The Netherlands"
    },
    "demographics": {
        "Population": 103000,
        "LifeExpectancy": 78.4000015258789
    }
}
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
2 documents in set (0.0019 sec)

该方法生成的结果除了包含集合中的所有文档外,还包含操作信息。

过滤搜索
你可以在find()方法中包含搜索条件。组成搜索条件的表达式的语法与传统MySQL相同。所有表达式必须用引号括起来。
这里的所有示例都使用world_x数据库中的flags集合。为简洁起见,有些示例不显示输出。
一个简单的搜索条件由_id字段和文档的唯一标识符组成。下面的例子返回一个与标识符字符串匹配的文档:

 MySQL  localhost:33060+  world_x  Py > db.flags.find("_id = 'SEA'")
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
1 document in set (0.0010 sec)

下面的示例搜索GNP高于5000亿美元的所有国家。国家信息收集以百万为单位衡量国民生产总值。

 MySQL  localhost:33060+  world_x  Py > db.flags.find("GNP > 500000")
{
    "GNP": 800000000,
    "_id": "CN",
    "Name": "Hunan",
    "IndepYear": 1971,
    "geography": {
        "Region": "Caribbean",
        "Continent": "North America",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Beatrix",
        "GovernmentForm": "Nonmetropolitan Territory of The Netherlands"
    },
    "demographics": {
        "Population": 8030000000,
        "LifeExpectancy": 85
    }
}
1 document in set (0.0013 sec)

下面查询中的Population字段嵌入到人口统计对象中。要访问嵌入式字段,使用人口统计数据和人口之间的句号来识别关系。文档名和字段名区 分大小写。

 MySQL  localhost:33060+  world_x  Py > db.flags.find("GNP > 500000 and demographics.Population > 100000000")
{
    "GNP": 800000000,
    "_id": "CN",
    "Name": "Hunan",
    "IndepYear": 1971,
    "geography": {
        "Region": "Caribbean",
        "Continent": "North America",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Beatrix",
        "GovernmentForm": "Nonmetropolitan Territory of The Netherlands"
    },
    "demographics": {
        "Population": 8030000000,
        "LifeExpectancy": 85
    }
}
1 document in set (0.0013 sec)

下列表达式中的算术运算符用于查询人均国民生产总值高于30000美元的国家。搜索条件可以包括算术运算符和大多数MySQL函数。

 MySQL  localhost:33060+  world_x  Py > db.flags.find("GNP*1000000/demographics.Population > 30000")
{
    "GNP": 800000000,
    "_id": "CN",
    "Name": "Hunan",
    "IndepYear": 1971,
    "geography": {
        "Region": "Caribbean",
        "Continent": "North America",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Beatrix",
        "GovernmentForm": "Nonmetropolitan Territory of The Netherlands"
    },
    "demographics": {
        "Population": 8030000000,
        "LifeExpectancy": 85
    }
}
1 document in set (0.0012 sec)

可以使用bind()方法将值与搜索条件分开。例如,与其指定硬编码的国家名作为条件,不如用冒号和以字母开头的名称(如country)组成的 命名占位符。然后在bind()方法中包含占位符和值,如下所示:

 MySQL  localhost:33060+  world_x  Py > db.flags.find("Name = :country").bind("country", "Aruba")
{
    "GNP": 828,
    "_id": "ABW",
    "Name": "Aruba",
    "IndepYear": 1972,
    "geography": {
        "Region": "Caribbean",
        "Continent": "North America",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Beatrix",
        "GovernmentForm": "Nonmetropolitan Territory of The Netherlands"
    },
    "demographics": {
        "Population": 103000,
        "LifeExpectancy": 78.4000015258789
    }
}
1 document in set (0.0014 sec)

指定返回列
可以返回文档的特定字段,而不是返回所有字段。下面的示例返回countryinfo集合中匹配搜索条件的所有文档的GNP和Name字段。使用fields()方法传递要返回的字段列表

 MySQL  localhost:33060+  world_x  Py > db.flags.find("GNP > 5000000").fields(["GNP", "Name"])
{
    "GNP": 800000000,
    "Name": "Hunan"
}
1 document in set (0.0014 sec)

此外,您可以使用描述要返回的文档的表达式来更改返回的文档——添加、重命名、嵌套甚至计算新的字段值。例如,使用下面的表达式更改字 段的名称,使其仅返回两个文档。

 MySQL  localhost:33060+  world_x  Py > db.flags.find().fields(mysqlx.expr('{"Name": upper(Name), "GNPPerCapita":  GNP*1000000/demographics.Population}')).limit(2)
{
    "Name": "ARUBA",
    "GNPPerCapita": 8038.834951456311
}
{
    "Name": "HUNAN",
    "GNPPerCapita": 99626.400996264
}
2 documents in set (0.0012 sec)

限制、排序和跳过结果
可以应用limit()、sort()和skip()方法来管理find()方法返回的文档数量和顺序。

要指定结果集中包含的文档数量,可以在limit()方法的find()方法后面添加一个值。下面的查询返回flags集合中的前2个文档。

 MySQL  localhost:33060+  world_x  Py > db.flags.find().limit(2)
{
    "GNP": 828,
    "_id": "ABW",
    "Name": "Aruba",
    "IndepYear": 1972,
    "geography": {
        "Region": "Caribbean",
        "Continent": "North America",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Beatrix",
        "GovernmentForm": "Nonmetropolitan Territory of The Netherlands"
    },
    "demographics": {
        "Population": 103000,
        "LifeExpectancy": 78.4000015258789
    }
}
{
    "GNP": 800000000,
    "_id": "CN",
    "Name": "Hunan",
    "IndepYear": 1971,
    "geography": {
        "Region": "Caribbean",
        "Continent": "North America",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Beatrix",
        "GovernmentForm": "Nonmetropolitan Territory of The Netherlands"
    },
    "demographics": {
        "Population": 8030000000,
        "LifeExpectancy": 85
    }
}
2 documents in set (0.0028 sec)

要指定结果的顺序,可将sort()方法添加到find()方法后面。向sort()方法传递一个列表,其中包含一个或多个用于排序的字段,还可以 根据需要传递descending (desc)或ascending (asc)属性。升序是默认的排序类型。

例如,下面的查询按indeyear字段对所有文档进行排序,然后按降序返回前2个文档。

 MySQL  localhost:33060+  world_x  Py > db.flags.find().sort(["IndepYear desc"]).limit(2)
{
    "GNP": 828,
    "_id": "ABW",
    "Name": "Aruba",
    "IndepYear": 1972,
    "geography": {
        "Region": "Caribbean",
        "Continent": "North America",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Beatrix",
        "GovernmentForm": "Nonmetropolitan Territory of The Netherlands"
    },
    "demographics": {
        "Population": 103000,
        "LifeExpectancy": 78.4000015258789
    }
}
{
    "GNP": 800000000,
    "_id": "CN",
    "Name": "Hunan",
    "IndepYear": 1971,
    "geography": {
        "Region": "Caribbean",
        "Continent": "North America",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Beatrix",
        "GovernmentForm": "Nonmetropolitan Territory of The Netherlands"
    },
    "demographics": {
        "Population": 8030000000,
        "LifeExpectancy": 85
    }
}
2 documents in set (0.0016 sec)

默认情况下,limit()方法从集合中的第一个文档开始。可以使用skip()方法来修改开始的文档。例如,要忽略第一个文档并返回匹配条件 的后面8个文档,就向skip()方法传递一个值1。

 MySQL  localhost:33060+  world_x  Py > db.flags.find().sort(["IndepYear desc"]).limit(3).skip(1)
{
    "GNP": 800000000,
    "_id": "CN",
    "Name": "Hunan",
    "IndepYear": 1971,
    "geography": {
        "Region": "Caribbean",
        "Continent": "North America",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Beatrix",
        "GovernmentForm": "Nonmetropolitan Territory of The Netherlands"
    },
    "demographics": {
        "Population": 8030000000,
        "LifeExpectancy": 85
    }
}
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
2 documents in set (0.0013 sec)

修改文档
可以使用modify()方法更新集合中的一个或多个文档。X DevAPI为modify()方法提供了额外的方法:
.设置和取消设置文档中的字段。
.追加、插入和删除数组
.绑定、限制和排序要修改的文档。

设置和不设置字段
modify()方法的工作原理是过滤一个集合,只包含需要修改的文档,然后对这些文档应用指定的操作。

在下面的示例中,modify()方法使用搜索条件来标识要更改的文档,然后set()方法替换嵌套的人口统计对象中的两个值。

 MySQL  localhost:33060+  world_x  Py > db.flags.modify("_id = 'SEA'").set("demographics", {"LifeExpectancy": 78,  "Population": 28})
Query OK, 1 item affected (0.0202 sec)

Rows matched: 1  Changed: 1  Warnings: 0

在修改文档之后,使用find()方法来验证更改。

 MySQL  localhost:33060+  world_x  Py > db.flags.find("_id = 'SEA'")
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 28,
        "LifeExpectancy": 78
    }
}
1 document in set (0.0010 sec)

要从文档中删除内容,可以使用modify()和unset()方法。例如,下面的查询从匹配搜索条件的文档中删除GNP。

 MySQL  localhost:33060+  world_x  Py > db.flags.modify("Name = 'Sealand'").unset("GNP")
Query OK, 1 item affected (0.0051 sec)

Rows matched: 1  Changed: 1  Warnings: 0

使用find()方法验证更改。

 MySQL  localhost:33060+  world_x  Py > db.flags.find("Name = 'Sealand'")
{
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 28,
        "LifeExpectancy": 78
    }
}
1 document in set (0.0012 sec)

追加、插入和删除数组
要向数组字段添加元素,或者插入、删除数组中的元素,可以使用array_append()、array_insert()或array_delete()方法。下面的例子 修改了flags集合,以支持跟踪国际机场。
第一个例子使用modify()和set()方法在所有文档中创建一个新的Airports字段。在没有指定搜索条件的情况下修改文档时要小心。这个操 作将修改集合中的所有文档。

 MySQL  localhost:33060+  world_x  Py > db.flags.modify("True").set("Airports", [])
Query OK, 3 items affected (0.0226 sec)

Rows matched: 3  Changed: 3  Warnings: 0

添加了Airports字段后,下一个示例使用array_append()方法将一个新机场添加到一个文档中。美元。下例中的Airports表示当前文档的 Airports字段。

 MySQL  localhost:33060+  world_x  Py > db.flags.modify("Name = 'Hunan'").array_append("$.Airports", "TY")
Query OK, 1 item affected (0.0067 sec)

Rows matched: 1  Changed: 1  Warnings: 0

使用db.flags.find(“Name = ‘Hunan'”)查看更改

 MySQL  localhost:33060+  world_x  Py > db.flags.find("Name = 'Hunan'")
{
    "GNP": 800000000,
    "_id": "CN",
    "Name": "Hunan",
    "Airports": [
        "TY"
    ],
    "IndepYear": 1971,
    "geography": {
        "Region": "Caribbean",
        "Continent": "North America",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Beatrix",
        "GovernmentForm": "Nonmetropolitan Territory of The Netherlands"
    },
    "demographics": {
        "Population": 8030000000,
        "LifeExpectancy": 85
    }
}
1 document in set (0.0011 sec)

要在数组的不同位置插入元素,可以使用array_insert()方法在路径表达式中指定要插入的索引。在这个例子中,索引是0,即数组的第一个 元素。

 MySQL  localhost:33060+  world_x  Py > db.flags.modify("Name = 'Hunan'").array_insert("$.Airports[0]", "HH")
Query OK, 1 item affected (0.0068 sec)

Rows matched: 1  Changed: 1  Warnings: 0

要从数组中删除元素,必须向array_delete()方法传递要删除元素的索引。

 MySQL  localhost:33060+  world_x  Py > db.flags.modify("Name = 'Hunan'").array_delete("$.Airports[1]")
Query OK, 1 item affected (0.0062 sec)

Rows matched: 1  Changed: 1  Warnings: 0

删除文档
可以使用remove()方法从数据库集合中删除部分或全部文档。X DevAPI为remove()方法提供了额外的方法,用于过滤和排序要删除的文档。

使用条件删除文档
下面的例子向remove()方法传递了一个搜索条件。所有符合条件的文档都将从flags集合中删除。在这个例子中,有一个文档符合条件。

 MySQL  localhost:33060+  world_x  Py > db.flags.remove("_id = 'SEA'")
Query OK, 1 item affected (0.0057 sec)

删除第一个文档
要删除flags集合中的第一个文档,可使用limit()方法,将值设为1。

 MySQL  localhost:33060+  world_x  Py > db.flags.remove("True").limit(1)
Query OK, 1 item affected (0.0047 sec)

按顺序删除最后一个文档
下面的示例按国家名称删除flags集合中的最后一个文档。

 MySQL  localhost:33060+  world_x  Py > db.flags.remove("True").sort(["Name desc"]).limit(1)
Query OK, 1 item affected (0.0086 sec)

删除集合中的所有文档
可以删除集合中的所有文档。为此,使用remove(”True”)方法,而不指定搜索条件。

MySQL Shell对关系表中的文档进行操作

MySQL Shell对关系表中的文档进行操作
在MySQL中,表可以包含传统的关系型数据、JSON值,或者两者都包含。你可以把传统数据和JSON文档结合起来,把文档存储在原生JSON数据类型的列中。

这里使用world_x数据库中的city表进行演示。

city表描述
city表有五个列(或字段)。

mysql> use world_x
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> desc city;
+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| ID          | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name        | char(35) | NO   |     |         |                |
| CountryCode | char(3)  | NO   |     |         |                |
| District    | char(20) | NO   |     |         |                |
| Info        | json     | YES  |     | NULL    |                |
+-------------+----------+------+-----+---------+----------------+
5 rows in set (0.01 sec)

插入记录
要向表的列中插入一个文档,只需按正确的顺序向values()方法传递一个格式良好的JSON文档。在下面的示例中,文档作为要插入Info列的最 终值被传递。

 MySQL  localhost:33060+  world_x  JS > db.city.insert().values(null, "San Francisco", "USA", "California",  '{"Population":830000}')
Query OK, 1 item affected (0.0104 sec)

查询记录
你可以使用搜索条件进行查询,计算表达式中的文档值。

 MySQL  localhost:33060+  world_x  JS > db.city.select(["ID", "Name", "CountryCode", "District", "Info"]).where("CountryCode =  :country and Info->'$.Population' > 1000000").bind('country', 'USA')
+------+--------------+-------------+--------------+-------------------------+
| ID   | Name         | CountryCode | District     | Info                    |
+------+--------------+-------------+--------------+-------------------------+
| 3793 | New York     | USA         | New York     | {"Population": 8008278} |
| 3794 | Los Angeles  | USA         | California   | {"Population": 3694820} |
| 3795 | Chicago      | USA         | Illinois     | {"Population": 2896016} |
| 3796 | Houston      | USA         | Texas        | {"Population": 1953631} |
| 3797 | Philadelphia | USA         | Pennsylvania | {"Population": 1517550} |
| 3798 | Phoenix      | USA         | Arizona      | {"Population": 1321045} |
| 3799 | San Diego    | USA         | California   | {"Population": 1223400} |
| 3800 | Dallas       | USA         | Texas        | {"Population": 1188580} |
| 3801 | San Antonio  | USA         | Texas        | {"Population": 1144646} |
+------+--------------+-------------+--------------+-------------------------+
9 rows in set (0.0078 sec)

删除记录
可以使用搜索条件进行删除,计算表达式中的文档值。

 MySQL  localhost:33060+  world_x  JS > db.city.delete().where("CountryCode = :country and Info->'$.Population'  =1830000").bind('country', 'CN')
Query OK, 1 item affected (0.0115 sec)

MySQL Shell对关系表进行操作

MySQL Shell不仅可以操作JSON文档,还可以操作关系表。

在MySQL中,每个关系表都与特定的存储引擎相关联。本节中的例子使用world_x数据库中的InnoDB表。

确认模式
要显示分配给模式变量的值,请输入db。

 MySQL  localhost:33060+  world_x  JS > db

如果schema值不是schema:world_x,则设置db变量如下:

mysql-js> \use world_x

显示所有表
要显示world_x数据库中的所有关系表,可以在schema对象上使用getTables()方法。

 MySQL  localhost:33060+  world_x  JS > db.getTables()
[
    ,
    ,
    ,
    
]

基本表操作
表的基本操作范围包括:
db.name.insert():insert()方法向指定的表中插入一条或多条记录。
db.name.select():select()方法返回指定表中的部分或全部记录。
db.name.update():update()方法更新指定表中的记录。
db.name.delete():delete()方法从指定的表中删除一条或多条记录。

向表中插入记录
可以结合values()方法使用insert()方法将记录插入到现有的关系表中。insert()方法接受单个列或表中的所有列作为参数。使用一个或 多个values()方法指定要插入的值。

插入完整记录
要插入完整的记录,向insert()方法传递表中的所有列。然后向values()方法传递表中的每一列的一个值。例如,要向world_x数据库中的 city表中添加一条新记录,插入下面的记录并按两次Enter键。

 MySQL  localhost:33060+  world_x  JS > db.city.insert("ID", "Name", "CountryCode", "District", "Info").values(null,  "Olympia", "USA", "Washington", '{"Population": 5000}')
Query OK, 1 item affected (0.0250 sec)

城市表有5列:ID、Name、CountryCode、District和Info。每个值必须与它表示的列的数据类型匹配。

插入部分记录
下面的示例将值插入city表的ID、Name和CountryCode列。

 MySQL  localhost:33060+  world_x  JS > db.city.insert("ID", "Name", "CountryCode").values(null, "Little Falls",  "USA").values(null, "Happy Valley", "USA")
Query OK, 2 items affected (0.0092 sec)

Records: 2  Duplicates: 0  Warnings: 0

使用insert()方法指定列时,值的数量必须与列的数量匹配。在前面的例子中,必须提供三个值来匹配指定的三列。

查询表记录
你可以使用select()方法从数据库的表中查询并返回记录。X DevAPI提供了与select()方法一起使用的其他方法,用于过滤和排序返回的记 录。

MySQL提供了以下运营商指定搜索条件:OR(| |),AND(& &),XOR IS,NOT,BETWEEN,IN,LIKE, !=, <>, >, >=, < , <=, &, |, <<, >>, +, -, *, /, ~, 和%。

查询所有记录
要查询已存在表中的所有记录,只需使用select()方法,而无需指定搜索条件。下面的示例从world_x数据库中的city表中选择所有记录。

将空的select()方法限制为交互式语句。始终在应用程序代码中使用显式的列名选择。

 MySQL  localhost:33060+  world_x  JS > db.city.select()
+------+--------------------------------+-------------+----------------------+-------------------------+
| ID   | Name                           | CountryCode | District             | Info                    |
+------+--------------------------------+-------------+----------------------+-------------------------+
|    1 | Kabul                          | AFG         | Kabol                | {"Population": 1780000} |
|    2 | Qandahar                       | AFG         | Qandahar             | {"Population": 237500}  |
|    3 | Herat                          | AFG         | Herat                | {"Population": 186800}  |
|    4 | Mazar-e-Sharif                 | AFG         | Balkh                | {"Population": 127800}  |
..................
| 4078 | Nablus                         | PSE         | Nablus               | {"Population": 100231}  |
| 4079 | Rafah                          | PSE         | Rafah                | {"Population": 92020}   |
| 4082 | Olympia                        | USA         | Washington           | {"Population": 5000}    |
| 4089 | Little Falls                   | USA         |                      | NULL                    |
| 4096 | Happy Valley                   | USA         |                      | NULL                    |
+------+--------------------------------+-------------+----------------------+-------------------------+
4082 rows in set (0.0024 sec)

过滤搜索
要发出一个返回一组表列的查询,可以使用select()方法,并在方括号中指定要返回的列。这个查询返回city表中的Name和CountryCode列。

 MySQL  localhost:33060+  world_x  JS > db.city.select(["Name", "CountryCode"])
+--------------------------------+-------------+
| Name                           | CountryCode |
+--------------------------------+-------------+
| Kabul                          | AFG         |
| Qandahar                       | AFG         |
| Herat                          | AFG         |
| Mazar-e-Sharif                 | AFG         |
.................
| Jabaliya                       | PSE         |
| Nablus                         | PSE         |
| Rafah                          | PSE         |
| Olympia                        | USA         |
| Little Falls                   | USA         |
| Happy Valley                   | USA         |
+--------------------------------+-------------+
4082 rows in set (0.0023 sec)

要查询返回符合特定搜索条件的行,可以使用where()方法来包含这些条件。例如,下面的示例返回以字母Z开头的城市的名称和国家代码。

 MySQL  localhost:33060+  world_x  JS > db.city.select(["Name", "CountryCode"]).where("Name like 'Z%'")
+-----------------+-------------+
| Name            | CountryCode |
+-----------------+-------------+
| Zaanstad        | NLD         |
| Zoetermeer      | NLD         |
| Zwolle          | NLD         |
| Zenica          | BIH         |
| Zagazig         | EGY         |
| Zaragoza        | ESP         |
| Zamboanga       | PHL         |
| Zahedan         | IRN         |
| Zanjan          | IRN         |
| Zabol           | IRN         |
| Zama            | JPN         |
| Zhezqazghan     | KAZ         |
| Zhengzhou       | CHN         |
| Zibo            | CHN         |
| Zhangjiakou     | CHN         |
| Zhuzhou         | CHN         |
| Zhangjiang      | CHN         |
| Zigong          | CHN         |
| Zaozhuang       | CHN         |
| Zhenjiang       | CHN         |
| Zhongshan       | CHN         |
| Zunyi           | CHN         |
| Zhaoqing        | CHN         |
| Zhangzhou       | CHN         |
| Zhaodong        | CHN         |
| Zhuhai          | CHN         |
| Zaoyang         | CHN         |
| Zhoushan        | CHN         |
| Zhoukou         | CHN         |
| Zalantun        | CHN         |
| Zhumadian       | CHN         |
| Zixing          | CHN         |
| Zhucheng        | CHN         |
| Zhangjiagang    | CHN         |
| Zagreb          | HRV         |
| Zapopan         | MEX         |
| Zamora          | MEX         |
| Zitácuaro       | MEX         |
| Zacatecas       | MEX         |
| Zinacantepec    | MEX         |
| Zumpango        | MEX         |
| Zinder          | NER         |
| Zaria           | NGA         |
| Zabrze          | POL         |
| Zielona Góra    | POL         |
| Zwickau         | DEU         |
| Ziguinchor      | SEN         |
| Zürich          | CHE         |
| Zanzibar        | TZA         |
| Zonguldak       | TUR         |
| Zaporizzja      | UKR         |
| Zytomyr         | UKR         |
| Zelenograd      | RUS         |
| Zlatoust        | RUS         |
| Zelenodolsk     | RUS         |
| Zeleznodoroznyi | RUS         |
| Zeleznogorsk    | RUS         |
| Zukovski        | RUS         |
| Zeleznogorsk    | RUS         |
+-----------------+-------------+
59 rows in set (0.0049 sec)

可以使用bind()方法将值与搜索条件分开。例如,不使用“Name = ‘Z%’ ”作为条件,而是使用冒号和以字母开头的名称组成的命名占位符, 例如Name。然后在bind()方法中包含占位符和值,如下所示:

 MySQL  localhost:33060+  world_x  JS > db.city.select(["Name", "CountryCode"]).where("Name like :name").bind("name", "Z%")
+-----------------+-------------+
| Name            | CountryCode |
+-----------------+-------------+
| Zaanstad        | NLD         |
| Zoetermeer      | NLD         |
| Zwolle          | NLD         |
| Zenica          | BIH         |
| Zagazig         | EGY         |
| Zaragoza        | ESP         |
| Zamboanga       | PHL         |
| Zahedan         | IRN         |
| Zanjan          | IRN         |
| Zabol           | IRN         |
| Zama            | JPN         |
| Zhezqazghan     | KAZ         |
| Zhengzhou       | CHN         |
| Zibo            | CHN         |
| Zhangjiakou     | CHN         |
| Zhuzhou         | CHN         |
| Zhangjiang      | CHN         |
| Zigong          | CHN         |
| Zaozhuang       | CHN         |
| Zhenjiang       | CHN         |
| Zhongshan       | CHN         |
| Zunyi           | CHN         |
| Zhaoqing        | CHN         |
| Zhangzhou       | CHN         |
| Zhaodong        | CHN         |
| Zhuhai          | CHN         |
| Zaoyang         | CHN         |
| Zhoushan        | CHN         |
| Zhoukou         | CHN         |
| Zalantun        | CHN         |
| Zhumadian       | CHN         |
| Zixing          | CHN         |
| Zhucheng        | CHN         |
| Zhangjiagang    | CHN         |
| Zagreb          | HRV         |
| Zapopan         | MEX         |
| Zamora          | MEX         |
| Zitácuaro       | MEX         |
| Zacatecas       | MEX         |
| Zinacantepec    | MEX         |
| Zumpango        | MEX         |
| Zinder          | NER         |
| Zaria           | NGA         |
| Zabrze          | POL         |
| Zielona Góra    | POL         |
| Zwickau         | DEU         |
| Ziguinchor      | SEN         |
| Zürich          | CHE         |
| Zanzibar        | TZA         |
| Zonguldak       | TUR         |
| Zaporizzja      | UKR         |
| Zytomyr         | UKR         |
| Zelenograd      | RUS         |
| Zlatoust        | RUS         |
| Zelenodolsk     | RUS         |
| Zeleznodoroznyi | RUS         |
| Zeleznogorsk    | RUS         |
| Zukovski        | RUS         |
| Zeleznogorsk    | RUS         |
+-----------------+-------------+
59 rows in set (0.0040 sec)

要使用AND操作符进行查询,在where()方法的搜索条件之间添加操作符。

 MySQL  localhost:33060+  world_x  JS > db.city.select(["Name", "CountryCode"]).where("Name like 'Z%' and CountryCode =  'CHN'")
+--------------+-------------+
| Name         | CountryCode |
+--------------+-------------+
| Zhengzhou    | CHN         |
| Zibo         | CHN         |
| Zhangjiakou  | CHN         |
| Zhuzhou      | CHN         |
| Zhangjiang   | CHN         |
| Zigong       | CHN         |
| Zaozhuang    | CHN         |
| Zhenjiang    | CHN         |
| Zhongshan    | CHN         |
| Zunyi        | CHN         |
| Zhaoqing     | CHN         |
| Zhangzhou    | CHN         |
| Zhaodong     | CHN         |
| Zhuhai       | CHN         |
| Zaoyang      | CHN         |
| Zhoushan     | CHN         |
| Zhoukou      | CHN         |
| Zalantun     | CHN         |
| Zhumadian    | CHN         |
| Zixing       | CHN         |
| Zhucheng     | CHN         |
| Zhangjiagang | CHN         |
+--------------+-------------+
22 rows in set (0.0051 sec)

要指定多个条件运算符,可以将搜索条件放在括号中以更改运算符的优先级。下面的例子演示了AND和OR操作符的位置。

 MySQL  localhost:33060+  world_x  JS > db.city.select(["Name", "CountryCode"]).where("Name like 'Z%' and (CountryCode = 'CHN'  or CountryCode = 'RUS')")
+-----------------+-------------+
| Name            | CountryCode |
+-----------------+-------------+
| Zhengzhou       | CHN         |
| Zibo            | CHN         |
| Zhangjiakou     | CHN         |
| Zhuzhou         | CHN         |
| Zhangjiang      | CHN         |
| Zigong          | CHN         |
| Zaozhuang       | CHN         |
| Zhenjiang       | CHN         |
| Zhongshan       | CHN         |
| Zunyi           | CHN         |
| Zhaoqing        | CHN         |
| Zhangzhou       | CHN         |
| Zhaodong        | CHN         |
| Zhuhai          | CHN         |
| Zaoyang         | CHN         |
| Zhoushan        | CHN         |
| Zhoukou         | CHN         |
| Zalantun        | CHN         |
| Zhumadian       | CHN         |
| Zixing          | CHN         |
| Zhucheng        | CHN         |
| Zhangjiagang    | CHN         |
| Zelenograd      | RUS         |
| Zlatoust        | RUS         |
| Zelenodolsk     | RUS         |
| Zeleznodoroznyi | RUS         |
| Zeleznogorsk    | RUS         |
| Zukovski        | RUS         |
| Zeleznogorsk    | RUS         |
+-----------------+-------------+
29 rows in set (0.0042 sec)

可以使用limit()、orderBy()和offSet()方法来管理select()方法返回的记录的数量和顺序。

要指定结果集中包含的记录数,可以在limit()方法后面添加一个值给select()方法。例如,下面的查询返回country表中的前5条记录。

 MySQL  localhost:33060+  world_x  JS > db.country.select(["Code", "Name"]).limit(5)
+------+-------------+
| Code | Name        |
+------+-------------+
| ABW  | Aruba       |
| AFG  | Afghanistan |
| AGO  | Angola      |
| AIA  | Anguilla    |
| ALB  | Albania     |
+------+-------------+
5 rows in set (0.0013 sec)

要指定结果的顺序,可以在select()方法后面添加orderBy()方法。向orderBy()方法传递一个列表,其中包含一个或多个用于排序的列, 还可以根据需要传递降序(desc)或升序(asc)属性。升序是默认的排序类型。

例如,下面的查询按Name列对所有记录进行排序,然后按降序返回前三条记录。

 MySQL  localhost:33060+  world_x  JS > db.country.select(["Code", "Name"]).orderBy(["Name desc"]).limit(3)
+------+------------+
| Code | Name       |
+------+------------+
| ZWE  | Zimbabwe   |
| ZMB  | Zambia     |
| YUG  | Yugoslavia |
+------+------------+
3 rows in set (0.0016 sec)

默认情况下,limit()方法从表中的第一条记录开始。可以使用offset()方法修改起始记录。例如,要忽略第一条记录并返回符合条件的后 三条记录,可以向offset()方法传递一个值1。

 MySQL  localhost:33060+  world_x  JS > db.country.select(["Code", "Name"]).orderBy(["Name desc"]).limit(3).offset(1)
+------+------------+
| Code | Name       |
+------+------------+
| ZMB  | Zambia     |
| YUG  | Yugoslavia |
| YEM  | Yemen      |
+------+------------+
3 rows in set (0.0015 sec)

更新表记录
可以使用update()方法修改表中的一条或多条记录。update()方法的工作原理是过滤一个查询,只包含需要更新的记录,然后对这些记录应 用指定的操作。

要替换city表中的城市名,向set()方法传递新的城市名。然后,向where()方法传递要定位和替换的城市名。下面的例子将北京这个城市替 换为北京。

 MySQL  localhost:33060+  world_x  JS > db.city.update().set("Name", "Beijing").where("Name = 'Peking'")
Query OK, 1 item affected (0.0299 sec)

Rows matched: 1  Changed: 1  Warnings: 0

使用select()方法验证修改。

 MySQL  localhost:33060+  world_x  JS > db.city.select(["ID", "Name", "CountryCode", "District", "Info"]).where("Name =  'Beijing'")
+------+---------+-------------+----------+-------------------------+
| ID   | Name    | CountryCode | District | Info                    |
+------+---------+-------------+----------+-------------------------+
| 1891 | Beijing | CHN         | Peking   | {"Population": 7472000} |
+------+---------+-------------+----------+-------------------------+
1 row in set (0.0072 sec)

删除表记录
你可以使用delete()方法从数据库的一张表中删除部分或全部记录。X DevAPI提供了额外的方法与delete()方法一起使用,用于过滤和排序 要删除的记录。

使用条件删除记录
下面的例子将搜索条件传递给delete()方法。所有符合条件的记录都将从city表中删除。在这个例子中,只有一条记录符合条件。

 MySQL  localhost:33060+  world_x  JS > db.city.delete().where("Name = 'Olympia'")
Query OK, 1 item affected (0.0130 sec)

删除第一条记录
要删除city表中的第一条记录,可以使用limit()方法将值设为1。

 MySQL  localhost:33060+  world_x  JS > db.city.delete().limit(1)
Query OK, 1 item affected (0.0060 sec)

删除表中的所有记录
可以删除表中的所有记录。为此,可以使用delete()方法,但不指定搜索条件。在没有指定搜索条件的情况下删除记录时要小心。该操作将从 表中删除所有记录。