暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

朝花夕拾16章MySQL Shell 第 6 章 MySQL 管理 API

原创 由迪 2023-07-13
702

第 6 章 MySQL 管理 API

目录

本章介绍 MySQL Shell 提供的 MySQL AdminAPI,它使您能够管理 MySQL 实例,使用它们创建 InnoDB Cluster、InnoDB ClusterSet 和 InnoDB ReplicaSet 部署,以及集成 MySQL Router。

6.1 使用 MySQL 管理 API

AdminAPI 由 MySQL Shell 提供。AdminAPI 通过dba全局变量及其关联方法进行访问。该dba变量的方法提供了使您能够部署、配置和管理 InnoDB Cluster、InnoDB ClusterSet 和 InnoDB ReplicaSet 的操作。例如,使用该 dba.createCluster()方法创建InnoDB Cluster。此外,AdminAPI 支持管理一些 MySQL Router 相关任务,例如创建或升级与 InnoDB Cluster、InnoDB ClusterSet 和 InnoDB ReplicaSet 配合使用的用户帐户。

AdminAPI支持以下部署场景:

  • *生产部署:*如果您想使用完整的生产环境,您需要配置所需数量的机器,然后将服务器实例部署到机器上。

  • *沙盒部署:*如果您想在提交完整的生产部署之前测试部署,提供的沙盒功能使您能够在本地计算机上设置测试环境。系统会为您创建具有所需配置的沙箱服务器实例。您可以尝试熟悉所使用的技术。

    重要的

    AdminAPI 沙箱部署不适合在完整的生产环境中使用。

MySQL Shell 除了原生 SQL 模式外,还提供 JavaScript 和 Python 两种语言模式。在本指南中,MySQL Shell 主要在 JavaScript 模式下使用。MySQL Shell 启动时默认处于 JavaScript 模式。\js通过发出JavaScript 模式和\pyPython 模式来切换模式。通过发出\js.

重要的

MySQL Shell 使您能够通过套接字连接连接到服务器,但 AdminAPI 需要到服务器实例的 TCP 连接。AdminAPI 不支持基于套接字的连接。

本节假设您熟悉 MySQL Shell;有关详细信息,请参阅 MySQL Shell 8.0 。MySQL Shell 还为 AdminAPI 提供在线帮助。要列出所有可用dba命令,请使用 dba.help()方法。有关特定方法的在线帮助,请使用通用格式 object.help('methodname')。例如,使用 JavaScript:

mysql-js> dba.help('getCluster')

Retrieves a cluster from the Metadata Store.

SYNTAX

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

WHERE

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

或者使用Python:

mysql-py>dba.help('get_cluster')
NAME
      get_cluster - Retrieves a cluster from the Metadata Store.

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

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

除了本文档之外,MySQL Shell JavaScript API 参考或 MySQL Shell Python API 参考中还有所有 AdminAPI 方法的开发人员文档,可从Connectors and APIs获取。

6.2 安装AdminAPI软件组件

如何安装 AdminAPI 所需的软件组件取决于您打算使用的部署类型:

  • 对于生产部署,请将组件安装到每台计算机。生产部署使用多台运行 MySQL 服务器实例的远程主机,因此您需要使用 SSH 或 Windows 远程桌面等工具连接到每台机器来执行安装组件等任务。
  • 对于沙箱部署,请将组件安装到单台计算机上。沙箱部署是在单台计算机本地进行的,因此只需在本地计算机上安装一次。

重要的

始终使用可用的最新版本的 MySQL Shell 和 MySQL Router,并确保其版本与 MySQL Server 版本相同或更高。MySQL Shell 和 MySQL Router 可以管理较旧的 MySQL Server 版本,但较旧版本的产品无法管理较新的 MySQL Server 版本中的功能。

使用以下文档下载并安装软件组件:

安装所需的软件后,本节将提供有关使用 AdminAPI 的更多信息。按照步骤设置第 7 章MySQL InnoDB Cluster第 8 章MySQL InnoDB ClusterSet第 9 章MySQL InnoDB ReplicaSet

6.2.1 使用MySQL 5.7实例

本文档假设您使用运行最新版本 MySQL 8 和 MySQL Shell 8 的 MySQL 实例。AdminAPI 还支持使用运行 MySQL 5.7 的实例,但描述的许多功能需要运行 MySQL 8 的实例。运行 MySQL 的实例存在以下差异5.7:

  • 运行 MySQL 5.7 的实例不支持 SET PERSIST,因此与运行 MySQL 8 的实例不同,它们无法远程或自动配置。 相反,在配置 MySQL 5.7 实例时,每次都必须连接到实例并使用该操作 dba.configureLocalInstance()。当实例选项文件在本地可用时,此操作会将设置保留到实例选项文件中。请参见 第 6.2.4 节“持久设置”

  • 运行 MySQL 5.7 的实例不支持自动节点配置,因此在将它们加入集群之前,您必须手动将它们与其他集群实例同步。这意味着要么依赖组复制的分布式恢复,这需要启用 GTID 的二进制日志,并且在有大量事务需要恢复时可能需要很长时间的等待,要么使用 MySQL Enterprise Backup 等工具手动复制数据。

    随着8.0版本中添加MySQL Clone插件,可以通过AdminAPI自动配置实例。当您添加支持 MySQL 克隆的 8.0 版本实例时,AdminAPI 会自动选择使加入实例与现有实例同步的最佳方式。例如,如果集群包含大量事务,则直接使用MySQL Clone来恢复数据,然后使用分布式恢复来同步克隆操作期间集群处理的所有事务。您可以直接从 MySQL Shell 监控操作进度,无需其他工具。这使得添加实例以扩展 InnoDB Cluster 和提高高可用性机会等任务变得毫不费力。有关更多信息,请参阅 第7.4.6节“将MySQL克隆与InnoDB集群一起使用”

  • 运行 MySQL 5.7 的实例与 InnoDB ReplicaSet 不兼容。

  • 运行 MySQL 5.7 的实例与 InnoDB ClusterSet 不兼容。

  • 使用 MySQL 5.7 服务器时,InnoDB Cluster 拓扑(无论是在单主模式还是多主模式下运行)无法动态更改。有关更多信息,请参阅更改集群的拓扑

  • 运行 MySQL 5.7 的实例与并行复制应用程序不兼容。有关更多信息 ,请参阅第 7.5.6 节 “配置并行复制应用程序”

  • 运行 MySQL 5.7 的实例不支持 autoRejoinTriesexitStateAction选项,这些选项配置实例尝试重新加入集群的次数以及实例离开时发生的情况。有关更多信息,请参阅 第 7.5.5 节 “配置实例的自动重新加入”

  • 运行 MySQL 5.7 的实例不支持该 consistency选项。有关更多信息,请参阅 第 7.5.4 节 “配置故障转移一致性”

  • 运行 MySQL 5.7 的实例不支持该 expelTimeout选项,该选项配置集群在驱逐与其他实例失去联系的实例之前等待的时间。

要使用这些功能,请将您的实例升级到 MySQL 8。

dba.configureInstance()对于运行 MySQL 5.7 的实例,请确保在将实例添加到集群之前 使用 以保留配置更改。对于 MySQL 5.7 上的非沙箱服务器实例(您手动配置而不是使用 的实例 dba.deploySandboxInstance()),如果您不使用该dba.configureInstance()操作,MySQL Shell 无法将任何 InnoDB ClusterSet 配置更改保留在实例的配置文件中。这会导致以下一种或两种情况:

  1. 组复制配置不会持久保存在实例的配置文件中,并且重新启动后,实例不会重新加入集群。
  2. 该实例对于集群使用无效。尽管可以使用 来验证实例 dba.checkInstanceConfiguration(),并且 MySQL Shell 会进行所需的配置更改以使实例可供集群使用做好准备,但这些更改不会保留在配置文件中,因此一旦重新启动就会丢失。

如果这两种情况都发生,您将无法使用该 dba.rebootClusterFromCompleteOutage() 操作使集群重新联机。这是因为,如果没有该dba.configureInstance() 操作,实例将丢失 MySQL Shell 所做的任何配置更改,并且由于这些更改未持久化,实例将恢复到为集群进行配置之前的先前状态。这会导致组复制停止响应,并最终命令超时。

6.2.2 配置主机名

在生产部署中,您使用的实例在单独的计算机上运行,因此每台计算机必须具有唯一的主机名,并且能够解析运行服务器实例的其他计算机的主机名。如果不是这种情况,您可以:

  1. 配置每台计算机以将其他计算机的 IP 映射到主机名。有关详细信息,请参阅您的操作系统文档。此配置是推荐的解决方案。
  2. 设置域名系统 (DNS) 服务。
  3. report_host 将每个实例的 MySQL 配置中的变量 配置为合适的外部可访问地址。

AdminAPI 支持使用 IP 地址而不是主机名。从 MySQL Shell 8.0.18 开始,如果目标 MySQL 服务器版本高于 8.0.13,则 AdminAPI 支持 IPv6 地址。

使用 MySQL Shell 8.0.18 或更高版本时,如果所有集群实例都运行 8.0.14 或更高版本,则您可以在连接字符串中使用 IPv6 地址或解析为 IPv6 地址的主机名,并使用 和 等 localAddress选项 ipAllowlist。有关使用 IPv6 的详细信息,请参阅对 IPv6 以及混合 IPv6 和 IPv4 组的支持

以前的版本仅支持 IPv4 地址。

要验证您是否正确配置了 MySQL 服务器的主机名,请处理以下查询。此查询显示实例如何向其他服务器报告其地址并尝试使用返回的地址从其他主机连接到该 MySQL 服务器:

SELECT coalesce(@@report_host, @@hostname);

6.2.3 连接到服务器实例

MySQL Shell 使您能够使用各种 API,并支持指定连接,如 使用类 URI 字符串或键值对连接到服务器中所述。您可以使用类似 URI 的字符串或键值对来指定连接。AdminAPI 不支持附加连接参数。 本文档演示了使用类似 URI 的连接字符串的 AdminAPI。

对于 AdminAPI 操作,您只能使用 TCP/IP 连接和经典 MySQL 协议连接到 InnoDB Cluster 中的服务器实例。AdminAPI 操作不支持使用 Unix 套接字和命名管道,并且 AdminAPI 操作不支持使用 X 协议。同样的限制也适用于服务器实例本身之间的连接。

笔记

客户端应用程序可以使用 X 协议、Unix 套接字和命名管道来连接到 InnoDB 集群中的实例。这些限制仅适用于使用 AdminAPI 命令的管理操作以及实例之间的连接。

例如,要以用户身份连接 myuser到位于 的 MySQL 服务器实例www.example.com,请在端口上 *3306*使用连接字符串:

