【MySQL Shell】6.8 AdminAPI MySQL 沙盒

本节介绍如何使用 AdminAPI 搭建沙盒部署。部署和使用 MySQL 的本地沙盒实例是开始探索 AdminAPI 的好方法。在部署到生产服务器上之前,可以在本地测试功能。AdminAPI 具有创建沙盒实例的内置功能,这些沙盒实例被正确配置为在本地部署的场景中与 InnoDB Cluster 、 InnoDB ClusterSet 和 InnoDB ReplicaSet 一起工作。

重点
沙盒实例仅适用于出于测试目的在本地计算机上部署和运行。在生产环境中,MySQL Server 实例被部署到网络上的不同主机上。有关更多信息,请参阅 第 7.4 节 “部署生产 InnoDB Cluster”

与生产部署不同,在生产部署中,您使用实例并通过连接(字符)串指定它们,沙盒实例与运行 MySQL Shell 的实例在同一台机器上本地运行。要选择沙盒实例,请提供 MySQL 沙盒实例正在侦听的端口号。

6.8.1 部署沙盒实例

AdminAPI 提供dba.deploySandboxInstance(port_number)操作,不像生产设置,每个实例在单独的主机上运行。port_number参数是 MySQL Server 实例侦听连接的 TCP 端口号。要部署绑定到端口 3310 的新沙盒实例,请执行:

mysql-js> dba.deploySandboxInstance(3310)

默认情况下,在 Unix 系统上,沙盒创建在名为 $HOME/mysql-sandboxes/port 的目录中。对于 Microsoft Windows 系统,目录为 $HOME/mysql-sandboxes/port 。每个沙盒实例都存储在以port_number命名的目录中。

将提示输入实例的root用户密码。

重点
每个沙盒实例都使用root用户和密码,并且在所有应该一起工作的沙盒实例上必须相同。在生产中不建议这样做。

要部署另一个沙盒服务器实例,请重复使用端口 3310 的沙盒实例的后续步骤,为每个实例选择不同的端口号。

要更改存储沙盒的目录,例如为了测试目的在一台主机上运行多个沙盒,请使用 MySQL Shell sandboxDir选项。例如,要在/home/user/sandbox1目录中使用沙盒,请执行:

mysql-js> shell.options.sandboxDir='/home/user/sandbox1'

然后对/home/user/sandbox1中的实例执行所有后续的沙盒相关操作。

当您部署沙盒时,MySQLShell 会搜索 mysqld 二进制文件,然后使用它创建沙盒实例。您可以通过配置PATH环境变量来配置 MySQLShell 搜索 mysqld 二进制文件的位置。这对于在将新版本的 MySQL 部署到生产环境之前在本地测试它非常有用。例如,要在路径/home/user/mysql-last/bin/issue处使用 mysqld 二进制文件:

PATH=/home/user/mysql-latest/bin/:$PATH

然后从设置PATH环境变量的终端运行 MySQL Shell 。部署的任何沙盒,使用配置路径中的mysqld 二进制文件。