myuser@www.example.com:3306

要将此连接字符串与 AdminAPI 操作(例如 )一起使用dba.configureInstance(),您需要确保连接字符串被解释为字符串。例如,用单引号 (’) 或双引号 (") 括住连接字符串。

如果您使用 AdminAPI 问题的 JavaScript 实现:

mysql-js> > dba.configureInstance('myuser@www.example.com:3306')

如果您使用Python实现AdminAPI问题:

mysql-py> dba.configure_instance('myuser@www.example.com:3306')

如果您在默认交互模式下运行 MySQL Shell,系统会提示您输入密码。AdminAPI 支持 MySQL Shell 的 第 4.4 节“可插入密码存储”,一旦您存储了用于连接实例的密码,系统将不再提示您输入该密码。

MySQL Shell 默认尝试 X 协议连接到服务器实例。如果您在为 AdminAPI 操作建立连接时未指定连接类型,则 MySQL Shell 的自动协议检测会在创建经典 MySQL 协议会话之前短暂创建 X 协议会话。

除非您使用 MySQL 路由器管理的端口连接到仅具有两个辅助(只读)实例的 InnoDB 集群,否则该行为不会产生任何影响。在这种情况下,两个实例之间的负载平衡无法正确管理,并且始终使用同一实例。为了避免这种副作用,您可以通过添加--mc--mysql选项来显式指定经典 MySQL 协议会话。

当一台或多台服务器确实无法访问时,打开许多服务器连接的某些操作可能需要很长时间才能执行,例如命令cluster.status() 。连接超时可能无法提供足够的时间进行响应。

从 MySQL Shell 8.0.28 开始,您可以使用 MySQL Shell 配置选项dba.connectTimeout为使用 AdminAPI 的任何会话设置默认连接超时(以秒为单位)。

6.2.4 保留设置

用于处理 InnoDB Cluster、InnoDB ClusterSet、InnoDB ReplicaSet 以及这些部署中的各个成员服务器实例的 AdminAPI 命令会修改实例上 MySQL Server 的配置。根据 MySQL Shell 连接到实例的方式以及实例上安装的 MySQL Server 的版本,这些配置更改可以自动保留到实例。

通过对实例进行持久设置,您可以确保实例重新启动后,配置更改得以保留。有关背景信息,请参阅 SET PERSIST。这种持久性对于可靠使用至关重要。例如,如果设置不是持久性的,则添加到集群的实例在重新启动后不会重新加入集群,因为配置更改会丢失。

满足以下要求的实例支持自动持久配置更改:

不满足这些要求的实例不支持自动持久化配置更改,并且当 AdminAPI 操作导致实例设置更改被持久化时,您会收到警告,例如:

WARNING: On instance 'localhost:3320' membership change cannot be persisted since MySQL version 5.7.21
does not support the SET PERSIST command (MySQL version >= 8.0.5 required). Please use the
<Dba>.configureLocalInstance command locally to persist the changes.

当针对当前运行 MySQL Shell 的 MySQL 实例(即本地实例)发出 AdminAPI 命令时,MySQL Shell 会将配置更改直接保留到该实例。在支持自动持久化配置更改的本地实例上,配置更改将持久化到实例的 mysqld-auto.cnf文件中,并且配置更改不需要任何进一步的步骤。

您必须在不支持自动持久配置更改的本地实例上进行本地更改。有关更多信息,请参阅使用配置实例 dba.configureLocalInstance()

当针对远程实例(换句话说,当前运行 MySQL Shell 的实例以外的实例)运行时,如果该实例自动支持持久配置更改,则 AdminAPI 命令会将配置更改持久保存到实例的选项文件中mysql-auto.conf

如果远程实例不支持自动持久配置更改,则 AdminAPI 命令无法自动配置实例的选项文件。因此,AdminAPI 命令可以从实例中读取信息,例如显示当前配置。但对配置的更改无法持久保存到实例的选项文件中。在这种情况下,您需要在本地保存更改。有关更多信息,请参阅 使用配置实例 dba.configureLocalInstance()

6.3 检索处理程序对象

当您使用 AdminAPI 时,您使用代表 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 的处理程序对象。您可以将此对象分配给一个变量,然后使用可用的操作来监视和管理 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet。

要检索处理程序对象,请建立与属于 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 的活动实例之一的连接。例如,当您使用 创建集群时dba.createCluster(),该操作会返回一个Cluster可以分配给变量的对象。您可以使用此处理程序对象来处理集群。例如,添加实例或检查集群的状态。如果您想Cluster 在以后再次检索对象,例如在重新启动 MySQL Shell 后,请使用该 函数。例如,使用 JavaScript: dba.getCluster([*name*],[*options*])

mysql-js> var cluster1 = dba.getCluster()

或者使用Python:

mysql-py> cluster1 = dba.get_cluster()

要检索ClusterSet表示 InnoDB ClusterSet 部署的对象,请使用 dba.getClusterSet()*cluster*.getClusterSet() 函数。例如,使用 JavaScript:

mysql-js> myclusterset = dba.getClusterSet()

或者使用Python:

mysql-py> myclusterset = dba.get_cluster_set()

笔记

当您使用ClusterSet对象时,从中获取该对象的服务器实例必须在 InnoDB ClusterSet 中仍然在线。如果该服务器实例离线,该对象将不再工作,您需要从 InnoDB ClusterSet 中仍然在线的服务器再次获取它。

使用该dba.getReplicaSet()操作来检索ReplicaSet对象。例如,使用 JavaScript:

mysql-js> var replicaset1 = dba.getReplicaSet()

或者使用Python:

mysql-py> replicaset1 = dba.get_replica_set()

如果不指定 a*name*则返回默认对象。返回的对象使用一个新的会话,独立于 MySQL Shell 的全局会话。这确保了如果您更改 MySQL Shell 全局会话,ClusterClusterSetReplicaSet 对象仍会保持与服务器实例的会话。

默认情况下,当您检索处理程序时,MySQL Shell 会尝试连接到主实例。设置 connectToPrimary选项来配置此行为。

  • 如果connectToPrimary是, true并且活动的全局 MySQL Shell 会话不是主实例,则 MySQL Shell 会查询主实例。如果集群中没有仲裁,则操作失败。
  • 如果connectToPrimaryfalse,则检索的对象使用为活动会话指定的服务器实例,换句话说,与 MySQL Shell 的当前全局会话相同的实例。
  • 如果connectToPrimary未指定,MySQL Shell 将视为connectToPrimarytrue并回退 connectToPrimaryfalse

要强制连接到辅助实例,请建立到辅助实例的连接,并connectToPrimary 通过在 JavaScript 中发出以下命令来使用该选项:

mysql-js> shell.connect(secondary_member)
mysql-js> var cluster1 = dba.getCluster(testCluster, {connectToPrimary:false})

WARNING: You are connected to an instance in state 'Read Only'
Write operations on the InnoDB cluster will not be allowed.

<Cluster:testCluster>

或者,通过在 Python 中发出以下命令:

mysql-py> shell.connect(secondary_member)	
mysql-py> cluster1 = dba.get_cluster(testCluster, connectToPrimary='false')

WARNING: You are connected to an instance in state 'Read Only'
Write operations on the InnoDB cluster will not be allowed.

<Cluster:testCluster>

笔记

辅助实例具有 super_read_only=ON,因此您无法对其进行写入更改。

6.4 为 AdminAPI 创建用户帐户

SUPER用于配置和管理 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 部署中的成员服务器实例的用户帐户除了具有完整的 MySQL 管理员权限( 、GRANT OPTIONCREATEDROP) 之外,还必须对元数据表具有完整的读写权限。)。有关更多信息,请参阅 MySQL 提供的权限

为此,您可以使用root服务器上的帐户,但如果这样做,root 部署中每个成员服务器上的帐户必须具有相同的密码。root出于安全原因,不建议 使用该帐户。

dba.configureInstance() 相反,推荐的方法是使用 AdminAPI 的 JavaScript和 操作 来设置用户帐户*cluster.setupAdminAccount()* 。这些操作接受的用户名格式遵循标准 MySQL 帐户名格式,请参阅 指定帐户名

如果您希望设置用户帐户,则 手动配置 InnoDB 集群管理员帐户中列出了所需的权限。如果仅需要读取操作(例如出于监视目的),您可以使用具有更受限权限的帐户,如本主题中详细介绍的。

重要的

用于配置或管理 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 部署的每个帐户必须存在于部署中的所有成员服务器实例上,并且具有相同的用户名和密码。

服务器配置账户

要加入 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 部署的每个服务器实例上都需要一个服务器配置帐户。dba.configureInstance()您可以使用JavaScript 命令或 dba.configure_instance()Python 命令以及选项来设置此帐户 clusterAdmin

为了获得更好的安全性,请在交互式提示符处指定密码,否则使用 选项指定密码 clusterAdminPassword。在将成为部署一部分的每个服务器实例(您连接以创建部署的实例以及之后将加入的实例)上以相同的方式使用相同的用户名和密码创建相同的帐户。

您可以使用该选项定义密码过期时间 clusterAdminPasswordExpiration。此选项可以设置为天数、NEVER 永不过期,或者DEFAULT使用系统默认值。

clusterAdminCertIssuer如果您使用 SSL 证书进行身份验证,则可以分别使用和 选项 添加证书颁发者和主题 clusterAdminCertSubject

使用该 dba.configureInstance()操作 创建的服务器配置帐户不会复制到 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 部署中的其他服务器。MySQL Shell 禁用该 dba.configureInstance()操作的二进制日志记录。因此,您必须在每个服务器实例上单独创建帐户。

clusterAdmin选项必须与基于用户的 MySQL Shell 连接一起使用,该用户有权创建具有适当权限的用户。在此 JavaScript 示例中,使用 root 用户:

mysql-js> dba.configureInstance('root@ic-1:3306', {clusterAdmin: "'icadmin'@'ic-1%'"});

同样,在此 Python 示例中使用 root 用户:

mysql-py> dba.configure_instance('root@ic-1:3306', clusterAdmin="'icadmin'@'ic-1%'");

管理员帐户

完成配置过程后,管理员帐户可用于管理部署。您可以设置多个。要创建管理员帐户,请 *cluster*.setupAdminAccount() 在将所有实例添加到 InnoDB Cluster 或 InnoDB ReplicaSet 后发出 JavaScript 命令。或者发出 Python 命令: <Cluster>setup_admin_account()

该命令使用您指定的用户名和密码创建一个帐户,并具有所有必需的权限。用于创建帐户的事务 *cluster*.setupAdminAccount() 将写入二进制日志并发送到集群中的所有其他服务器实例以在其上创建帐户。

要使用该setupAdminAccount()操作,您必须以具有创建用户权限的 MySQL 用户身份连接,例如 root。该 操作还允许您在JavaScript 操作或Python 操作 之前升级现有 MySQL 帐户并具有必要的权限 。 setupAdminAccount(*user*)``dba.upgradeMetadata()``dba.upgrade_metadata()

强制*user参数是您要创建用于管理部署的 MySQL 帐户的名称。该操作接受的用户名格式setupAdminAccount()遵循标准 MySQL 帐户名格式。有关详细信息,请参阅指定帐户名称。用户参数格式是 可选的,如果未提供,则默认为通配符。 *username*[@*host*]host*%

例如,要 使用 JavaScript 创建一个名为*icadmin管理分配给变量的 InnoDB Cluster 的 用户,请发出:myCluster*

mysql-js> myCluster.setupAdminAccount('icadmin')

Missing the password for new account icadmin@%. Please provide one.
Password for new account: ********
Confirm password: ********

Creating user icadmin@%.
Setting user password.
Account icadmin@% was successfully created.

或者使用Python:

mysql-py> myCluster.setup_admin_account('icadmin')

Missing the password for new account icadmin@%. Please provide one.
Password for new account: ********
Confirm password: ********

Creating user icadmin@%.
Setting user password.
Account icadmin@% was successfully created.

从 MySQL Shell 8.0.33 开始,添加了以下选项 setupAdminAccount()

  • requireCertIssuer:帐户的可选 SSL 证书颁发者。
  • requireCertSubject:帐户的可选 SSL 证书主题。
  • passwordExpiration: numberOfDays | Never | Default:账户的密码有效期设置。

笔记

如果设置了requireCertIssuerrequireCertSubject,或者两者都设置了,则现有密码将变为可选。

更新旧帐户

如果您有使用 MySQL Shell 8.0.20 之前的版本创建的服务器配置帐户或管理员帐户,请使用该update选项和 setupAdminAccount()操作来升级现有用户的权限。这在升级期间是相关的,以确保用户帐户兼容。例如,要icadmin使用 JavaScript 升级名为 的用户,请发出:

mysql-js> myCluster.setupAdminAccount('icadmin', {'update':1})
Updating user icadmin@%.
Account icadmin@% was successfully updated.

或者使用Python:

mysql-py> myCluster.setup_admin_account('icadmin',update=1})
Updating user icadmin@%.
Account icadmin@% was successfully updated.

*cluster*.setupAdminAccount() 这是不写入二进制日志的命令 的特殊用途 。

6.4 为 AdminAPI 创建用户帐户

SUPER用于配置和管理 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 部署中的成员服务器实例的用户帐户除了具有完整的 MySQL 管理员权限( 、GRANT OPTIONCREATEDROP) 之外,还必须对元数据表具有完整的读写权限。)。有关更多信息,请参阅 MySQL 提供的权限

为此,您可以使用root服务器上的帐户,但如果这样做,root 部署中每个成员服务器上的帐户必须具有相同的密码。root出于安全原因,不建议 使用该帐户。

dba.configureInstance() 相反,推荐的方法是使用 AdminAPI 的 JavaScript和 操作 来设置用户帐户*cluster.setupAdminAccount()* 。这些操作接受的用户名格式遵循标准 MySQL 帐户名格式,请参阅 指定帐户名

如果您希望设置用户帐户,则 手动配置 InnoDB 集群管理员帐户中列出了所需的权限。如果仅需要读取操作(例如出于监视目的),您可以使用具有更受限权限的帐户,如本主题中详细介绍的。

重要的

用于配置或管理 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 部署的每个帐户必须存在于部署中的所有成员服务器实例上,并且具有相同的用户名和密码。

服务器配置账户

要加入 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 部署的每个服务器实例上都需要一个服务器配置帐户。dba.configureInstance()您可以使用JavaScript 命令或 dba.configure_instance()Python 命令以及选项来设置此帐户 clusterAdmin

为了获得更好的安全性,请在交互式提示符处指定密码,否则使用 选项指定密码 clusterAdminPassword。在将成为部署一部分的每个服务器实例(您连接以创建部署的实例以及之后将加入的实例)上以相同的方式使用相同的用户名和密码创建相同的帐户。

您可以使用该选项定义密码过期时间 clusterAdminPasswordExpiration。此选项可以设置为天数、NEVER 永不过期,或者DEFAULT使用系统默认值。

clusterAdminCertIssuer如果您使用 SSL 证书进行身份验证,则可以分别使用和 选项 添加证书颁发者和主题 clusterAdminCertSubject

使用该 dba.configureInstance()操作 创建的服务器配置帐户不会复制到 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 部署中的其他服务器。MySQL Shell 禁用该 dba.configureInstance()操作的二进制日志记录。因此,您必须在每个服务器实例上单独创建帐户。

clusterAdmin选项必须与基于用户的 MySQL Shell 连接一起使用,该用户有权创建具有适当权限的用户。在此 JavaScript 示例中,使用 root 用户:

mysql-js> dba.configureInstance('root@ic-1:3306', {clusterAdmin: "'icadmin'@'ic-1%'"});

同样,在此 Python 示例中使用 root 用户:

mysql-py> dba.configure_instance('root@ic-1:3306', clusterAdmin="'icadmin'@'ic-1%'");

管理员帐户

完成配置过程后,管理员帐户可用于管理部署。您可以设置多个。要创建管理员帐户,请 *cluster*.setupAdminAccount() 在将所有实例添加到 InnoDB Cluster 或 InnoDB ReplicaSet 后发出 JavaScript 命令。或者发出 Python 命令: <Cluster>setup_admin_account()

该命令使用您指定的用户名和密码创建一个帐户,并具有所有必需的权限。用于创建帐户的事务 *cluster*.setupAdminAccount() 将写入二进制日志并发送到集群中的所有其他服务器实例以在其上创建帐户。

要使用该setupAdminAccount()操作,您必须以具有创建用户权限的 MySQL 用户身份连接,例如 root。该 操作还允许您在JavaScript 操作或Python 操作 之前升级现有 MySQL 帐户并具有必要的权限 。 setupAdminAccount(*user*)``dba.upgradeMetadata()``dba.upgrade_metadata()

强制*user参数是您要创建用于管理部署的 MySQL 帐户的名称。该操作接受的用户名格式setupAdminAccount()遵循标准 MySQL 帐户名格式。有关详细信息,请参阅指定帐户名称。用户参数格式是 可选的,如果未提供,则默认为通配符。 *username*[@*host*]host*%

例如,要 使用 JavaScript 创建一个名为*icadmin管理分配给变量的 InnoDB Cluster 的 用户,请发出:myCluster*

mysql-js> myCluster.setupAdminAccount('icadmin')

Missing the password for new account icadmin@%. Please provide one.
Password for new account: ********
Confirm password: ********

Creating user icadmin@%.
Setting user password.
Account icadmin@% was successfully created.

或者使用Python:

mysql-py> myCluster.setup_admin_account('icadmin')

Missing the password for new account icadmin@%. Please provide one.
Password for new account: ********
Confirm password: ********

Creating user icadmin@%.
Setting user password.
Account icadmin@% was successfully created.

从 MySQL Shell 8.0.33 开始,添加了以下选项 setupAdminAccount()

  • requireCertIssuer:帐户的可选 SSL 证书颁发者。
  • requireCertSubject:帐户的可选 SSL 证书主题。
  • passwordExpiration: numberOfDays | Never | Default:账户的密码有效期设置。

笔记

如果设置了requireCertIssuerrequireCertSubject,或者两者都设置了,则现有密码将变为可选。

更新旧帐户

如果您有使用 MySQL Shell 8.0.20 之前的版本创建的服务器配置帐户或管理员帐户,请使用该update选项和 setupAdminAccount()操作来升级现有用户的权限。这在升级期间是相关的,以确保用户帐户兼容。例如,要icadmin使用 JavaScript 升级名为 的用户,请发出:

mysql-js> myCluster.setupAdminAccount('icadmin', {'update':1})
Updating user icadmin@%.
Account icadmin@% was successfully updated.

或者使用Python:

mysql-py> myCluster.setup_admin_account('icadmin',update=1})
Updating user icadmin@%.
Account icadmin@% was successfully updated.

*cluster*.setupAdminAccount() 这是不写入二进制日志的命令 的特殊用途 。

在进行生产部署时,为 MySQL Shell 配置详细日志记录可能会很有用。例如,日志中的信息可以帮助您查找并解决在准备服务器实例作为 InnoDB Cluster 的一部分工作时可能出现的任何问题。要以详细日志记录级别启动 MySQL Shell,请使用以下--log-level 选项:

$> mysqlsh --log-level=DEBUG3

DEBUG3推荐级别 。有关详细信息,请参阅--log-level。设置后,DEBUG3MySQL Shell 日志文件包含诸如Debug: execute_sql( ... )包含作为每个 AdminAPI 调用的一部分执行的 SQL 查询之类的行。MySQL Shell 生成的日志文件位于 ~/.mysqlsh/mysqlsh.log基于 Unix 的系统中;在 Microsoft Windows 系统上,它位于 %APPDATA%\MySQL\mysqlsh\mysqlsh.log. 有关更多信息,请参阅第 12 章,MySQL Shell 日志记录和调试

除了启用 MySQL Shell 日志级别之外,您还可以配置 AdminAPI 在发出每个命令后在 MySQL Shell 中提供的输出量。要启用 AdminAPI 输出量,请在 MySQL Shell 问题中:

mysql-js> dba.verbose=2

这可以实现 AdminAPI 调用的最大输出。可用的输出级别为:

  • 0 或关闭是默认值。这提供了最小的输出,并且是不进行故障排除时的推荐级别。
  • 1 或 ON 添加每次调用 AdminAPI 的详细输出。
  • 2 将调试输出添加到详细输出中,提供有关每次调用 AdminAPI 执行内容的完整信息。

MySQL Shell 可以选择记录 AdminAPI 操作使用的 SQL 语句(沙箱操作除外),并且还可以在执行时在终端中显示它们。有关更多信息,请参阅 第 12.5 节 “记录 AdminAPI 操作”

6.6 寻找主元