dba.deploySandboxInstance()操作支持以下选项:

  • allowRootFrom 配置root用户可以从哪个主机连接。默认为root@%
  • ignoreSslError在沙盒实例上配置安全连接。当ignoreSslErrortrue(这是默认值)时,如果无法提供 SSL 支持并且部署服务器实例时没有 SSL 支持,则在操作期间不会发出错误。当ignoreSslError设置为false时,沙盒实例将部署 SSL 支持,如果无法配置 SSL 支持,将发出错误。
  • mysqldOptions在沙盒实例上配置其他选项。默认为空字符串,并接受指定选项和值的字符串列表。例如mysqldOptions: ["lower_case_table_names=1", "report_host="10.1.2.3"]} 。指定的选项将写入沙盒实例的选项文件。
  • portX配置用于 X 协议 连接的端口。默认值通过将端口值乘以 10 来计算。该值是介于 1024 和 65535 之间的整数。

6.8.2 管理沙盒实例

沙盒实例运行后,可以随时使用以下命令更改其状态。指定实例的端口号以标识它:

  • 要停止使用 JavaScript 的沙盒实例,请执行dba.stopSandboxInstance(instance) 。这会优雅地停止实例,而不是dba.killSandboxInstance(instance)
  • 要停止使用 Python 的沙盒实例,请执行:dba.stop_sandbox_instance(instance) 。与dba.kill_sandbox_instance(instance)不同,这会优雅地停止实例。
  • 要使用 JavaScript 启动沙盒实例,请执行:dba.startSandboxInstance(instance)
  • 要使用 Python 启动沙盒实例,请执行:dba.start_sandbox_instance(instance)
  • 要使用 JavaScript 杀死一个沙盒实例,请执行:dba.killSandboxInstance(instance) 。这会停止实例,而不会优雅地停止它,在模拟意外停止时非常有用。
  • 要使用 Python 杀死沙盒实例,请执行:dba.kil_sandbox_instance(instance) 。这会停止实例,而不会优雅地停止它,在模拟意外停止时非常有用。
  • 要使用 JavaScript 删除沙盒实例,请执行:dba.deleteSandboxInstance(instance) 。这将从文件系统中完全删除沙盒实例。
  • 要使用 Python 删除沙盒实例,请执行:dba.delete_SandboxInstance(instance) 。这将从文件系统中完全删除沙盒实例。

沙盒实例被认为是暂时的,并不是为生产使用而设计的。因此,版本升级不支持它们。在沙盒部署中,每个沙盒实例都使用本地mysql-sandboxes目录中的、$PATH中的 mysqld 二进制文件副本。如果 mysqld 的版本发生变化,例如在升级后,基于先前版本的沙盒将无法启动。这是因为与basedir下的依赖项相比,沙盒二进制文件已过时。

如果您确实希望在升级后保留一个沙盒实例,则解决方法是手动将升级的 mysqld 二进制文件复制到每个沙盒的bin目录中。然后通过执行dba.startSandboxInstance()启动沙盒。操作因超时失败,错误日志包含:

2020-03-26T11:43:12.969131Z 5 [System] [MY-013381] [Server] Server upgrade
from '80019' to '80020' started.
2020-03-26T11:44:03.543082Z 5 [System] [MY-013381] [Server] Server upgrade
from '80019' to '80020' completed.

虽然操作似乎因超时而失败,但沙盒已成功启动。

6.8.3 搭建 InnoDB Cluster 和 MySQL Router

在下面的示例中,我们利用使用 AdminAPI 的沙盒部署来完成以下任务,以部署带有 MySQL Router 的 InnoDB Cluster。

部署和使用 MySQL 的本地沙盒实例允许您在部署到生产服务器之前在本地测试功能。AdminAPI 内置了创建沙盒实例的功能,这些沙盒实例预先配置为在本地部署的场景中与 InnoDB Cluster 、 InnoDB ClusterSet 和 InnoDB ReplicaSet 一起使用。

本示例包含以下部分:

  • 安装
  • 创建 InnoDB Cluster 沙盒配置
  • 创建 InnoDB Cluster
  • 引导 MySQL Router
  • 测试 MySQL Router 配置

警告
沙盒实例仅适用于出于测试目的在本地计算机上部署和运行。

安装

安装以下组件:

创建 InnoDB Cluster 沙盒配置

要为一个故障提供容错,请创建一个具有三个实例的 InnoDB Cluster 。在本例中,我们将使用在同一台机器上运行的三个沙盒实例。在实际设置中,这三个实例将在网络上的不同主机上运行。

  1. 要启动 MySQL Shell,请执行:

    $ mysqlsh
    
  2. 要创建和启动 MySQL 沙盒实例,请使用作为 X AdminAPI 一部分的dba.deploySandboxInstance()函数。在 MySQL Shell 中执行以下三条语句,并为每个实例输入root密码:

    mysql-js> dba.deploySandboxInstance(3310)
    mysql-js> dba.deploySandboxInstance(3320)
    mysql-js> dba.deploySandboxInstance(3330)
    

    注意
    对所有实例使用相同的root密码。

创建 InnoDB Cluster

要创建 InnoDB Cluster ,请完成以下步骤:

  1. 通过执行以下命令连接到您希望成为 InnoDB Cluster 中主实例的 MySQL 实例:

    mysql-js> shell.connect('root@localhost:3310')
    
  2. 执行dba.createCluster()命令创建集群,并使用指定的变量 cluster 保存输出值:

    mysql-js> cluster = dba.createCluster('devCluster')
    

    此命令输出:

    A new InnoDB cluster will be created on instance 'localhost: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.
    
    Creating InnoDB cluster 'devCluster' 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.
    
    <Cluster:devCluster>
    
  3. 使用带有指定变量 cluster***cluster***函数验证创建是否成功:

    mysql-js> cluster.status()
    

    输出以下状态:

    {
    “clusterName”: “devCluster”,
    “defaultReplicaSet”: {
    		"name": "default",
    "primary": "127.0.0.1:3310",
    "ssl": "REQUIRED",
    "status": "OK_NO_TOLERANCE",
    "statusText": "Cluster is NOT tolerant to any failures.",
    "topology": {
    "127.0.0.1:3310": {
    	"address": "127.0.0.1:3310",
    	"memberRole": "PRIMARY",
    	"mode": "R/W",
    	"readReplicas": {},
    	"replicationLag": null,
    	"role": "HA",
    	"status": "ONLINE",
    	"version": "8.0.28"
    }
    },
    "topologyMode": "Single-Primary"
    }, “groupInformationSourceMember”:127.0.0.1:3310}
    
  4. 集群已启动并正在运行,但还不能容错。使用<Cluster>.addInstance()函数将其他 MySQL Server 实例添加到集群:

    {
    mysql-js> cluster.addInstance('root@localhost:3320')
    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 [C]lone/[I]ncremental recovery/[A]bort (default Clone):
    mysql-js> cluster.addInstance('root@localhost:3330')
    }
    
  5. 从提示中选择恢复方法。选项包括:

  • 克隆(Clone):克隆要添加到主集群的实例,删除该实例包含的所有事务。MySQL 克隆插件将自动安装。假设您正在添加一个空实例(尚未处理任何事务)或一个包含您不希望保留的事务的实例,请选择克隆选项。

  • 增量恢复(Incremental Recovery):使用异步复制将集群处理的所有事务恢复到加入实例。如果您确定集群处理的所有更新都已在启用 全局事务 ID(GTID) 的情况下完成,则增量恢复是合适的。没有清除的事务,新实例包含与集群或其子集相同的 GTID 集。

    在此示例中,选择 C 代表“克隆”:

    	Please select a recovery method [C]lone/[I]ncremental recovery/[A]bort (default Clone): C
    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.
    
    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.
    
    Adding instance to the cluster...
    
    Monitoring recovery process of the new cluster member. Press ^C to stop monitoring 
    and let it continue in background.
    Clone based state recovery is now in progress.
    
    NOTE: A server restart is expected to happen as part of the clone process. If the
    server does not support the RESTART command or does not come back after a
    while, you may need to manually start it back.
    
    * Waiting for clone to finish...
    NOTE: 127.0.0.1:3320 is being cloned from 127.0.0.1:3310
    ** Stage DROP DATA: Completed
    ** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed
    
    NOTE: 127.0.0.1:3320 is shutting down...
    
    * Waiting for server restart... ready
    * 127.0.0.1:3320 has restarted, waiting for clone to finish...
    ** Stage RESTART: Completed
    * Clone process has finished: 72.61 MB transferred in about 1 second (~72.61 MB/s)
    
    State recovery already finished for '127.0.0.1:3320'
    
    The instance '127.0.0.1:3320' was successfully added to the cluster.
    
  1. 添加创建的第三个实例,然后再次选择 C 作为克隆恢复方法:

    mysql-js> cluster.addInstance('root@localhost:3330')
    
  2. 查看集群状态,执行:

    mysql-js> cluster.status()
    

    输出如下:

    {
    "clusterName": "devCluster",
    "defaultReplicaSet": {
    "name": "default",
    "primary": "127.0.0.1:3310",
    "ssl": "REQUIRED",
    "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": {},
    			"replicationLag": null,
    			"role": "HA",
    			"status": "ONLINE",
    			"version": "8.0.28"
    		},
    		"127.0.0.1:3320": {
    			"address": "127.0.0.1:3320",
    			"memberRole": "SECONDARY",
    			"mode": "R/O",
    			"readReplicas": {},
    			"replicationLag": null,
    			"role": "HA",
    			"status": "ONLINE",
    			"version": "8.0.28"
    		},
    		"127.0.0.1:3330": {
    			"address": "127.0.0.1:3330",
    			"memberRole": "SECONDARY",
    			"mode": "R/O",
    			"readReplicas": {},
    			"replicationLag": null,
    			"role": "HA",
    			"status": "ONLINE",
    			"version": "8.0.28"
    		}
    	},
    	"topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "127.0.0.1:3310"
    }
    The setup of the InnoDB Cluster was successful!
    
  3. 集群现在最多可以容忍一个实例故障。执行\q以退出 MySQL Shell 。

引导 MySQL Router

MySQL InnoDB Cluster 设置完成后,测试集群的高可用性。为此,请使用 MySQL Router 。如果一个实例失败,MySQL Router 会自动更新其路由配置,并确保将新连接路由到其余实例。

在 MySQL Router 执行路由操作之前,请让它能够感知到新的 InnoDB Cluster 。为此,请使用–bootstrap选项并将 MySQL Router 指向集群的当前 R/W MySQL Server 实例(主实例)。使用-d选项将路由器的配置存储在名为mysqlrouter的文件夹中。

译者注
此处官方文档中一会是mysql-router,一会是mysqlrouter。应该是文档错误,故译者将其统一改为mysqlrouter

  1. 在家目录中打开终端:
    • 在 Linux 系统上,执行:
    [demo-user@losthost]$> mysqlrouter --bootstrap root@localhost:3310 -d mysqlrouter
    
    • 在 Windows 系统上,执行:
    C:\Users\demo-user> mysqlrouter --bootstrap root@localhost:3310 -d mysqlrouter
    

然后,MySQL Router 打印将用于路由连接的 TCP/IP 端口。有关更多信息,请参阅 部署 MySQL Router

  1. 成功配置 MySQL Router 后,在后台线程中启动它:
    • 在 Windows 系统上,使用start /B命令并将路由器指向使用–bootstrap选项生成的配置文件:
    C:\> start /B mysqlrouter -c %HOMEPATH%\mysql-router\mysqlrouter.conf
    
    • 或者,调用之前创建的mysqlrouter文件夹中的 Windows PowerShell 脚本:
    \mysqlrouter\start.ps1
    
    • 在使用 systemd 的 Linux 系统上,执行:
    sudo systemctl start mysqlrouter.service
    
    • 或者,在 Linux 系统上,调用在之前创建的mysqlrouter目录中的 Shell 脚本:
    /mysqlrouter/start.sh
    