当您使用单主 InnoDB Cluster 或 InnoDB ReplicaSet 时,您需要连接到主实例来执行管理任务,以便将配置更改写入元数据。要查找当前的主要您可以:

  • 在 MySQL Shell 启动时使用该--redirect-primary 选项可确保目标服务器是 InnoDB Cluster 或 InnoDB ReplicaSet 的一部分。如果目标实例不是主实例,MySQL Shell 会找到主实例并连接到它。

  • 使用该 操作(在版本8.0.20中添加),该操作检查目标实例是否属于集群或ReplicaSet。如果是这样,MySQL Shell 将打开一个到主数据库的新会话,将活动的全局 MySQL Shell 会话设置为已建立的会话并返回它。 shell.connectToPrimary([*instance*, *password*])

    如果*instance未提供,操作将尝试使用活动的全局 MySQL Shell 会话。如果instance*未提供并且没有活动的全局 MySQL Shell 会话,则会引发异常。如果目标实例不属于集群或 ReplicaSet,则操作将失败并出现错误。

  • 使用状态操作,在结果中找到主实例,然后手动连接到该实例。

6.7 编写 AdminAPI 脚本

除了本节中说明的交互模式外,MySQL Shell 还支持以 批处理模式运行脚本。这使您能够使用 AdminAPI 以及用 JavaScript 或 Python 编写的脚本来自动化流程,这些脚本可以使用 MySQL Shell 的选项运行--file 。例如:

$> mysqlsh --file setup-innodb-cluster.js

笔记

脚本文件名后指定的任何命令行选项都会传递给脚本,而不是传递给 MySQL Shell。您可以使用 os.argvJavaScript 中的数组或 sys.argvPython 中的数组来访问这些选项。在这两种情况下,数组中选取的第一个选项是脚本名称。

此处显示了使用 JavaScript 的示例脚本文件的内容:

print('InnoDB Cluster sandbox set up\n'); print('==================================\n'); print('Setting up a MySQL InnoDB Cluster with 3 MySQL Server sandbox instances,\n'); print('installed in ~/mysql-sandboxes, running on ports 3310, 3320 and 3330.\n\n'); var dbPass = shell.prompt('Please enter a password for the MySQL root account: ', {type:"password"}); try { print('\nDeploying the sandbox instances.'); dba.deploySandboxInstance(3310, {password: dbPass}); print('.'); dba.deploySandboxInstance(3320, {password: dbPass}); print('.'); dba.deploySandboxInstance(3330, {password: dbPass}); print('.\nSandbox instances deployed successfully.\n\n'); print('Setting up InnoDB Cluster...\n'); shell.connect('root@localhost:3310', dbPass); var cluster = dba.createCluster("prodCluster"); print('Adding instances to the Cluster.'); cluster.addInstance({user: "root", host: "localhost", port: 3320, password: dbPass}); print('.'); cluster.addInstance({user: "root", host: "localhost", port: 3330, password: dbPass}); print('.\nInstances successfully added to the Cluster.'); print('\nInnoDB Cluster deployed successfully.\n'); } catch(e) { print('\nThe InnoDB Cluster could not be created.\n\nError: ' + + e.message + '\n'); }

或者使用Python:

print('InnoDB Cluster sandbox set up\n');
print('==================================\n');
print('Setting up a MySQL InnoDB Cluster with 3 MySQL Server sandbox instances,\n');
print('installed in ~/mysql-sandboxes, running on ports 3310, 3320 and 3330.\n\n');

dbPass = shell.prompt('Please enter a password for the MySQL root account: ', type ="password");

try:
       print('\nDeploying the sandbox instances.');
       dba.deploy_sandbox_instance(3310, password = dbPass);
       print('.');
       dba.deploy_sandbox_instance(3320, password = dbPass);
       print('.');
       dba.deploy_sandbox_instance(3330, password = dbPass);
       print('.\nSandbox instances deployed successfully.\n\n');

       print('Setting up InnoDB Cluster...\n');
       shell.connect('root@localhost:3310', dbPass);

       cluster = dba.create_cluster("prodCluster");

       print('Adding instances to the Cluster.');
       cluster.add_instance('root@localhost:3320', password = dbPass);
       print('.');
       cluster.add_instance('root@localhost:3330', password = dbPass);
       print('.\nInstances successfully added to the Cluster.');

       print('\nInnoDB Cluster deployed successfully.\n');

except ValueError:
       print('\nThe InnoDB Cluster could not be created.\n\nError.\n');

AdminAPI MySQL Shell 命令行集成

MySQL Shell 的第 5.8 节“API 命令行集成” 也支持 AdminAPI 。此命令行集成使您能够轻松地将 AdminAPI 集成到您的环境中。例如,要使用监听端口 1234 的沙箱实例检查 InnoDB Cluster 的状态:

$ mysqlsh root@localhost:1234 -- cluster status

这映射到 MySQL Shell 中的等效命令:

mysql-js> cluster.status()

6.8 AdminAPI MySQL 沙箱

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

重要的

沙箱实例仅适合在本地计算机上部署和运行以用于测试目的。在生产环境中,MySQL Server 实例部署到网络上的各种主机上。有关更多信息,请参阅 第 7.4 节 “部署生产 InnoDB 集群”

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

6.8.1 部署沙箱实例

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

mysql-js> dba.deploySandboxInstance(3310)