测试 MySQL Router 配置

现在 InnoDB Cluster 和 MySQL Router 正在运行,测试集群设置。

不要直接连接到其中一个 MySQL Server 实例,而是通过 MySQL Router 连接。

  1. 执行以下连接命令:

    $ mysqlsh root@localhost:6446
    
  2. 提供root密码以连接到 InnoDB Cluster 。

  3. 通过创建一个变量cluster并为其分配dba.getCluster()操作的值来检查 InnoDB Cluster 的状态:

    mysql-js> cluster = dba.getCluster()
    mysql-js> cluster.status()
    
  4. 切换到 SQL 模式:

    mysql-js> \sql
    
  5. 查询实例正在运行在哪个接口,执行:

    mysql-sql> SELECT @@port;
        
           +--------+
    	   | @@port |
           +--------+
           |   3310 |
           +--------+
    1 row in set (0.0007 sec)
    
  6. 切换回 JavaScript 模式:

    mysql-sql> \js
    
  7. 使用dba.killSandboxInstance()函数来关闭 MySQL Server 实例。

    mysql-js> dba.killSandboxInstance(3310)
            
    Killing MySQL instance...
    
    Instance localhost:3310 successfully killed.
    
  8. 通过对刚刚终止的实例运行SELECT@@port命令,检查MySQL Router是否正确路由了流量,并检查结果:

    • 切换到 SQL 模式:
      mysql-js> \sql
      
    • 检查 MySQL 端口:
      mysql-sql> SELECT @@port;
      
  9. 返回一个错误;ERROR: 2013 (HY000): Lost connection to MySQL server during query 。此错误意味着在端口 3310 上运行的实例不再运行。

  10. 再次检查 MySQL 端口:

    mysql-sql> SELECT @@port;
    +--------+
    | @@port |
    +--------+
    |   3320 |
    +--------+
    
  11. 此输出显示端口 3320 上运行的实例已升级为新的读/写主实例。

  12. 返回 JavaScript 模式,并检查集群的状态:

    mysql-js> cluster.status()
    {
    "clusterName": "devCluster",
    "defaultReplicaSet": {
    	"name": "default",
    	"primary": "127.0.0.1:3320",
    	"ssl": "REQUIRED",
    	"status": "OK_NO_TOLERANCE",
    	"statusText": "Cluster is NOT tolerant to any failures. 1 member is not active.",
    	"topology": {
    		"127.0.0.1:3310": {
    			"address": "127.0.0.1:3310",
    			"memberRole": "SECONDARY",
    			"mode": "n/a",
    			"readReplicas": {},
    			"role": "HA",
    			"shellConnectError": "MySQL Error 2003: Could not open connection to '127.0.0.1:3310': 
    									Can't connect to MySQL server on '127.0.0.1:3310' (10061)",
    			"status": "(MISSING)"
    		},
    		"127.0.0.1:3320": {
    			"address": "127.0.0.1:3320",
    			"memberRole": "PRIMARY",
    			"mode": "R/W",
    			"readReplicas": {},
    			"replicationLag": null,
    			"role": "HA",
    			"status": "ONLINE",
    			"version": "8.0.28"
    		},
    		"127.0.0.1:3330": {
    			"address": "127.0.0.1:3330",
    			"memberRole": "SECONDARY",
    			"mode": "R/O",
    			"readReplicas": {},
    			"replicationLag": null,
    			"role": "HA",
    			"status": "ONLINE",
    			"version": "8.0.28"
    		}
    	},
    	"topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "127.0.0.1:3320"
    }
    
  13. 在端口 3310 上正式运行的 MySQL Server 实例状态为 Missing

  14. 使用该端口号执行dba.startSandboxInstance操作,重新启动此实例:

    mysql-js> dba.startSandboxInstance(3310)
    
  15. 检查集群的状态表明该实例已在集群中恢复为活动状态,但作为SECONDARY成员:

    mysql-js > cluster.status()
    {
    "clusterName": "devCluster",
    "defaultReplicaSet": {
    	"name": "default",
    	"primary": "127.0.0.1:3320",
    	"ssl": "REQUIRED",
    	"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": "SECONDARY",
    			"mode": "R/O",
    			"readReplicas": {},
    			"replicationLag": null,
    			"role": "HA",
    			"status": "ONLINE",
    			"version": "8.0.28"
    		},
    		"127.0.0.1:3320": {
    			"address": "127.0.0.1:3320",
    			"memberRole": "PRIMARY",
    			"mode": "R/W",
    			"readReplicas": {},
    			"replicationLag": null,
    			"role": "HA",
    			"status": "ONLINE",
    			"version": "8.0.28"
    		},
    		"127.0.0.1:3330": {
    			"address": "127.0.0.1:3330",
    			"memberRole": "SECONDARY",
    			"mode": "R/O",
    			"readReplicas": {},
    			"replicationLag": null,
    			"role": "HA",
    			"status": "ONLINE",
    			"version": "8.0.28"
    		}
    	},
    	"topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "127.0.0.1:3320"
    }
    
  16. 所有实例都恢复联机(在线),集群可以再次容忍一个实例的故障。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独上西楼影三人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值