默认情况下,沙箱创建在 Unix 系统上指定的目录中。对于 Microsoft Windows 系统,该目录是 . 每个沙箱实例都存储在以 . $HOME/mysql-sandboxes/*port*``%userprofile%\MySQL\mysql-sandboxes\*port*port_number

系统会提示输入实例的根用户密码。

重要的

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

要部署另一个沙箱服务器实例,请对端口 3310 处的沙箱实例重复执行以下步骤,为每个实例选择不同的端口号。

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

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

然后,针对在 中找到的实例执行所有后续与沙箱相关的操作 /home/user/sandbox1

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

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

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

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

  • allowRootFrom配置 root 用户可以从哪个主机进行连接。默认为 root@%.
  • ignoreSslError在沙盒实例上配置安全连接。当 ignoreSslError为 true 时(默认情况下),如果无法提供 SSL 支持并且在不支持 SSL 的情况下部署服务器实例,则在操作期间不会发出错误。当 ignoreSslError设置为 时 false,沙盒实例将部署为支持 SSL,如果无法配置 SSL 支持,则会发出错误。
  • mysqldOptions在沙箱实例上配置其他选项。默认为空字符串,并接受指定选项和值的字符串列表。例如mysqldOptions: ["lower_case_table_names=1", "report_host="10.1.2.3"]}。指定的选项将写入沙箱实例的选项文件中。
  • portX配置用于 X 协议连接的端口。默认值乘以 10 计算。port该值是 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.kill_sandbox_instance(*instance*)
  • 要使用 JavaScript 删除沙箱实例,请发出: 。这将从您的文件系统中完全删除沙箱实例。 dba.deleteSandboxInstance(*instance*)
  • 要使用 Python 删除沙箱实例,请发出: 。这将从您的文件系统中完全删除沙箱实例。 dba.delete_SandboxInstance(*instance*)

沙盒实例被认为是暂时的,不适合生产使用。因此,它们不支持版本升级。在沙箱部署中,每个沙箱实例都使用本地 目录中找到的mysqld二进制文件的副本。如果mysqld的版本 发生变化,例如升级后,基于先前版本的沙箱将无法启动。这是因为与 . $PATH``mysql-sandboxesbasedir

如果您确实想在升级后保留沙箱实例,解决方法是手动将升级后的 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 集群,完成以下任务。

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

该示例包含以下部分:

警告

沙箱实例仅适合在本地计算机上部署和运行以用于测试目的。

安装

安装以下组件:

创建InnoDB集群沙箱配置

为了提供对一次故障的容忍度,请创建一个包含三个实例的 InnoDB 集群。在此示例中,我们将使用在同一台计算机上运行的三个沙箱实例。在实际设置中,这三个实例将在网络上的不同主机上运行。

  1. 要启动 MySQL Shell,请发出:

    > mysqlsh
    
  2. 要创建并启动 MySQL 沙箱实例,请使用 dba.deploySandboxInstance()X AdminAPI 中的函数。在 MySQL Shell 中发出以下三个语句并输入每个实例的 root 密码:

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

    笔记

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

创建InnoDB集群

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

  1. 通过发出以下命令连接到您想要成为 InnoDB Cluster 中主实例的 MySQL 实例:

    mysql-js> shell.connect('root@localhost:3310')
    
  2. 发出dba.createCluster()命令创建 Cluster,并使用分配的变量 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.status()使用带有指定变量的函数 来验证创建是否成功 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. 集群已启动并正在运行,但尚不能容忍故障。使用以下函数将另一个 MySQL Server 实例添加到集群中<Cluster>.addInstance()

    { 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. 从提示中选择恢复方法。选项有:

    • ****克隆****:克隆您要添加到主集群的实例,删除该实例包含的所有事务。MySQL 克隆插件会自动安装。假设您要添加空实例(未处理任何事务)或包含您不希望保留的事务的实例,请选择克隆选项。
    • ****增量恢复****:使用异步复制将集群处理的所有事务恢复到加入实例。如果您确定集群处理过的所有更新都是在启用全局事务 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.
    
  6. 添加创建的第三个实例,并再次选择 ****C****作为克隆恢复方法:

    mysql-js> cluster.addInstance('root@localhost:3330')
    
  7. 通过发出以下命令检查集群的状态:

    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!
  8. 集群现在最多可以容忍一次故障。通过发出以下命令退出 MySQL Shell:\q

引导 MySQL 路由器

MySQL InnoDB Cluster搭建完成后,测试Cluster的高可用性。为此,请使用 MySQL Router。如果一个实例发生故障,MySQL Router 会自动更新其路由配置,并确保新连接路由到其余实例。

在 MySQL Router 执行路由操作之前,请使其了解新的 InnoDB Cluster。为此,请使用该 –bootstrap选项并将 MySQL Router 指向R/W集群的当前 MySQL Server 实例(主实例)。将路由器的配置存储在mysql-router使用该 -d选项调用的文件夹中。

  1. 在您的主目录中打开终端:

    • 在 Linux 系统上,发出:

      [demo-user@losthost]$> mysqlrouter --bootstrap root@localhost:3310 -d mysqlrouter
      
    • 在 Windows 系统上,发出:

      C:\Users\demo-user> mysqlrouter --bootstrap root@localhost:3310 -d mysql-router
      

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

  2. 成功配置 MySQL Router 后,在后台线程中启动它:

    • 在 Windows 系统上,使用start /B 命令并将路由器指向使用以下 –bootstrap选项生成的配置文件:

      C:\> start /B mysqlrouter -c %HOMEPATH%\mysql-router\mysqlrouter.conf
      
    • 或者调用之前创建的文件夹 Windows PowerShell中的脚本:mysqlrouter

      \mysqlrouter\start.ps1
      
    • 在使用systemd 的 Linux 系统上 ,发出:

      sudo systemctl start mysqlrouter.service
      
    • 或者在 Linux 系统上,调用之前创建的文件夹 Shell 中的脚本:mysqlrouter

      /mysqlrouter/start.sh
      

测试 MySQL 路由器配置

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

不要直接连接到 MySQL 服务器实例之一,而是通过 MySQL 路由器进行连接。

  1. 发出以下连接命令:

    > mysqlsh root@localhost:6446
    
  2. 提供 root 密码以连接到 InnoDB 集群。

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

    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-js> \js
    
  7. 使用该dba.killSandboxInstance()函数 停止MySQL Server 实例:

                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-sql> SELECT @@port;
    +--------+
    | @@port |
    +--------+
    |   3320 |
    +--------+
    
  11. 此输出显示在端口 3320 上运行的实例已提升为新的Read/Write主实例。

  12. 返回JavaScript模式,查看Cluster状态:

    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. 所有实例均已恢复在线,并且集群可以再次容忍一次故障。

6.9 标记元数据

从版本 8.0.21 开始,可配置的标记框架可用于允许使用附加信息标记 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 的元数据。标签使将自定义键值对与 Cluster、ReplicaSet 或实例相关联成为可能。标签已保留供 MySQL Router 使用,使兼容的 MySQL Router 能够支持对应用程序隐藏实例。为此目的保留以下标签:

  • _hidden指示 MySQL Router:从客户端应用程序的可能目标列表中排除该实例。
  • _disconnect_existing_sessions_when_hidden:指示路由器断开与标记为隐藏的实例的现有连接。

有关更多信息,请参阅 从路由中删除实例

此外,标签框架是用户可配置的。自定义标签可以由任何 ASCII 字符组成,并提供 namespace,它充当可以与 Cluster、ReplicaSet 或其特定实例关联的字典键值对。标签值可以是任何 JSON 值。此配置使您能够在元数据之上添加自己的属性。

显示标签

*Cluster*.options() 操作显示有关分配给各个集群实例以及集群本身的标签的信息。例如,分配给的 InnoDB Cluster myCluster可以显示:

mysql-js> myCluster.options()
{
    "cluster": {
        "name": "test1",
        "tags": {
            "ic-1:3306": [
                {
                    "option": "_disconnect_existing_sessions_when_hidden",
                    "value": true
                },
                {
                    "option": "_hidden",
                    "value": false
                }
            ],
            "ic-2:3306": [],
            "ic-3:3306": [],
            "global": [
                {
                    "option": "location:",
                    "value": "US East"
                }
            ]
        }
    }
}

该集群有一个名为 的全局标签location ,其值为US East,并且实例 ic-1已被标记。

在集群实例上设置标签

您可以在实例级别设置标签,例如,这使您可以将实例标记为不可用,以便应用程序和路由器将其视为离线。使用该 操作设置实例的标签值。 *Cluster*.setInstanceOption(*instance*, *option*, *value*)

参数*instance*是目标实例的连接字符串。参数 option必须是格式为 的字符串 。该参数是应分配给指定的 值。如果值为 ,则从指定中删除。对于属于集群的实例,该 操作仅接受命名空间。任何其他命名空间都会生成. *namespace*:*option*valueoption``namespace``null``option``namespace``setInstanceOption()``tag``ArgumentError

例如,要使用 JavaScript 将标签设置 *test*为true实例,请发出 myClusteric-1

mysql-js> myCluster.setInstanceOption("icadmin@ic-1:3306", "tag:test", true);

或者使用Python 将标签设置*test* 为true实例 ,发出: myClusteric-1

mysql-py> myCluster.set_instance_option("icadmin@ic-1:3306", "tag:test", True);

从路由中删除实例

当 AdminAPI 和 MySQL Router 一起工作时,它们支持特定的标签,使您能够将实例标记为隐藏并将它们从路由中删除。然后,MySQL Router 会从路由目标候选列表中排除此类标记的实例。此功能使您能够安全地将服务器实例脱机,以便应用程序和 MySQL Router 忽略它。例如,当您执行维护任务(例如服务器升级或配置更改)时。

当该_hidden标签设置为 true 时,这会指示 MySQL Router 从客户端应用程序的可能目标列表中排除该实例。该实例保持在线状态,但不会路由到新的传入连接。该 _disconnect_existing_sessions_when_hidden标签控制如何关闭与实例的现有连接。假定此标记为 true,并且它指示针对 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 引导的任何 MySQL Router 实例在标记为 true 时断开与实例的任何现有连接 _hidden

_disconnect_existing_sessions_when_hidden为 false 时,如果为 true,则不会关闭与实例的任何现有客户端连接_hidden。保留 _hidden_disconnect_existing_sessions_when_hidden 标签特定于实例,不能在集群级别使用。

警告

use_gr_notifications 启用 MySQL Router 选项时,默认为 60 秒。这意味着当您设置标签时,MySQL Router 最多需要 60 秒才能检测到更改。要减少等待时间,请更改 use_gr_notifications为较低的值。

例如,假设您想要 从路由目标ic-1中删除分配给 InnoDB 集群的实例。myCluster使用 setInstanceOption()JavaScript 操作启用_hidden_disconnect_existing_sessions_when_hidden 标签:

mysql-js> myCluster.setInstanceOption("icadmin@ic-1:3306", "tag:_hidden", true);

或者使用set_instance_option()Python操作启用_hiddenand _disconnect_existing_sessions_when_hidden 标签:

			mysql-js> myCluster.set_instance_option("icadmin@ic-1:3306", "tag:_hidden", true);

您可以通过检查选项来验证元数据中的更改。例如,所做的更改ic-1 将在选项中显示为:

mysql-js> myCluster.options()
{
    "cluster": {
        "name": "test1",
        "tags": {
            "ic-1:3306": [
                {
                    "option": "_disconnect_existing_sessions_when_hidden",
                    "value": true
                },
                {
                    "option": "_hidden",
                    "value": true
                }
            ],
            "ic-2:3306": [],
            "ic-3:3306": [],
            "global": []
        }
    }
}

您可以通过查看日志文件来验证 MySQL Router 是否已检测到元数据中的更改。检测到所做更改的 MySQL 路由器ic-1将显示如下更改:

2020-07-03 16:32:16 metadata_cache INFO [7fa9d164c700] Potential changes detected in cluster 'testCluster' after metadata refresh
2020-07-03 16:32:16 metadata_cache INFO [7fa9d164c700] view_id = 4, (3 members)
2020-07-03 16:32:16 metadata_cache INFO [7fa9d164c700]     ic-1:3306 / 33060 - mode=RW
2020-07-03 16:32:16 metadata_cache INFO [7fa9d164c700]     ic-1:3306 / 33060 - mode=RO
2020-07-03 16:32:16 metadata_cache INFO [7fa9d164c700]     ic-1:3306 / 33060 - mode=RO hidden=yes disconnect_when_hidden=yes
2020-07-03 16:32:16 routing INFO [7fa9d164c700] Routing routing:testCluster_x_ro listening on 64470 got request to disconnect invalid connections: metadata change
2020-07-03 16:32:16 routing INFO [7fa9d164c700] Routing routing:testCluster_x_rw listening on 64460 got request to disconnect invalid connections: metadata change
2020-07-03 16:32:16 routing INFO [7fa9d164c700] Routing routing:testCluster_rw listening on 6446 got request to disconnect invalid connections: metadata change
2020-07-03 16:32:16 routing INFO [7fa9d164c700] Routing routing:testCluster_ro listening on 6447 got request to disconnect invalid connections: metadata change

要使实例重新上线,请使用 setInstanceOption()删除标签的操作,MySQL Router 会自动将实例添加回路由目的地,并且它会针对应用程序重新上线。例如:

mysql-js> myCluster.setInstanceOption(icadmin@ic-1:3306, "tag:_hidden", false);

通过再次检查选项来验证元数据的更改:

mysql-js> myCluster.options()
{
    "cluster": {
        "name": "test1",
        "tags": {
            "ic-1:3306": [
                {
                    "option": "_disconnect_existing_sessions_when_hidden",
                    "value": true
                },
                {
                    "option": "_hidden",
                    "value": false
                }
            ],
            "ic-2:3306": [],
            "ic-3:3306": [],
            "global": []
        }
    }
}

从 8.0.32 开始,您还可以使用以下命令输出中的 _hidden 属性查看成员的状态 :hiddenFromRouter

  • *Cluster*.status()
  • *Cluster*.describe()
  • *ReplicaSet*.status()

此属性适用true于使用元数据标记对 MySQL 路由器流量隐藏的任何成员_hidden

设置集群标签

该 操作使您能够更改整个集群的命名空间选项的值。参数必须是格式为 的字符串 。 *Cluster*.setOption(*option*, *value*)option*namespace*:*option*

该*value*参数是要option在指定的 namespace. 如果值为 null,则从option指定中删除namespace。对于集群,该setOption()操作接受tag命名空间。任何其他命名空间都会生成ArgumentError.

提示

在集群级别设置的标签不会覆盖在实例级别设置的标签。您不能用于 *Cluster*.setOption() 删除在实例级别设置的所有标签。

不要求所有实例都在线,只要集群有仲裁即可。要将分配给的 InnoDB 集群 myCluster标记 location为美国东部,请在 JavaScript 中发出以下命令:

mysql-js> myCluster.setOption("tag:location", "US East")
mysql-js> myCluster.options()
{
    "cluster": {
        "name": "test1",
        "tags": {
            "ic-1:3306": [],
            "ic-2:3306": [],
            "ic-3:3306": [],
            "global": [
                {
                    "option": "location:",
                    "value": "US East"
                }
            ]
        }
    }
}

或者在 Python 中发出以下命令:

mysql-py> myCluster.set_option("tag:location", "US East")
mysql-pys> myCluster.options()
{
    "cluster": {
        "name": "test1",
        "tags": {
            "ic-1:3306": [],
            "ic-2:3306": [],
            "ic-3:3306": [],
            "global": [
                {
                    "option": "location:",
                    "value": "US East"
                }
            ]
        }
    }
}

从集群中删除标签

要从集群中删除标签,请使用 带有 JavaScript 中的值和 Python 中的值的操作。 *Cluster*.setOption(*option*, *value*)``null``None

myCluster要从分配给该 标签 的 InnoDB Cluster 中删除该标签 location,请在 JavaScript 中发出以下命令:

mysql-js> myCluster.setOption("tag:location", null)

或者使用Python:

mysql-js> myCluster.set_option("tag:location", None)

用户定义的标签

AdminAPI 支持tag命名空间,您可以在其中存储与给定 Cluster、ReplicaSet 或实例关联的键值对中的信息。命名空间下的选项 tag不受限制,这意味着您可以使用您选择的任何信息进行标记,只要它是有效的 MySQL ASCII 标识符即可。

您可以使用标签的任何名称和值,只要名称遵循以下语法:_ 或字母后跟字母数字和 _ 字符。

namespace选项是一个冒号分隔的字符串,格式为namespace:option,其中namespace是命名空间的名称,option是实际的选项名称。您可以在实例级别、集群或副本集级别设置和删除标签。

标记名称可以具有任何值,只要它以字母或下划线开头,可以选择后跟字母数字和 _字符,例如 ^[a-zA-Z_][0-9a-zA-Z_]*。仅允许内置标签以下划线_ 字符开头。

如何使用自定义标签取决于您。您可以在集群上设置自定义标签来标记集群的位置。EMEA例如,在集群上 设置一个名为 location 且值为 的自定义标签 。

6.10 将 MySQL Router 与 AdminAPI、InnoDB Cluster 和 InnoDB ReplicaSet 一起使用

本节介绍如何将MySQL Router与InnoDB Cluster和InnoDB ReplicaSet集成。有关将 MySQL Router 与 InnoDB ClusterSet 集成的说明,请参阅 第 8.5 节 “将 MySQL Router 与 InnoDB ClusterSet 集成”

有关 MySQL Router 的背景信息,请参阅 MySQL Router 8.0

6.10.1 引导 MySQL 路由器

您可以针对 InnoDB ReplicaSet 或 InnoDB Cluster 引导 MySQL Router 以自动配置路由。bootstrap进程是运行MySQL Router的一种特定方式,它不会启动通常的路由,而是 mysqlrouter.conf根据元数据配置文件。

要在命令行引导 MySQL Router,请 --bootstrap在启动mysqlrouter命令时传入选项,它会从元数据中检索拓扑信息并配置到服务器实例的路由连接。或者,在 Windows 上使用 MySQL 安装程序来引导 MySQL 路由器。有关更多信息,请参阅 使用 MySQL 安装程序配置 MySQL 路由器

一旦 MySQL Router 启动,客户端应用程序就会连接到它发布的端口。MySQL Router 根据传入端口自动将客户端连接重定向到实例,例如使用 read-write经典 MySQL 协议的连接默认使用 6646。

如果拓扑发生变化,例如实例意外故障,MySQL Router 会检测到变化并自动调整到其余实例的路由。这种自动调整消除了客户端应用程序处理故障转移或了解底层拓扑的需要。有关更多信息,请参阅 MySQL InnoDB 集群的路由

笔记

不要尝试手动配置 MySQL Router 以重定向到服务器实例。始终使用该 --bootstrap选项,因为这可以确保 MySQL Router 从元数据中获取其配置。请参阅集群元数据和状态

6.10.2 配置MySQL路由器用户

当 MySQL Router 连接到 Cluster、ClusterSet 或 ReplicaSet 时,它需要具有正确权限的用户帐户。从 MySQL Router 版本 8.0.19 开始,可以使用该--account选项指定此内部用户。在以前的版本中,MySQL Router 在集群的每次引导时创建内部帐户,这可能会导致随着时间的推移建立许多帐户。从 MySQL Shell 版本 8.0.20 开始,您可以使用 AdminAPI 设置 MySQL Router 所需的用户帐户。

使用该setupRouterAccount(user, [options]) 操作创建MySQL用户帐户或升级现有帐户,以便MySQL Router可以使用该帐户对InnoDB Cluster或InnoDB ReplicaSet进行操作。这是使用 InnoDB Cluster 和 InnoDB ReplicaSet 配置 MySQL Router 的推荐方法。

*myRouter1*要添加一个名为变量引用的 InnoDB Cluster 的 新 MySQL Router 帐户 testCluster,请执行以下命令:

mysqlsh> testCluster.setupRouterAccount('myRouter1')

在这种情况下,未指定域,因此使用通配符 ( ) 字符创建帐户%,这确保创建的用户可以从任何域进行连接。要将帐户限制为只能从 *example.com*JavaScript 中的域进行连接,请发出:

mysql-js> testCluster.setupRouterAccount('myRouter1@example.com')

或者使用Python:

mysql-py> testCluster.setup_router_account('myRouter1@example.com')

该操作会提示输入密码,然后为 MySQL Router 用户设置正确的权限。如果InnoDB Cluster或InnoDB ReplicaSet有多个实例,则创建的MySQL Router用户将传播到所有实例。

当您已经配置了MySQL Router用户时,例如您使用的是8.0.20之前的版本,您可以使用该 setupRouterAccount()操作重新配置现有用户。在本例中,传入 update设置为 true 的选项。例如,要重新配置*myOldRouter*用户,请在 JavaScript 中发出以下命令:

mysql-js> testCluster.setupRouterAccount('myOldRouter', {'update':1})

或者使用Python:

mysql-py> testCluster.setup_router_account('myOldRouter', {'update':1})

从 MySQL Shell 8.0.33 开始,支持 SSL 证书。添加了以下选项 setupRouterAccount()

  • requireCertIssuer:帐户的可选 SSL 证书颁发者。

  • requireCertSubject:帐户的可选 SSL 证书主题。

  • passwordExpiration: numberOfDays | Never | Default:账户的密码有效期设置。

    • numberOfDays:密码过期前的天数。

    • Never:密码永不过期。

    • Default:使用系统默认值。

      6.10.3 部署MySQL路由器

      建议将 MySQL Router 部署在与应用程序相同的主机上。使用沙箱部署时,所有内容都在单个主机上运行。因此,您将 MySQL Router 部署到同一主机。使用生产部署时,我们建议将一个 MySQL Router 实例部署到用于托管客户端应用程序之一的每台计算机。还可以将 MySQL Router 部署到应用程序实例连接的公用计算机上。有关更多信息,请参阅 安装 MySQL 路由器

      要基于 InnoDB Cluster 或 InnoDB ReplicaSet 引导 MySQL Router,您需要指向在线实例的类似 URI 的连接字符串。运行mysqlrouter 命令并提供 选项,其中是指向在线实例的类似 URI 的连接字符串。MySQL Router 连接到实例并使用附带的元数据缓存插件来检索元数据,其中包含服务器实例地址及其角色的列表。例如: --bootstrap=*instance*instance

      $> mysqlrouter --bootstrap icadmin@ic-1:3306 --account=mysqlrouter
      

      系统会提示您输入 MySQL Router 使用的实例密码和加密密钥。该密钥用于加密 MySQL Router 用于连接集群的实例密码。还会显示可用于客户端连接的端口。有关其他引导相关选项,请参阅 引导选项

      提示

      此时 MySQL Router 尚未启动,因此无法路由连接。引导是一个单独的过程。

      MySQL Router 引导进程创建一个 mysqlrouter.conf文件,其中的设置基于从传递给选项的地址检索到的元数据( --bootstrap在上面的示例中icadmin@ic-1:3306)。根据检索到的元数据,MySQL Router 自动配置文件 mysqlrouter.conf,包括一个 metadata_cache部分。

      如果您使用 MySQL Router 8.0.14 及更高版本,该 --bootstrap选项会自动将 MySQL Router 配置为在配置的路径中跟踪和存储活动 MySQL 元数据服务器地址 dynamic_state。这确保了当 MySQL Router 重新启动时,它知道哪些 MySQL 元数据服务器地址是当前的。有关更多信息,请参阅 dynamic_state文档。

      在早期的 MySQL Router 版本中,元数据服务器信息是在 MySQL Router 的初始引导操作期间定义的,并静态存储在 bootstrap_server_addresses 配置文件中,其中包含集群中所有服务器实例的地址。例如:

      [metadata_cache:prodCluster] router_id=1 bootstrap_server_addresses=mysql://icadmin@ic-1:3306,mysql://icadmin@ic-2:3306,mysql://icadmin@ic-3:3306 user=mysql_router1_jy95yozko3k2 metadata_cluster=prodCluster ttl=300

      提示

      如果使用 MySQL Router 8.0.13 或更早版本,当您在引导 MySQL Router 后通过添加另一个服务器实例来更改集群的拓扑时,您需要根据更新的 bootstrap_server_addresses 元数据进行更新。使用该--bootstrap选项重新启动 MySQL Router,或者手动编辑 bootstrap_server_addresses 该文件的部分mysqlrouter.conf并重新启动 MySQL Router。

      生成的 MySQL 路由器配置会创建用于连接到集群的 TCP 端口。默认情况下,会创建使用经典 MySQL 协议和 X 协议与集群通信的端口。要使用 X 协议,服务器实例必须安装并配置 X 插件,这是 MySQL 8.0 及更高版本的默认设置。默认可用的 TCP 端口是:

      • 6446- 对于经典 MySQL 协议读写会话,MySQL 路由器将传入连接重定向到主服务器实例。
      • 6447- 对于经典 MySQL 协议只读会话,MySQL 路由器将传入连接重定向到辅助服务器实例之一。
      • 64460- 对于 X 协议读写会话,MySQL 路由器将传入连接重定向到主服务器实例。
      • 64470- 对于 X 协议只读会话,MySQL 路由器将传入连接重定向到辅助服务器实例之一。

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

      传入连接的重定向方式取决于所使用的底层拓扑。例如,当使用单主集群时,默认情况下 MySQL Router 会发布 X 协议和经典 MySQL 协议端口,客户端连接到该端口进行读写会话,并重定向到集群的单主集群。对于多主集群,读写会话会以循环方式重定向到主实例之一。例如,到端口 6446 的第一个连接被重定向到 ic-1 实例。到端口 6446 的第二个连接被重定向到 ic-2 实例,依此类推。

      对于传入的只读连接,MySQL Router 也会以循环方式将连接重定向到辅助实例之一。要修改此行为,请参阅该 routing_strategy选项。

      引导并配置后,启动 MySQL Router。如果您使用带有该 --bootstrap选项的系统范围安装,则发出:

      $> mysqlrouter &
      

      如果您使用该 --directory选项将 MySQL Router 安装到某个目录,请使用 start.sh在您安装的目录中找到的脚本。

      或者设置一个服务以在系统启动时自动启动 MySQL Router,请参阅 启动 MySQL Router。现在,您可以将 MySQL 客户端(例如 MySQL Shell)连接到传入的 MySQL 路由器端口之一(如上所述),并查看客户端如何透明地连接到服务器实例之一。

      $> mysqlsh --uri root@localhost:6442
      

      要验证您连接到哪个实例,请针对port状态变量发出 SQL 查询。例如:

      mysql-js> \sql
      Switching to SQL mode... Commands end with ;
      mysql-sql> select @@port;
      +--------+
      | @@port |
      +--------+
      |   3310 |
      +--------+
      

      或者,例如,使用:

      mysql-js> \sql
      Switching to SQL mode... Commands end with ;
      mysql-sql> SHOW VARIABLES WHERE Variable_name = 'port';
      +--------+
      | @@port |
      +--------+
      |   3310 |
      +--------+
      

      6.10.4 将 ReplicaSet 与 MySQL Router 一起使用

      您可以使用 MySQL Router 8.0.19 及更高版本来针对 InnoDB ReplicaSet 进行引导。有关更多信息,请参阅 第 6.10 节 “将 MySQL Router 与 AdminAPI、InnoDB Cluster 和 InnoDB ReplicaSet 一起使用”。生成的 MySQL Router 配置文件的唯一区别是添加了该cluster_type 选项。当 MySQL Router 针对 ReplicaSet 进行引导时,生成的配置文件包括:

      cluster_type=rs
      

      当您将 MySQL Router 与 InnoDB ReplicaSet 一起使用时,请注意:

      • MySQL Router 的读写端口将客户端连接定向到 ReplicaSet 的主实例。
      • MySQL Router 的只读端口将客户端连接定向到 ReplicaSet 的辅助实例,尽管它也可以将它们定向到主实例。
      • MySQL Router 从主实例获取有关 ReplicaSet 拓扑的信息。
      • 当主实例不可用并且升级不同的实例时,MySQL Router 会自动恢复。

      您可以使用与 InnoDB Cluster 相同的方式使用针对 ReplicaSet 引导的 MySQL Router 实例。有关 *ReplicaSet*.listRouters() 和 的更多信息*ReplicaSet*.removeRouterMetadata(),请参阅第 6.10.6 节 “使用集群路由器”

      6.10.5 测试InnoDB集群高可用

      要测试 InnoDB Cluster 高可用性是否有效,请通过终止实例来模拟意外停止。集群检测到实例离开集群并重新配置自身。集群如何重新配置自身取决于您使用的是单主集群还是多主集群,以及实例在集群中扮演的角色。

      在单主模式下:

      • 如果当前主实例离开集群,则辅助实例之一将被选为新的主实例,实例按最低优先级排列 server_uuid。MySQL Router 将读写连接重定向到新选出的主节点。
      • 如果当前辅助节点离开集群,MySQL Router 会停止将只读连接重定向到该实例。

      有关详细信息,请参阅 单主模式

      在多主模式下:

      • 如果当前的“R/W”实例离开集群,MySQL Router 会将读写连接重定向到其他主实例。如果离开的实例是集群中的最后一个主实例,则集群完全消失,您无法连接到任何 MySQL 路由器端口。

      有关详细信息,请参阅 多主模式

      dba.killSandboxInstance()有多种方法可以模拟实例离开集群,例如,您可以强制停止实例上的 MySQL 服务器,或者在测试沙箱部署时 使用 AdminAPI 。在此示例中,有一个包含三个服务器实例的单主沙箱集群部署,并且侦听端口 3310 的实例是当前的主实例。实例意外离开集群,由 killing实例模拟:

      例如,通过发出 JavaScript 命令:

      mysql-js> dba.killSandboxInstance(3310)
      

      或者,通过发出 Python 命令:

      mysql-py> dba.kill_sandbox_instance(3310)
      

      集群检测到更改并自动选择新的主节点。

      假设您的会话连接到端口 6446(默认的读写经典 MySQL 协议端口),MySQL Router 应该检测到集群拓扑的更改,并将您的会话重定向到新选举的主节点。要验证这一点,请使用命令在 MySQL Shell 中切换到 SQL 模式\sql,然后选择实例的port 变量以检查您的会话已重定向到哪个实例。

      第一条SELECT语句失败,因为与原始主数据库的连接丢失,这意味着当前会话已关闭。MySQL Shell 会自动为您重新连接,当您再次发出命令时,新端口将得到确认。

      mysql-js> \sql
      Switching to SQL mode... Commands end with ;
      mysql-sql> SELECT @@port;
      ERROR: 2013 (HY000): Lost connection to MySQL server during query
      The global session got disconnected.
      Attempting to reconnect to 'root@localhost:6446'...
      The global session was successfully reconnected.
      mysql-sql> SELECT @@port;
      +--------+
      | @@port |
      +--------+
      |   3330 |
      +--------+
      1 row in set (0.00 sec)
      

      在此示例中,端口 3330 处的实例已被选为新的主实例。这次选举表明InnoDB Cluster已经提供了自动故障转移,并且MySQL Router已经自动将我们重新连接到新的主实例,并且我们具有高可用性。

      6.10.5 测试InnoDB集群高可用

      要测试 InnoDB Cluster 高可用性是否有效,请通过终止实例来模拟意外停止。集群检测到实例离开集群并重新配置自身。集群如何重新配置自身取决于您使用的是单主集群还是多主集群,以及实例在集群中扮演的角色。

      在单主模式下:

      • 如果当前主实例离开集群,则辅助实例之一将被选为新的主实例,实例按最低优先级排列 server_uuid。MySQL Router 将读写连接重定向到新选出的主节点。
      • 如果当前辅助节点离开集群,MySQL Router 会停止将只读连接重定向到该实例。

      有关详细信息,请参阅 单主模式

      在多主模式下:

      • 如果当前的“R/W”实例离开集群,MySQL Router 会将读写连接重定向到其他主实例。如果离开的实例是集群中的最后一个主实例,则集群完全消失,您无法连接到任何 MySQL 路由器端口。

      有关详细信息,请参阅 多主模式

      dba.killSandboxInstance()有多种方法可以模拟实例离开集群,例如,您可以强制停止实例上的 MySQL 服务器,或者在测试沙箱部署时 使用 AdminAPI 。在此示例中,有一个包含三个服务器实例的单主沙箱集群部署,并且侦听端口 3310 的实例是当前的主实例。实例意外离开集群,由 killing实例模拟:

      例如,通过发出 JavaScript 命令:

      mysql-js> dba.killSandboxInstance(3310)
      

      或者,通过发出 Python 命令:

      mysql-py> dba.kill_sandbox_instance(3310)
      

      集群检测到更改并自动选择新的主节点。

      假设您的会话连接到端口 6446(默认的读写经典 MySQL 协议端口),MySQL Router 应该检测到集群拓扑的更改,并将您的会话重定向到新选举的主节点。要验证这一点,请使用命令在 MySQL Shell 中切换到 SQL 模式\sql,然后选择实例的port 变量以检查您的会话已重定向到哪个实例。

      第一条SELECT语句失败,因为与原始主数据库的连接丢失,这意味着当前会话已关闭。MySQL Shell 会自动为您重新连接,当您再次发出命令时,新端口将得到确认。

      mysql-js> \sql
      Switching to SQL mode... Commands end with ;
      mysql-sql> SELECT @@port;
      ERROR: 2013 (HY000): Lost connection to MySQL server during query
      The global session got disconnected.
      Attempting to reconnect to 'root@localhost:6446'...
      The global session was successfully reconnected.
      mysql-sql> SELECT @@port;
      +--------+
      | @@port |
      +--------+
      |   3330 |
      +--------+
      1 row in set (0.00 sec)
      

      在此示例中,端口 3330 处的实例已被选为新的主实例。这次选举表明InnoDB Cluster已经提供了自动故障转移,并且MySQL Router已经自动将我们重新连接到新的主实例,并且我们具有高可用性。

6.10.6 使用集群路由器

您可以针对 InnoDB Cluster 或 InnoDB ReplicaSet 引导多个 MySQL Router 实例。从版本 8.0.19 开始,要显示所有已注册 MySQL Router 实例的列表,请发出:

Cluster.listRouters()

结果提供有关每个注册的 MySQL Router 实例的信息,例如元数据中的名称、主机名、端口等。例如,发出以下 JavaScript 命令:

mysql-js> Cluster.listRouters()
{
    "clusterName": "example",
    "routers": {
        "ic-1:3306": {
            "hostname": "ic-1:3306",
            "lastCheckIn": "2020-01-16 11:43:45",
            "roPort": 6447,
            "roXPort": 64470,
            "rwPort": 6446,
            "rwXPort": 64460,
            "version": "8.0.19"
        }
    }
}

或者发出以下 Python 命令:

mysql-py> Cluster.list_routers()
{
    "clusterName": "example",
    "routers": {
        "ic-1:3306": {
            "hostname": "ic-1:3306",
            "lastCheckIn": "2020-01-16 11:43:45",
            "roPort": 6447,
            "roXPort": 64470,
            "rwPort": 6446,
            "rwXPort": 64460,
            "version": "8.0.19"
        }
    }
}

返回的信息显示:

  • MySQL 路由器实例的名称。
  • 最后签入时间戳,由存储在元数据中的 MySQL 路由器的定期 ping 生成。
  • 运行 MySQL Router 实例的主机名。
  • 只读和读写端口,MySQL 路由器为经典 MySQL 协议连接发布这些端口。
  • 只读和读写端口,MySQL 路由器为 X 协议连接发布这些端口。
  • 此 MySQL Router 实例的版本。version8.0.19 中添加了对返回的支持 。如果此操作针对早期版本的 MySQL Router 运行,则版本字段为null

此外,该 *Cluster*.listRouters() 操作还可以显示不支持 MySQL Shell 支持的元数据版本的实例列表。使用该 onlyUpgradeRequired选项。例如,通过发布 *Cluster*.listRouters({'onlyUpgradeRequired':'true'}).

返回的列表仅显示向 注册的 MySQL Router 实例*Cluster*,这些实例需要升级其元数据。有关更多信息,请参阅 第 6.11 节 “升级元数据架构”

MySQL Router 实例不会自动从元数据中删除,因此,例如,当您引导更多实例时,InnoDB Cluster 元数据包含越来越多的实例引用。要从集群的元数据中删除已注册的 MySQL Router 实例,请使用 版本 8.0.19 中添加的操作。 *Cluster*.removeRouterMetadata(*router*)

使用该 *Cluster*.listRouters() 操作获取要删除的 MySQL Router 实例的名称,并将其作为 传入*router*。例如,假设向集群注册的 MySQL Router 实例是:

mysql-js> Cluster.listRouters(){

    "clusterName": "testCluster",
    "routers": {
        "myRouter1": {
            "hostname": "example1.com",
            "lastCheckIn": null,
            "routerId": "1",
            "roPort": "6447",
            "rwPort": "6446"
            "version": null
        },
        "myRouter2": {
            "hostname": "example2.com",
            "lastCheckIn": "2019-11-27 16:25:00",
            "routerId": "3",
            "roPort": "6447",
            "rwPort": "6446"
            "version": "8.0.19"
        }
    }
}

基于名为“ myRouter1 ” 的实例 具有“ lastCheckIn ”和“ version ”null的 事实。通过发出以下 JavaScript 命令从元数据中删除此旧实例:

mysql-js> cluster.removeRouterMetadata('myRouter1')

或者,通过发出以下 Python 命令:

mysql-py> cluster.remove_router_metadata('myRouter1')

通过从 InnoDB Cluster 元数据中删除指定的 MySQL Router 实例,将其从集群中取消注册。

6.11 升级元数据架构

随着 AdminAPI 的发展,某些版本可能要求您升级现有 ClusterSet、ReplicaSet 和 Cluster 的元数据,以确保它们与较新版本的 MySQL Shell 兼容。例如,8.0.19版本中增加了InnoDB ReplicaSet,意味着元数据架构已经升级到2.0版本。无论您是否计划使用 InnoDB ReplicaSet,要在使用早期版本的 MySQL Shell 部署的集群中使用 MySQL Shell 8.0.19 或更高版本,您必须升级集群的元数据。

警告

如果不升级元数据,您将无法使用 MySQL Shell 更改使用早期版本创建的集群的配置。例如,您只能对集群执行读取操作,例如:

  • *Cluster*.status()
  • *Cluster*.describe()
  • *Cluster*.options()

dba.upgradeMetadata()操作会将 MySQL Shell 当前连接到的 ClusterSet、ReplicaSet 或 InnoDB Cluster 上找到的元数据模式版本与该 MySQL Shell 版本支持的元数据模式版本进行比较。如果发现的元数据版本较低,则启动升级过程。然后,该 dba.upgradeMetadata()函数会更新任何自动创建的 MySQL Router 用户以拥有正确的权限。手动创建名称不以以下字符开头的 MySQL Router 用户mysql_router_不会自动升级。这是升级 ClusterSet、ReplicaSet 或 InnoDB Cluster 的重要一步,只有这样才能升级 MySQL Router 元数据。要查看有关哪些注册到 ClusterSet、ReplicaSet 或 Cluster 的 MySQL Router 实例需要元数据升级的信息,请使用该 .listRouters()函数。例如,要列出与集群关联的路由器实例,请使用分配的变量cluster问题:

cluster.listRouters({'onlyUpgradeRequired':'true'})
{
    "clusterName": "mycluster",
    "routers": {
        "example.com::": {
            "hostname": "example.com",
            "lastCheckIn": "2019-11-26 10:10:37",
            "roPort": 6447,
            "roXPort": 64470,
            "rwPort": 6446,
            "rwXPort": 64460,
            "version": "8.0.18"
        }
    }
}

在此示例中,选项onlyUpgradeRequired包含在listRouters()函数中。是 onlyUpgradeRequired一个启用过滤的布尔值,因此只有支持旧版本元数据架构并需要升级的路由器实例才会包含在返回的 JSON 对象中。

要升级 ClusterSet、ReplicaSet 或 Cluster 的元数据,请将 MySQL Shell 的全局会话连接到 ClusterSet、ReplicaSet 或 Cluster,然后使用该操作将 dba.upgradeMetadata()ClusterSet、ReplicaSet 或 Cluster 的元数据升级到新的元数据。例如:

mysql-js> shell.connect('user@example.com:3306')

mysql-js> dba.upgradeMetadata()
InnoDB Cluster Metadata Upgrade

The cluster you are connected to is using an outdated metadata schema version
1.0.1 and needs to be upgraded to 2.0.0.

Without doing this upgrade, no AdminAPI calls except read only operations will
be allowed.

The grants for the MySQL Router accounts that were created automatically when
bootstrapping need to be updated to match the new metadata version's
requirements.
Updating router accounts...
NOTE: 2 router accounts have been updated.

Upgrading metadata at 'example.com:3306' from version 1.0.1 to version 2.0.0.
Creating backup of the metadata schema...
Step 1 of 1: upgrading from 1.0.1 to 2.0.0...
Removing metadata backup...
Upgrade process successfully finished, metadata schema is now on version 2.0.0

如果安装的元数据版本较低,则启动升级过程。

dba.upgradeMetadata()函数接受以下选项:

  • dryRun:是一个布尔值,用于启用升级过程的试运行。如果dryRun使用,该dba.upgradeMetadata()函数将确定是否需要元数据升级或恢复,并通知您而不实际执行操作。
  • interactive:是一个布尔值,用于禁用或启用命令执行中的向导,表示根据设置的值提供或不提供提示和确认。默认值等于 MySQL Shell 向导模式

如果您遇到与 ClusterSet、ReplicaSet 或集群管理用户缺少权限相关的错误,请使用.setupAdminAccount()带有更新选项的相关操作来授予用户正确的权限:

  • 创建或升级具有管理 InnoDB 集群所需权限的 MySQL 用户帐户: <Cluster>.setupAdminAccount(user, options)

    请参阅 InnoDB Cluster 管理员帐户

  • 创建或升级具有管理 InnoDB ReplicaSet 所需权限的 MySQL 用户帐户: <ReplicaSet>.setupAdminAccount(user, options)

6.12 AdminAPI操作的锁定机制

从版本 8.0.33 开始,AdminAPI 将 8.0.20 中为 InnoDB ReplicaSet 引入的锁定机制扩展到 InnoDB Cluster 和 InnoDB ClusterSet。

以前,MySQL Shell 的不同实例可以在同一资源上同时连接和处理 AdminAPI 操作。例如,如果 和 是并行处理的,这可能会导致不一致的状态和错误。 *Cluster*.addInstance()``*Cluster*.setPrimaryInstance()

锁定类型

AdminAPI 使用 MySQL 锁定服务提供以下锁定类型:

  • 读锁或共享锁:允许并发执行某些操作,同时阻止独占操作。如果某个操作尝试获取共享锁,但由于存在排他锁而无法获取共享锁,则该操作将中止,而不进行任何更改。如果当前操作有共享锁,并且新操作需要共享锁,则允许新操作访问。
  • 写锁或排它锁:阻止所有其他操作的执行,直到当前操作完成并释放排它锁。如果某个操作尝试获取独占锁,但由于存在现有锁而无法获取独占锁,则该操作将中止,而不进行任何更改。

有关更多信息, 请参阅锁定服务。

下表列出了每个 AdminAPI 操作的锁定:

笔记

不需要锁的操作没有列出。

实际上,如果您尝试执行一个操作,而另一个无法并发执行的操作仍在运行,则会收到一条错误,指示无法获取所需资源的锁定。在这种情况下,您应该等待正在运行的持有锁的操作完成,然后才尝试处理下一个操作。例如:

mysql-js> rs.addInstance("admin@rs2:3306");

ERROR: The operation cannot be executed because it failed to acquire the lock on
instance 'rs1:3306'. Another operation requiring exclusive access to the
instance is still in progress, please wait for it to finish and try again.

ReplicaSet.addInstance: Failed to acquire lock on instance 'rs1:3306' (MYSQLSH
51400)

在此示例中, 失败是因为无法获取 *ReplicaSet*.addInstance() 主实例 ( ) 上的锁,因为 操作(或其他类似操作)仍在运行。 rs1:3306``*ReplicaSet*.setPrimaryInstance()

笔记

如果实例作为克隆操作或请求的重新启动的一部分重新启动,则锁定将被释放。因此,在短时间内(以毫秒为单位),另一个 Shell 会话可以在重新启动时访问该实例并锁定它。但是,Cluster 和/或 ClusterSet 上的原始锁仍然存在,因此可以锁定新重新启动的实例的新命令无法请求 Cluster 或 ClusterSet 锁。

DBA 锁定

本节列出了操作的锁 。 *dba*.*operationName*

表 6.1 DBA 操作锁

手术 锁型
configureInstance() 在目标实例上独占
configureLocalInstance() 在目标实例上独占
createCluster() 在目标实例上独占
rebootClusterFromCompleteOutage() 对所有可联系的集群成员独占。如果集群是副本集群,并且是 ClusterSet 的一部分,则它也会作为操作的一部分重新加入 ClusterSet。在这种情况下,该操作也获取与 相同的锁 clusterset.rejoinCluster()
upgradeMetadata() 集群:集群和目标实例上的排他锁。ClusterSet:ClusterSet、主 Cluster 和目标实例上的排他锁。
createReplicaSet() 目标实例上的独占锁。
configureReplicaSetInstance() 目标实例上的独占锁。
upgradeMetadata() 如果拓扑是 ClusterSet,则在 ClusterSet 和主集群上锁定;如果拓扑是独立集群,则在 ClusterSet 上锁定;如果拓扑是独立集群,则在目标实例上锁定。

集群锁定

本节列出了操作的锁 。 *cluster*.*operationName*

表 6.2 集群操作锁

手术 集群锁类型 目标实例锁类型
addInstance() 独家的 独家的
createClusterSet() 独家的
dissolve() 独家的
fenceAllTraffic() 独家的
fenceWrites() 独家的
forceQuorum() 独家的
rejoinInstance() 共享 独家的
removeInstance() 独家的 独家的
rescan() 独家的
resetRecoveryAccountsPassword() 独家的
setInstanceOption() 独家的除了选项tagclusterName
setOption() 独家的除了选项tagclusterName
setPrimaryInstance( 独家的
setupAdminAccount() 共享
setupRouterAccount() 共享
switchToMultiPrimaryMode() 独家的
switchToSinglePrimaryMode() 独家的
unfenceWrites() 独家的

簇集锁定

本节列出了操作的锁 。 *clusterSet*.*operationName*

表 6.3 ClusterSet 操作锁

手术 ClusterSet锁类型 主集群锁类型 目标集群锁类型
createReplicaCluster() 共享 在用于创建新副本集群的实例上独占。
forcePrimaryCluster() 在所有副本集群上独占。
rejoinCluster() 共享 共享 独家的
removeCluster() 独家的。 独家的 独家的
setOption() 独家的 独家的(仅当replicationAllowedHost设置时)
setPrimaryCluster() 独家的 独家的

InnoDB 副本集锁定

本节列出了操作的锁 。 *replicaSet*.*operationName*

表 6.4 ReplicaSet 操作锁

手术 主实例锁类型 目标实例锁类型
forcePrimaryInstance() 操作时目标实例和 ReplicaSet 的所有可联系成员上独占。
setPrimaryInstance() 独家的 操作时目标实例和 ReplicaSet 的所有可联系成员上独占。
addInstance() 共享 独家的
rejoinInstance() 共享 独家的
removeInstance() 共享 独家的
removeRouterMetadata() 共享
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论