第21章InnoDB集群

目录

21.1 InnoDB集群简介
21.2创建InnoDB集群
21.2.1部署方案
21.2.2 InnoDB集群要求
21.2.3安装方法
21.2.4 InnoDB集群的生产部署
21.2.5 InnoDB集群的沙箱部署
21.2.6采用组复制部署
21.3将MySQL路由器与InnoDB集群配合使用
21.4使用InnoDB集群
21.5已知限制

本章介绍MySQL InnoDB集群,它结合了MySQL技术,使您能够创建高度可用的MySQL服务器实例集群。

21.1 InnoDB集群简介

MySQL InnoDB集群为MySQL提供了完整的高可用性解决方案。 MySQL Shell 包含AdminAPI,使您可以轻松配置和管理一组至少三个MySQL服务器实例,以充当InnoDB集群。 每个MySQL服务器实例都运行MySQL Group Replication,它提供了在InnoDB集群内复制数据的机制,具有内置故障转移功能。 AdminAPI无需在InnoDB集群中直接使用组复制,但有关详细信息,请参阅 第18章“ 组复制” ,其中说明了详细信息。 MySQL路由器 可以根据您部署的集群自动配置自身,将客户端应用程序透明地连接到服务器实例。 如果服务器实例意外故障,群集将自动重新配置。 在默认的单主模式下,InnoDB集群具有单个读写服务器实例 - 主要实例。 多个辅助服务器实例是主要副本的副本。 如果主服务器出现故障,则辅助服务器将自动升级为主服务器。 MySQL路由器检测到此情况并将客户端应用程序转发到新主服务器。 高级用户还可以将群集配置为具有多原色。

重要

InnoDB集群不支持MySQL NDB Cluster。 NDB Cluster依赖于 NDB 存储引擎以及许多特定于NDB Cluster的程序,这些程序未随MySQL Server 8.0提供; NDB 仅作为MySQL NDB Cluster分发的一部分提供。 此外, MySQL Server 8.0提供 的MySQL服务器二进制文件( mysqld )不能与NDB Cluster一起使用。 有关MySQL NDB Cluster的更多信息,请参见 第22章, MySQL NDB Cluster 8.0 。 22.1.6节,“MySQL服务器使用的是InnoDB与NDB集群相比” ,提供了有关之间的差异 InnoDB 和 NDB 存储引擎。

下图显示了这些技术如何协同工作的概述:

图21.1 InnoDB集群概述

三台MySQL服务器组合在一起作为高可用性集群。 其中一个服务器是读/写主实例,另外两个是只读辅助实例。 组复制用于将数据从主实例复制到辅助实例。 MySQL路由器将客户端应用程序(在此示例中为MySQL连接器)连接到主实例。

使用AdminAPI

MySQL Shell包含AdminAPI,可通过 dba 全局变量及其相关方法访问。 该 dba 变量的方法使您能够部署,配置和管理InnoDB的集群。 例如,使用该 dba.createCluster() 方法创建InnoDB集群。

重要

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

MySQL Shell为AdminAPI提供在线帮助。 要列出所有可用 dba 命令,请使用该 dba.help() 方法。 有关特定方法的联机帮助,请使用常规格式 object.help('methodname') 。 例如:

MySQL的-JS> dba.help('getCluster')

从元数据存储中检索群集。

句法

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

哪里

  name:参数,用于指定要返回的集群的名称。
  选项:包含其他选项的词典。

退货

  由给定名称或默认群集标识的群集对象。

描述

如果未指定name或为null,则将返回默认群集。

如果指定了name,并且找不到具有指定名称的集群,则会出现错误
将被提出。

options字典接受connectToPrimary选项,默认为
true表示shell自动连接到主要成员
集群。

例外

  以下场景中的MetadataError:

   - 如果元数据无法访问。
   - 如果元数据更新操作失败。

  以下场景中的ArgumentError:

   - 如果群集名称为空。
   - 如果群集名称无效。
   - 如果群集不存在。

  以下场景中的RuntimeError:

   - 如果当前连接不能用于组复制。

21.2创建InnoDB集群

本节介绍了创建InnoDB集群的不同方法,服务器实例的要求以及部署集群时需要安装的软件。

21.2.1部署方案

InnoDB集群支持以下部署方案:

  • 生产部署: 如果要在完整生产环境中使用InnoDB集群,则需要配置所需数量的计算机,然后将服务器实例部署到计算机。 通过生产部署,您可以充分利用InnoDB集群的高可用性功能。 有关说明 , 请参见 第21.2.4节“InnoDB集群的生产部署” 。

  • 沙箱部署: 如果要在提交完整生产部署之前测试InnoDB集群,则提供的沙箱功能使您可以在本地计算机上快速设置集群。 使用所需配置创建沙盒服务器实例,您可以尝试InnoDB集群以熟悉所使用的技术。 有关说明 , 请参见 第21.2.5节“InnoDB集群的沙箱部署” 。

    重要

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

21.2.2 InnoDB集群要求

在安装InnoDB集群的生产部署之前,请确保您要使用的服务器实例满足以下要求。

  • InnoDB集群使用组复制,因此您的服务器实例必须满足相同的要求。 请参见 第18.9.1节“组复制要求” 。 AdminAPI提供了 dba.checkInstanceConfiguration() 验证实例是否满足组复制要求的 dba.configureInstance() 方法 ,以及 配置实例以满足要求的方法。

    注意

    使用沙箱部署时,实例将配置为自动满足这些要求。

  • 组复制成员可以使用比其它存储引擎包含表 InnoDB ,例如 MyISAM 。 这些表不能由Group Replication写入,因此在使用InnoDB集群时也是如此。 为了能够使用InnoDB集群写入此类表,请 InnoDB 在使用InnoDB集群中的实例之前 将所有此类表转换为 。

  • 必须在要与InnoDB集群一起使用的任何实例上启用性能模式。

  • MySQL Shell用于配置在InnoDB集群中使用的服务器的配置脚本需要访问Python 2.7版。 对于沙箱部署,在用于部署的单个机器上需要Python,生产部署需要在每个应在本地运行MySQL Shell的服务器实例上使用Python,请参阅 持久设置 。

    在Windows上,MySQL Shell包含Python,不需要用户配置。 在Unix上,必须将Python作为shell环境的一部分。 要检查您的系统是否正确配置了Python,请发出:

    $ /usr/bin/env python

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

21.2.3安装方法

用于安装InnoDB集群的方法取决于您要使用的部署类型。 对于沙箱部署,将InnoDB集群的组件安装到单个计算机上。 沙箱部署是单个计算机的本地部署,因此安装只需在本地计算机上执行一次。 对于生产部署,请将组件安装到要添加到群集的每台计算机上。 生产部署使用运行MySQL服务器实例的多个远程主机,因此您需要使用SSH或Windows远程桌面等工具连接到每台计算机,以执行安装组件等任务。 可以使用以下安装InnoDB集群的方法:

安装InnoDB集群所需的软件后,请选择 第21.2.5节“InnoDB集群的沙箱部署” 或 第21.2.4节“InnoDB集群的生产部署” 。

21.2.4 InnoDB集群的生产部署

在生产环境中工作时,构成InnoDB集群的MySQL服务器实例作为网络的一部分在多台主机上运行,​​而不是在单机上运行,​​如 第21.2.5节“InnoDB集群的沙箱部署”中所述 。 在继续执行这些说明之前,必须将所需的软件安装到要作为服务器实例添加到群集的每台计算机上,请参见 第21.2.3节“安装方法” 。

下图说明了您在本节中使用的方案:

图21.2生产部署

三台MySQL服务器组合在一起作为生产InnoDB集群。 其中一个服务器是主实例,另外两个是辅助实例。 主服务器的IP地址为139.59.177.10,两个辅助实例的IP地址为139.59.177.11和139.59.177.12。 MySQL路由器将客户端应用程序连接到主实例。 MySQL Shell中的管理功能直接与生产InnoDB集群交互。

重要

与沙箱部署(其中所有实例都本地部署到AdminAPI具有本地文件访问权限并且可以保留配置更改的一台计算机)不同,对于生产部署,您必须在实例上保留所有配置更改。 如何执行此操作取决于在实例上运行的MySQL版本,请参阅“ 持久设置” 。

要将服务器的连接信息传递给AdminAPI,请使用URI类型字符串或数据字典,请参见 第4.2.4节“使用URI或键值对进行连接” 。 在此文档中,显示了URI类型字符串。

用户权限

用于管理实例的用户帐户不必是root帐户,但用户需要分配全读,除了全面的MySQL管理员特权写在InnoDB的集群的元数据表的权限( SUPER , GRANT OPTION , CREATE , DROP 等) 。 创建用户以管理群集的首选方法是使用 clusterAdmin 带有 dba.configureInstance() 和 Cluster.addInstance() 操作 的 选项 。 在此过程中,用户 ic 显示在示例中。

如果仅需要读取操作(例如用于监视目的),则可以使用具有更多受限特权的帐户。 为用户 your_user 提供监控InnoDB集群问题所需的权限:

GRANT SELECT on mysql_innodb_cluster_metadata。* TO your_user@'%';
GRANT SELECT ON performance_schema.global_status TO your_user@'%';
GRANT SELECT ON performance_schema.replication_applier_configuration TO your_user@'%';
GRANT SELECT ON performance_schema.replication_applier_status TO your_user@'%';
GRANT SELECT ON performance_schema.replication_applier_status_by_coordinator TO your_user@'%';
GRANT SELECT ON performance_schema.replication_applier_status_by_worker TO your_user@'%';
GRANT SELECT ON performance_schema.replication_connection_configuration TO your_user@'%';
GRANT SELECT ON performance_schema.replication_connection_status TO your_user@'%';
GRANT SELECT ON performance_schema.replication_group_member_stats TO your_user@'%';
GRANT SELECT ON performance_schema.replication_group_members TO your_user@'%';
GRANT SELECT ON performance_schema.threads TO your_user@'%'WITH GRANT OPTION; 

InnoDB Cluster创建的用户帐户

作为使用组复制的一部分,InnoDB集群创建内部用户,以便在集群中的服务器之间进行复制。 这些用户是群集的内部用户,生成的用户的用户名遵循命名方案 。 用于内部用户的主机名取决于是否 已配置 该 选项。 如果 未配置,则默认为, 并且使用通配符 和 主机名值 创建内部用户 。 当 已配置,在每个地址 mysql_innodb_cluster_r[10_numbers] ipWhitelist ipWhitelist AUTOMATIC % localhost ipWhitelist ipWhitelist 列表创建了一个内部用户。 有关更多信息,请参阅 创建服务器白名单 。

每个内部用户都有一个随机生成的密码。 随机生成的用户将获得以下授权:

授予复制权限*。*至internal_user;

内部用户帐户在种子实例上创建,然后复制到群集中的其他实例。 内部用户是:

  • 通过发出创建新集群时生成的 dba.createCluster()

  • 通过发出将新实例添加到群集时生成 Cluster.addInstance() 。

此外, Cluster.rejoinInstance() 当使用该 ipWhitelist 选项指定主机名 时 ,该 操作还可能导致生成新的内部用户 。 例如,通过发布:

Cluster.rejoinInstance({ipWhitelist:“192.168.1.1 / 22”});

删除所有以前存在的内部用户并创建新的内部用户,同时考虑所 ipWhitelist 使用 的 值。

有关Group Replication所需的内部用户的更多信息,请参见 第18.2.1.3节“用户凭据” 。

配置主机名

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

  • 配置每台计算机以将每台其他计算机的IP映射到主机名。 有关详细信息,请参阅操作系统文档 这是推荐的解决方案。

  • 设置DNS服务

  • 将 report_host 每个实例的MySQL配置中 的 变量配置为合适的外部可访问地址

在此过程中,主机名 用于示例中。 ic-number

要验证是否正确配置了MySQL服务器的主机名,请执行以下查询以查看实例如何将其自己的地址报告给其他服务器,并尝试使用返回的地址从其他主机连接到该MySQL服务器:

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

持久设置

您用于处理群集的AdminAPI命令,它的服务器实例会修改实例的配置。 根据MySQL Shell连接到实例的方式以及实例上安装的MySQL版本,这些配置更改可以自动保留到实例。 对实例保持设置可确保在实例重新启动后保留配置更改,有关背景信息,请参阅 SET PERSIST 。 这对于可靠的群集使用至关重要,例如,如果设置未持久化,则添加到群集的实例在重新启动后不会重新加入群集,因为配置更改会丢失。 以下操作后需要进行持续更改:

  • dba.configureInstance()

  • dba.createCluster()

  • Cluster.addInstance()

  • Cluster.removeInstance()

  • Cluster.rejoinInstance()

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

不满足这些要求的实例不支持自动进行持久性配置更改,当AdminAPI操作导致实例设置的更改持续存在时,您会收到警告,例如:

	
警告:自MySQL版本5.7.21以来,实例“localhost:3320”成员身份更改无法保留 
不支持SET PERSIST命令(需要MySQL版本> = 8.0.5)。请使用
本地<Dba> .configureLocalInstance命令可以保留更改。

当针对当前正在运行MySQL Shell的MySQL实例发出AdminAPI命令时,换句话说,本地实例MySQL Shell将配置更改直接保存到实例。 在支持持久配置更改的本地实例上,配置更改将持久保存到实例的 mysqld-auto.cnf 文件,配置更改不需要任何进一步的步骤。 在不支持自动持久配置更改的本地实例上,您需要在本地进行更改,请参阅 配置实例 dba.configureLocalInstance() 。

当针对远程实例运行时,换句话说,运行MySQL Shell当前运行的实例以外的实例,如果实例支持自动保持配置更改,则AdminAPI命令会保持对实例的配置更改 mysql-auto.conf 选项文件。 如果远程实例不支持自动持久配置更改,则AdminAPI命令无法自动配置实例的选项文件。 这意味着AdminAPI命令可以从实例读取信息,例如显示当前配置,但是对配置的更改不能持久保存到实例的选项文件。 在这种情况下,您需要在本地持久保存更改,请参阅 配置实例 dba.configureLocalInstance() 。

详细记录

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

外壳> mysqlsh --log-level=DEBUG3

该 DEBUG3 建议,请 --log-level 以获取更多信息。 当 DEBUG3 设置了MySQL壳牌日志文件包含例如线 Debug: execute_sql( ... ) ,其包含被作为各AdminAPI呼叫的一部分执行的SQL查询。 MySQL Shell生成的日志文件位于 ~/.mysqlsh/mysqlsh.log 基于Unix的系统中; 在Microsoft Windows系统上,它位于 %APPDATA%\MySQL\mysqlsh\mysqlsh.log 。 有关 更多信息, 请参阅 MySQL Shell应用程序日志

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

mysql-js> dba.verbose = 2

这将启用AdminAPI调用的最大输出。 可用的输出水平是:

  • 0或OFF是默认值。 这提供了最小的输出,是不进行故障排除时的推荐级别。

  • 1或ON会将每次调用的详细输出添加到AdminAPI。

  • 2将调试输出添加到详细输出,提供有关每次调用AdminAPI的内容的完整信息。

配置生产实例

AdminAPI提供的 dba.configureInstance() 功能可检查实例是否针对InnoDB群集使用情况进行了适当配置,并在发现任何与InnoDB群集不兼容的设置时配置实例。 您 dba.configureInstance() 针对实例 运行该 命令,并检查启用该实例以用于InnoDB群集使用所需的所有设置。 如果实例不需要更改配置,则无需修改实例的配置,并且 dba.configureInstance() 命令输出确认实例已准备好使用InnoDB群集。 如果要使实例与InnoDB集群兼容,则需要进行任何更改,将显示不兼容设置的报告,您可以选择让命令对实例的选项文件进行更改。 根据MySQL Shell连接到实例的方式以及在实例上运行的MySQL版本,您可以通过将这些更改持久保存到远程实例的选项文件来永久更改这些更改,请参阅“ 持久设置” 。 不支持持久配置更改的实例会自动要求您在本地配置实例,请参阅 使用配置实例 dba.configureLocalInstance() 。 或者,您可以手动更改实例的选项文件, 有关详细信息 ,请参见 第4.2.2.2节“使用选项文件” 。 无论您进行配置更改的方式如何,您可能必须重新启动MySQL以确保检测到配置更改。

该 dba.configureInstance() 命令 的语法 是:

dba.configureInstance([ instance] [,options])

其中 instance 是实例定义, options 是一个数据字典,其中包含用于配置操作的其他选项。 该命令返回有关操作结果的描述性文本消息。

实例定义是实例的连接数据。 如果目标实例已属于InnoDB集群,则会生成错误,并且该过程将失败。

选项字典可以包含以下内容:

  • mycnfPath - 实例的MySQL选项文件的路径。

  • outputMycnfPath - 用于写入实例的MySQL选项文件的备用输出路径。

  • password - 连接使用的密码。

  • clusterAdmin - 要创建的InnoDB集群管理员用户的名称。 支持的格式是标准的MySQL帐户名称格式。 支持用户名和主机名的标识符或字符串。 默认情况下,如果不加引号,则假定input是一个字符串。

  • clusterAdminPassword - 使用创建的InnoDB集群管理员帐户的密码 clusterAdmin 。

  • clearReadOnly - 用于确认 super_read_only 应设置为off 的布尔值 ,请参阅 超级只读和实例 。

  • interactive - 用于在命令执行中禁用交互式向导的布尔值,因此不会向用户提供提示,也不会显示确认提示。

  • restart - 一个布尔值,用于指示应执行目标实例的远程重新启动以完成操作。

连接密码可以包含在实例定义中。 或者,可以使用 password 选项 指定它来覆盖它 。

一旦 dba.configureInstance() 针对实例发出,该命令将检查实例的设置是否适合InnoDB群集使用。 将显示一个报告,显示InnoDB群集所需的设置。 如果实例不需要对其设置进行任何更改,则可以在InnoDB集群中使用它,并可以继续 创建集群 。 如果实例的设置对InnoDB群集使用无效,则该 dba.configureInstance() 命令将显示需要修改的设置。 在配置实例之前,系统会提示您使用以下信息确认表中显示的更改:

  • Variable - 无效的配置变量。

  • Current Value - 无效配置变量的当前值。

  • Required Value - 配置变量所需的值。

如何继续取决于实例是否支持持久设置,请参阅“ 持久设置” 。 当 dba.configureInstance() 针对MySQL Shell当前运行的MySQL实例(即本地实例)发出时,它会尝试自动配置实例。 何时 dba.configureInstance() 针对远程实例发出,如果实例支持自动保持配置更改,则可以选择执行此操作。 如果远程实例不支持持久化更改以配置InnoDB群集使用,则必须在本地配置实例。 请参阅使用 配置实例 dba.configureLocalInstance() 。

通常, dba.configureInstance() 配置选项文件 后不需要重新启动实例 ,但对于某些特定设置,可能需要重新启动。 此信息显示在发布后生成的报告中 dba.configureInstance() 。 如果实例支持该 RESTART 语句,MySQL Shell可以关闭然后启动实例。 这可确保mysqld检测到对实例选项文件所做的更改。 欲了解更多信息,请参阅 RESTART 。

注意

执行 RESTART 语句后,实例的当前连接将丢失。 如果启用了自动重新连接,则在服务器重新启动后将重新建立连接。 否则,必须手动重新建立连接。

该 dba.configureInstance() 方法验证合适的用户是否可用于群集使用,该群集用于群集成员之间的连接,请参阅 用户权限 。 添加合适用户的推荐方法是使用 clusterAdmin 和 clusterAdminPassword 选项,这使您可以在调用函数时配置群集用户和密码。 例如:

mysql-js> dba.configureInstance('ic @ ic-1:3306',\ 
{clusterAdmin:“'icadmin'@'ic-1%'”,clusterAdminPassword:' password'});

此用户被授予能够管理群集的权限。 接受的用户名格式遵循标准的MySQL帐户名称格式,请参见 第6.2.4节“指定帐户名称” 。

如果未指定用户来管理群集,则在交互模式下,可以使用向导选择以下选项之一:

  • 为root用户启用远程连接

  • 创建一个新用户,相当于指定 clusterAdmin 和 clusterAdminPassword 选项

  • 没有自动配置,在这种情况下您需要手动创建用户

以下示例演示了为群集使用创建新用户的选项。

	
MySQL的-JS> dba.configureLocalInstance('root@localhost:3306')

请提供'root @ localhost:3306'的密码:

请指定MySQL配置文件的路径:/etc/mysql/mysql.conf.d/mysqld.cnf
验证实例......

配置已更新,但需要重新启动服务器。
{
  “config_errors”:[
    {
      “行动”:“重启”,
      “当前”:“关闭”,
      “选项”:“enforce_gtid_consistency”,
      “必需”:“开”
    },
    {
      “行动”:“重启”,
      “当前”:“关闭”,
      “选项”:“gtid_mode”,
      “必需”:“开”
      },
    {
      “行动”:“重启”,
      “当前”:“0”,
      “option”:“log_bin”,
      “必需”:“1”
    },
    {
      “行动”:“重启”,
      “当前”:“0”,
      “option”:“log_slave_updates”,
      “必需”:“开”
    },
    {
      “行动”:“重启”,
      “当前”:“文件”,
      “option”:“master_info_repository”,
      “必需”:“表”
    },
    {
      “行动”:“重启”,
      “当前”:“文件”,
      “option”:“relay_log_info_repository”,
      “必需”:“表”
    },
    {
      “行动”:“重启”,
      “当前”:“关闭”,
      “option”:“transaction_write_set_extraction”,
      “必填”:“XXHASH64”
    }
  ]
  “错误”:[],
  “restart_required”:是的,
  “状态”:“错误”
}
MySQL的-JS>
小费

如果实例有, super_read_only=ON 那么您可能需要确认AdminAPI可以设置 super_read_only=OFF 。 有关 详细信息, 请参阅 超级只读和实例 。

创建群集

准备好实例后,使用该 dba.createCluster() 功能创建群集。 您运行MySQL Shell的计算机将用作群集的种子实例。 种子实例将复制到您添加到群集的其他实例,从而使它们成为种子实例的副本。

在创建集群之前,MySQL Shell必须连接到实例,因为当您发出 MySQL Shell时,会创建与连接到MySQL Shell当前全局会话的服务器实例的MySQL协议会话。 使用该 函数创建集群并将返回的集群分配给名为的变量 : dba.createCluster(name) dba.createCluster(name) cluster

      
MySQL的-JS> var cluster = dba.createCluster('testCluster')

在ic @ ic-1验证实例:3306 ...

此实例将其自己的地址报告为ic-1

实例配置是合适的。
在'ic @ ic-1:3306'上创建InnoDB集群'testCluster'......

添加种子实例...
群集已成功创建。使用Cluster.addInstance()添加MySQL实例。
至少需要3个实例才能使集群能够承受最多
一台服务器故障。

返回的Cluster对象使用一个独立于MySQL Shell主会话的新会话。 这可确保如果更改MySQL Shell全局会话,Cluster对象将维护其与实例的会话。

小费

如果实例有, super_read_only=ON 那么您可能需要确认AdminAPI可以设置 super_read_only=OFF 。 有关 详细信息, 请参阅 超级只读和实例 。

注意

如果遇到与无法访问的元数据相关的错误,则可能配置了环回网络接口。 要正确使用InnoDB群集,请禁用环回接口。

要检查是否已创建群集,请使用群集实例的 status() 功能。 请参阅使用 检查群集的状态 Cluster.status() 。

小费

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

使用MySQL Shell 8.0.14及更高版本创建集群时,可以在实例从集群中排除之前设置超时,例如,当它们无法访问时。 将 expelTimeout 选项 传递 给 dba.createCluster() 操作,该操作 group_replication_member_expel_timeout 在种子实例上 配置 变量。 该 expelTimeout 选项可以采用0到3600范围内的整数值。运行MySQL服务器8.0.13及更高版本的所有实例(已添加到已 expelTimeout 配置 的集群) 将自动配置为具有与 expelTimeout 种子实例上配置的值 相同的 值。

有关可以传递给的其他选项的信息 dba.createCluster() ,请参见 第21.4节“使用InnoDB Cluster” 。

将实例添加到群集

使用此 功能可向群集添加更多实例,其中 是已配置实例的连接信息,请参阅 配置生产实例 。 群集中至少需要三个实例,以使其能够容忍一个实例的失败。 添加更多实例会增加对实例失败的容忍度。 要向集群问题添加实例: cluster.addInstance(instance) instance

MySQL的-JS> cluster.addInstance('ic@ic-2:3306')
将在InnoDB集群中添加一个新实例。取决于数量
群集上的数据可能需要几秒钟到几个小时。

请提供“ic @ ic-2:3306”的密码:********
将实例添加到集群中......

在ic-2验证实例:3306 ...

此实例将其自己的地址报告为ic-2

实例配置是合适的。

实例“ic @ ic-2:3306”已成功添加到群集中。

要验证是否已添加实例,请使用集群实例的 status() 功能。 例如,这是添加第二个实例后沙箱集群的状态输出:

MySQL的-JS> cluster.status()
{
    “clusterName”:“testCluster”, 
    “defaultReplicaSet”:{
        “名称”:“默认”, 
        “primary”:“localhost:3310”, 
        “ssl”:“必需的”, 
        “status”:“OK_NO_TOLERANCE”, 
        “statusText”:“群集不能容忍任何失败。”, 
        “拓扑”:{
            “localhost:3310”:{
                “地址”:“localhost:3310”, 
                “模式”:“R / W”, 
                “readReplicas”:{}, 
                “角色”:“HA”, 
                “状态”:“在线”
            }, 
            “localhost:3320”:{
                “地址”:“localhost:3320”, 
                “模式”:“R / O”, 
                “readReplicas”:{}, 
                “角色”:“HA”, 
                “状态”:“在线”
            }
        }
    }, 
    “groupInformationSourceMember”:“mysql:// root @ localhost:3310”
}

如何继续操作取决于实例是MySQL Shell运行实例的本地实例还是远程实例,以及实例是否支持自动保持配置更改,请参阅保持 设置 。 如果实例支持自动持久更改配置,则无需手动保留设置,可以添加更多实例或继续执行下一步。 如果实例不支持自动持久配置更改,则必须在本地配置实例。 请参阅使用 配置实例 dba.configureLocalInstance() 。 这对于确保实例在离开群集时重新加入群集至关重要。

小费

如果实例有, super_read_only=ON 那么您可能需要确认AdminAPI可以设置 super_read_only=OFF 。 有关 详细信息, 请参阅 超级只读和实例 。

部署集群后,您可以配置MySQL路由器以提供高可用性,请参见 第21.3节“将MySQL路由器与InnoDB集群配合使用” 。

21.2.5 InnoDB集群的沙箱部署

本节介绍如何设置沙箱InnoDB集群部署。 您可以使用包含AdminAPI的MySQL Shell创建和管理InnoDB集群。 本节假设您熟悉MySQL Shell,请参阅 MySQL Shell 8.0(MySQL 8.0的一部分) 以获取更多信息。

最初部署和使用MySQL的本地沙箱实例是开始探索InnoDB集群的好方法。 在生产服务器上部署之前,您可以在本地完全测试InnoDB集群。 MySQL Shell具有内置功能,用于创建正确配置为在本地部署方案中使用组复制的沙箱实例。

重要

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

部署沙箱实例时,将创建本地目录并 存储 mysqld 的副本 。 此副本与部署沙箱时安装的当前MySQL服务器版本相匹配。 因此, 用于沙箱 的 mysqld 版本 是固定的,如果您随后升级已安装的MySQL版本,则不会更改。 由于沙盒实例被认为是瞬态的并且用于测试,因此最快的解决方案是在升级MySQL之后部署新的沙箱实例之前删除在旧版本上构建的所有沙箱。

本教程介绍如何使用MySQL Shell创建由三个MySQL服务器实例组成的InnoDB集群。

部署沙箱实例

MySQL Shell包含添加 dba 全局变量 的AdminAPI,该 变量提供管理沙箱实例的功能。 在此示例设置中,您将使用创建三个沙箱实例 dba.deploySandboxInstance() 。

通过发出命令从命令提示符启动MySQL Shell:

外壳> mysqlsh

除了本机SQL模式之外,MySQL Shell还提供两种脚本语言模式,JavaScript和Python。 在本指南中,MySQL Shell主要用于JavaScript模式。 当MySQL Shell启动时,它默认处于JavaScript模式。 通过发布 \js JavaScript模式, \py Python模式和 \sql SQL模式来 切换 模式。 通过发出 \js 命令 确保您处于JavaScript模式 ,然后执行:

MySQL的-JS> dba.deploySandboxInstance(3310)
注意

在JavaScript和Python模式下,不需要使用分号终止命令。

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

将提示用户的root用户密码。

重要

每个实例都有自己的密码。 在本教程中为所有沙箱定义相同的密码使其更容易,但请记住在生产部署中为每个实例使用不同的密码。

要部署其他沙箱服务器实例,请在端口3310处重复沙盒实例所遵循的步骤,选择不同的端口号。 对于每个其他沙盒实例问题:

MySQL的-JS> dba.deploySandboxInstance(port_number)

要学习本教程,请为三个沙盒服务器实例使用端口号3310,3320和3330。 问题:

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

创建Sandbox InnoDB集群

下一步是在连接到种子MySQL Server实例时创建InnoDB集群。 种子实例包含要复制到其他实例的数据。 在此示例中,沙箱实例为空,因此我们可以选择任何实例。

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

MySQL的-JS> \connect root@localhost:3310

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

MySQL的-JS> shell.connect('user@localhost:3310')
小费

尝试使用主机名解析为与真实网络接口不匹配的IP地址的实例失败。 请参见 第21.5节“已知限制” 。

连接后,AdminAPI可以写入本地实例的选项文件。 这与使用生产部署不同,在生产部署中,您需要将设置保留到实例的选项文件中。

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

MySQL的-JS> var cluster = dba.createCluster('testCluster')

该 createCluster() 方法将InnoDB集群元数据部署到所选实例,并将当前连接的实例添加为种子实例。 该 createCluster() 方法返回创建的集群,在上面的示例中,它被分配给 cluster 变量。 createCluster() 在这种情况下, 传递给该 方法 的参数 是赋予此InnoDB集群的符号名称 testCluster 。

小费

如果实例有, super_read_only=ON 那么您可能需要确认AdminAPI可以设置 super_read_only=OFF 。 有关 详细信息, 请参阅 超级只读和实例 。

将实例添加到InnoDB群集

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

最近创建了此示例中的种子实例,因此它几乎为空。 因此,几乎没有数据需要从种子实例复制到辅助实例。 在生产环境中,种子实例上有现有数据库,您可以使用MySQL Enterprise Backup等工具确保辅助数据在复制开始之前具有匹配的数据。 这避免了数据从主数据库复制到辅助数据库时长时间延迟的可能性。 请参见 第18.4.7节“将MySQL企业备份与组复制一起使用” 。

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

MySQL的-JS> cluster.addInstance('root@localhost:3320')

提示输入root用户的密码。

添加第三个实例:

MySQL的-JS> cluster.addInstance('root@localhost:3330')

提示输入root用户的密码。

此时,您已创建了一个包含三个实例的集群:一个主服务器和两个辅助服务器。

小费

只能指定 localhost 在 addInstance() 如果实例是一个沙箱实例。 这也适用于 addInstance() 发布后 的隐含 createCluster() 。

坚持沙箱配置

将沙箱实例添加到群集后,必须将InnoDB群集所需的配置保留到每个实例的选项文件中。 如何继续取决于实例是否支持自动持久配置更改,请参阅“ 持久设置” 。 当您使用的MySQL实例支持持久更改配置时,添加实例会自动配置实例。 当您使用的MySQL实例不支持自动持久配置更改时,您必须在本地配置实例。 请参阅使用 配置实例 dba.configureLocalInstance() 。

要检查是否已创建群集,请使用群集实例的 status() 功能。 请参阅使用 检查群集的状态 Cluster.status() 。

部署集群后,您可以配置MySQL路由器以提供高可用性,请参见 第21.3节“将MySQL路由器与InnoDB集群配合使用” 。

21.2.6采用组复制部署

如果您具有组复制的现有部署,并且希望使用它来创建集群,请将该 adoptFromGR 选项 传递 给该 dba.createCluster() 函数。 创建的InnoDB集群会匹配复制组是以单主数据库还是多主数据库运行。

要采用现有的组复制组,请使用MySQL Shell连接到组成员。 在以下示例中,采用单主组。 我们连接到 gr-member-2 辅助实例,同时 gr-member-1 作为组的主要功能。 使用 dba.createCluster() 传入 adoptFromGR 选项 创建集群 。 例如:

  
MySQL的-JS> var cluster = dba.createCluster('prodCluster', {adoptFromGR: true});

将在实例'root @ gr-member-2:3306'上创建一个新的InnoDB集群。

在'root @ gr-member-2:3306'上创建InnoDB集群'prodCluster'...
添加种子实例...

群集已成功创建。使用cluster.addInstance()添加MySQL实例。
至少需要3个实例才能使集群能够承受最多
一台服务器故障。
小费

如果实例有, super_read_only=ON 那么您可能需要确认AdminAPI可以设置 super_read_only=OFF 。 有关 详细信息, 请参阅 超级只读和实例 。

新群集与组的模式匹配。 如果采用的组以单主模式运行,则会创建单主群集。 如果采用的组以多主模式运行,则会创建多主集群。

21.3将MySQL路由器与InnoDB集群配合使用

本节介绍如何使用带有InnoDB集群的MySQL路由器来实现高可用性。 无论您是否部署了沙箱或生产群集,MySQL路由器都可以使用该 --bootstrap 选项 基于InnoDB群集的元数据进行自我配置 。 这会自动配置MySQL路由器以将连接路由到群集的服务器实例。 客户端应用程序连接到MySQL路由器提供的端口,无需了解InnoDB集群拓扑。 如果发生意外故障,InnoDB集群会自动调整,MySQL Router会检测到更改。 这消除了客户端应用程序处理故障转移的需要。 有关更多信息,请参阅 MySQL InnoDB集群的路由 。

注意

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

建议的MySQL路由器部署与应用程序位于同一主机上。 使用沙箱部署时,所有内容都在单个主机上运行,​​因此您将MySQL路由器部署到同一主机。 使用生产部署时,我们建议将一个MySQL路由器实例部署到用于托管其中一个客户端应用程序的每台计算机上。 还可以将MySQL路由器部署到应用程序实例连接的公共计算机。

假设已经 安装了MySQL路由器 (请参阅 安装MySQL路由器 ),请使用该 --bootstrap 选项提供属于InnoDB群集的服务器实例的位置。 MySQL路由器检索InnoDB集群的元数据,包括组成集群的服务器实例地址列表及其在集群中的角色。 您传递MySQL路由器应从中检索InnoDB群集元数据的服务器的URI类型字符串。 例如:

外壳> mysqlrouter --bootstrap ic@ic-1:3306 --user=mysqlrouter 

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

[metadata_cache:prodCluster]
Router_ID与= 1
bootstrap_server_addresses = MySQL的:// IC @ IC-1:3306,MySQL的:// IC @ IC-2:3306,MySQL的:// IC @ IC-3:3306
用户= mysql_router1_jy95yozko3k2
metadata_cluster = prodCluster
TTL = 300
小费

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

生成的MySQL路由器配置会创建用于连接到群集的TCP端口。 创建使用经典MySQL协议和X协议与群集通信的端口。 要使用X协议,服务器实例必须安装并配置X插件。 对于沙箱部署,实例会自动设置X插件。 对于生产部署,如果要使用X协议,则需要在每个实例上安装和配置X插件,请参阅 安装MySQL Shell 。 默认的可用TCP端口是:

  • 6446 - 对于经典MySQL协议读写会话,MySQL路由器将传入连接重定向到主服务器实例。

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

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

  • 64470 - 对于X协议只读会话,MySQL路由器将传入连接重定向到其中一个辅助服务器实例。

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

传入连接的重定向方式取决于所使用的群集类型。 使用单主群集时,默认情况下,MySQL路由器会发布X协议和经典协议端口,客户端连接到这些端口以进行读写会话,并重定向到群集的单个主节点。 使用多主群集时,读写会话将以循环方式重定向到其中一个主要实例。 例如,这意味着到端口6446的第一个连接将被重定向到ic-1实例,到端口6446的第二个连接将被重定向到ic-2实例,依此类推。 对于传入的只读连接,MySQL路由器还以循环方式将连接重定向到其中一个辅助实例。 routing_strategy 选项。

一旦引导和配置,启动MySQL路由器。 如果您使用带有该 --bootstrap 选项 的系统范围安装, 则发出:

外壳> mysqlrouter &

如果使用该 --directory 选项 将MySQL路由器安装到目录 ,请使用 start.sh 您安装目录中 的 脚本。 或者设置服务以在系统引导时自动启动MySQL路由器,请参阅 启动MySQL路由器 。 现在,您可以将MySQL客户端(如MySQL Shell)连接到其中一个传入的MySQL路由器端口,如上所述,并查看客户端如何透明地连接到其中一个InnoDB集群实例。

外壳> mysqlsh --uri root@localhost:6442

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

MySQL的-JS> \sql
切换到SQL模式...命令以;结尾;
MySQL的-SQL> select @@port;
+ -------- +
| @@ port |
+ -------- +
| 3310 |
+ -------- +

测试高可用性

要测试高可用性是否有效,请通过终止实例来模拟意外停止。 群集检测到实例离开群集并重新配置自身的事实。 群集重新配置的确切方式取决于您使用的是单主群集还是多主群集,以及实例在群集中所服务的角色。

在单主模式下:

  • 如果当前主节点离开集群,则其中一个辅助实例被选为新主节点,其中实例按最低值排列优先级 server_uuid 。 MySQL路由器将读写连接重定向到新选择的主节点。

  • 如果当前辅助节点离开群集,MySQL路由器将停止将只读连接重定向到该实例。

有关更多信息,请参见 第18.4.1.1节“单主模式” 。

在多主模式下:

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

有关更多信息,请参见 第18.4.1.2节“多主模式” 。

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

MySQL的-JS> dba.killSandboxInstance(3310)

群集会检测到更改并自动选择新的主数据库。 假设您的会话连接到端口6446(默认的读写经典MySQL协议端口),MySQL路由器应检测到群集拓扑的更改并将会话重定向到新选择的主节点。 要验证这一点,请使用该 \sql 命令 在MySQL Shell中切换到SQL模式, 然后选择实例的 port 变量以检查会话被重定向到的实例。 注意第一个 SELECT 语句失败,因为与原始主节点的连接丢失。 这意味着当前会话已关闭,MySQL Shell会自动为您重新连接,当您再次发出命令时,将确认新端口。

MySQL的-JS> \sql
切换到SQL模式...命令以;结尾;
MySQL的-SQL> SELECT @@port;
错误:2013(HY000):查询期间与MySQL服务器的连接丢失
全局会话断开了。
试图重新连接到'root @ localhost:6446'...
全球会议已成功重新连接。
MySQL的-SQL> SELECT @@port;
+ -------- +
| @@ port |
+ -------- +
| 3330 |
+ -------- +
1排(0.00秒)

在此示例中,端口3330处的实例已被选为新主节点。 这表明InnoDB集群为我们提供了自动故障转移,MySQL路由器自动将我们重新连接到新的主要实例,并且我们具有高可用性。

MySQL路由器和元数据服务器

当MySQL路由器针对群集进行引导时,它会在其配置文件中记录服务器实例的地址。 如果在引导MySQL路由器之后将任何其他实例添加到群集,则不会自动检测它们,因此 不会 将它们用于连接路由。

要确保新添加的实例正确路由,您必须针对群集引导MySQL路由器以读取更新的元数据。 这意味着您必须重新启动MySQL路由器并包含该 --bootstrap 选项。

21.4使用InnoDB集群

本节介绍如何使用InnoDB集群,以及如何处理常见的管理任务。

运用 dba.checkInstanceConfiguration()

在从服务器实例创建生产部署之前,您需要检查每个实例上的MySQL是否已正确配置。 除了 dba.configureInstance() 在配置实例时检查配置,您还可以使用该 dba.checkInstanceConfiguration() 功能。 这可确保实例满足 第21.2.2节“InnoDB群集要求”, 而无需更改实例上的任何配置。 这不会 检查实例 上的任何数据,请参阅 检查实例状态 以获取更多信息。 以下演示了在运行的MySQL Shell中发布它:

MySQL的-JS> dba.checkInstanceConfiguration('ic@ic-1:3306')
请提供“ic @ ic-1:3306”的密码:***
验证ic-1:3306上的MySQL实例,以便在InnoDB集群中使用...

此实例将其自己的地址报告为ic-1
默认情况下,客户端和其他集群成员将通过此地址与其进行通信。
如果这不正确,则应更改report_host MySQL系统变量。

检查现有表是否符合组复制要求...
未检测到不兼容的表

检查实例配置...

需要修复一些配置选项:
+ -------------------------- + -------- + ------ ---------- + --------------------------------------- ----------- +
| 变量| 当前价值| 必需值| 注意|
+ -------------------------- + -------- + ------ ---------- + --------------------------------------- ----------- +
| binlog_checksum | CRC32 | 没有| 更新服务器变量|
| enforce_gtid_consistency | 关闭| ON | 更新只读变量并重新启动服务器
| gtid_mode | 关闭| ON | 更新只读变量并重新启动服务器
| server_id | 1 | | 更新只读变量并重新启动服务器
+ -------------------------- + -------- + ------ ---------- + --------------------------------------- ----------- +

请使用dba.configureInstance()命令来修复这些问题。

{
    “config_errors”:[
        {
            “action”:“server_update”,
            “当前”:“CRC32”,
            “option”:“binlog_checksum”,
            “必需”:“无”
        },
        {
            “行动”:“重启”,
            “当前”:“关闭”,
            “选项”:“enforce_gtid_consistency”,
            “必需”:“开”
        },
        {
            “行动”:“重启”,
            “当前”:“关闭”,
            “选项”:“gtid_mode”,
            “必需”:“开”
        },
        {
            “行动”:“重启”,
            “当前”:“1”,
            “option”:“server_id”,
            “必需”:“”
        }
    ]
    “状态”:“错误”
}

对计划用作群集一部分的每个服务器实例重复此过程。 运行后生成的报告 dba.checkInstanceConfiguration() 提供有关所需的任何配置更改的信息,然后才能继续。 该 action 领域 config_error 的报告的部分告诉你的MySQL的实例是否需要重新启动才能检测对配置文件进行任何改变。

使用配置实例 dba.configureLocalInstance()

不支持持久配置更改的实例(请参阅 持久设置 )要求您连接到服务器,运行MySQL Shell,在本地连接到实例并发出问题 dba.configureLocalInstance() 。 这使MySQL Shell能够在针对远程实例运行以下命令后修改实例的选项文件:

  • dba.configureInstance()

  • dba.createCluster()

  • Cluster.addInstance()

  • Cluster.removeInstance()

  • Cluster.rejoinInstance()

重要

如果未将配置更改持久保存到实例的选项文件,则可能导致实例在下次重新启动后未重新加入群集。

建议的方法是登录远程计算机,例如使用SSH,以root用户身份运行MySQL Shell,然后连接到本地MySQL服务器。 例如,使用 --uri 选项连接到本地 instance :

外壳> sudo -i mysqlsh --uri=instance

或者,使用该 \connect 命令登录本地实例。 然后发出 , 本地实例的连接信息 在哪里 ,以保持对本地实例的选项文件所做的任何更改。 dba.configureInstance(instance) instance

mysql-js> dba.configureLocalInstance('ic @ ic-2:3306')
	

对群集中的每个实例重复此过程,该实例不支持自动进行持久配置更改。 例如,如果向群集添加2个不自动支持持久性配置更改的实例,则必须连接到每个服务器并在实例重新启动之前保留InnoDB群集所需的配置更改。 同样,如果您修改群集结构(例如更改实例数),则需要为每个服务器实例重复此过程,以便相应地为群集中的每个实例更新InnoDB群集元数据。

用。检索InnoDB集群 dba.getCluster()

使用时创建集群时 dba.createCluster() ,该操作将返回可以分配给变量的Cluster对象。 您可以使用此对象来处理群集,例如添加实例或检查群集的状态。 如果要在以后再次检索群集,例如在重新启动MySQL Shell之后,请使用该 功能。 例如: dba.getCluster([name],[options])

MySQL的-JS> var cluster1 = dba.getCluster()

如果未指定 name 群集,则返回默认群集。 默认情况下,MySQL Shell会在您使用时尝试连接到群集的主实例 dba.getCluster() 。 设置 connectToPrimary 选项以配置此行为。 如果 connectToPrimary 是 true 并且活动的全局MySQL Shell会话不是主实例,则查询群集以查找主要成员,并且群集对象连接到该主要成员。 如果群集中没有仲裁,则操作将失败。 如果 connectToPrimary 是 false ,则群集对象使用活动会话,换句话说,就是与MySQL Shell当前全局会话相同的实例。 如果 connectToPrimary 未指定,MySQL外壳中把 connectToPrimary 作为 true ,并回落到 connectToPrimary 是 false 。

要在获取群集时强制连接到辅助节点,请建立与群集的辅助成员的连接,并 connectToPrimary 通过发出以下命令来 使用该 选项:

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

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

使用检查群集的状态 Cluster.status()

群集对象提供了 status() 一种方法,使您可以检查群集的运行方式。 在检查InnoDB集群的状态之前,您需要通过连接到其任何实例来获取对InnoDB集群对象的引用。 但是,如果要更改群集的配置,则必须连接到“R / W”实例。 发出 status() 将根据您所连接的服务器实例知道的集群视图检索集群的状态并输出状态报告。

重要

集群中实例的状态直接影响状态报告中提供的信息。 因此,请确保您连接的实例的状态为 ONLINE 。

有关InnoDB集群如何运行的信息,请使用集群的 status() 方法:

mysql-js> var cluster = dba.getCluster()
mysql-js>cluster.status()
{
    “clusterName”:“testcluster”, 
    “defaultReplicaSet”:{
        “名称”:“默认”, 
        “primary”:“ic-1:3306”, 
        “ssl”:“必需的”, 
        “状态”:“好”, 
        “statusText”:“群集在线并且最多可以容忍一次失败。”, 
        “拓扑”:{
            “ic-1:3306”:{
                “地址”:“ic-1:3306”, 
                “模式”:“R / W”, 
                “readReplicas”:{}, 
                “角色”:“HA”, 
                “状态”:“在线”
            }, 
            “ic-2:3306”:{
                “地址”:“ic-2:3306”, 
                “模式”:“R / O”, 
                “readReplicas”:{}, 
                “角色”:“HA”, 
                “状态”:“在线”
            }, 
            “ic-3:3306”:{
                “地址”:“ic-3:3306”, 
                “模式”:“R / O”, 
                “readReplicas”:{}, 
                “角色”:“HA”, 
                “状态”:“在线”
            }
        }
    }, 
    “groupInformationSourceMember”:“mysql:// ic @ ic-1:3306”
}

输出 Cluster.status() 提供以下信息:

  • clusterName :在此期间分配给此群集的名称 dba.createCluster() 。

  • defaultReplicaSet :属于InnoDB集群并包含数据集的服务器实例。

  • primary :仅在群集以单主模式运行时显示。 显示当前主实例的地址。 如果未显示此字段,则群集将以多主模式运行。

  • ssl :群集是否使用安全连接。 显示的值 REQUIRED 或者 DISABLED ,这取决于如何 memberSslMode 选择在过程中,可以配置 createCluster() 或 addInstance() 。 此参数返回的值对应于 group_replication_ssl_mode 实例上的服务器变量 的值 。 请参阅 保护群集 。

  • status :群集的此元素的状态。 对于整个群集,它描述了此群集提供的高可用性。 状态为以下之一:

    • ONLINE :实例处于联机状态并参与群集。

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

    • RECOVERING :实例尝试通过在成为 ONLINE 成员 之前检索所需的事务来尝试与集群同步 。

    • UNREACHABLE :实例已丢失与群集的通信。

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

      重要

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

    • (MISSING) :作为已配置群集的一部分但实际上不可用的实例的状态。

      注意

      该 MISSING 状态特定于InnoDB集群,它不是Group Replication生成的状态。 MySQL Shell使用此状态来指示在元数据中注册但在实时群集视图中找不到的实例。

  • topology :已添加到群集的实例。

  • Host name of instance :实例的主机名,例如localhost:3310。

  • role :此实例在群集中提供的功能。 目前只有HA,具有高可用性。

  • mode :服务器是读写(“R / W”)还是只读(“R / O”)。 模式表示 R/W (可读和可写)或 R/O (只读)。 在单主模式下,只有标记为“R / W”的一个实例可以执行更新数据库的事务,因此它是主数据库。 如果该实例由于任何原因(例如意外暂停)而无法访问,则剩余的“R / O”实例之一将自动接管其位置并成为新的“R / W”主要实例。 在多主模式下,所有实例都标记为“R / W”,并且没有单个选定的主要实例。

  • groupInformationSourceMember :用于获取有关集群的信息的内部连接,显示为URI类型字符串。 通常最初用于创建集群的连接。

Cluster.status() 可以扩展操作 的输出, 以使您能够显示有关群集使用的基础组复制组的信息。 要查看有关信息 groupName , memberId , GRProtocolVersion -由组,以及有关交易检查,提出的一些一般性的统计数据使用的通信协议,并通过实例拒绝,问题:

Cluster.STATUS({扩展:真})
小费

InnoDB集群管理自动使用的 组复制协议, 有关详细信息 ,请参阅 InnoDB集群和组复制协议 。

要查看有关恢复和常规事务I / O,应用程序工作线程统计信息和任何滞后的信息; 应用程序协调器统计信息,如果启用了并行应用; 错误,以及来自I / O和应用程序线程问题的其他信息

Cluster.STATUS({queryMembers:真})

如果 queryMembers 设置为 true ,则会打开与群集中每个实例的连接,以便可以查询其他特定于实例的统计信息。 输出中包含的确切统计信息取决于实例的状态和配置以及服务器版本。 此信息与 replication_group_member_stats 表 中显示的信息相匹配 ,请参阅匹配列的说明。 ONLINE 具有 transactions 包含在输出中 的 对象的 实例 。 RECOVERING 具有 recovery 包含在输出中 的 对象的 实例 。 在任何一种情况下,对象都可以包含以下内容:

  • appliedCount :看 COUNT_TRANSACTIONS_REMOTE_APPLIED

  • checkedCount :看 COUNT_TRANSACTIONS_CHECKED

  • committedAllMembers :看 TRANSACTIONS_COMMITTED_ALL_MEMBERS

  • conflictsDetectedCount :看 COUNT_CONFLICTS_DETECTED

  • inApplierQueueCount :看 COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE

  • inQueueCount :看 COUNT_TRANSACTIONS_IN_QUEUE

  • lastConflictFree :看 LAST_CONFLICT_FREE_TRANSACTION

  • proposedCount :看 COUNT_TRANSACTIONS_LOCAL_PROPOSED

  • rollbackCount :看 COUNT_TRANSACTIONS_LOCAL_ROLLBACK

该 connection 部分显示了该 replication_connection_status 表 中的信息 。

该 currentlyQueueing 部分包含有关当前排队的交易的信息:

  • immediateCommitTimestamp :看 QUEUEING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP

  • immediateCommitToNowTime :见 QUEUEING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP 减号 NOW()

  • originalCommitTimestamp :看 QUEUEING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP

  • originalCommitToNowTime :见 QUEUEING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP 减号 NOW()

  • startTimestamp :看 QUEUEING_TRANSACTION_START_QUEUE_TIMESTAMP

  • transaction :看 QUEUEING_TRANSACTION

  • lastHeartbeatTimestamp :看 LAST_HEARTBEAT_TIMESTAMP

该 lastQueued 部分包含有关最近排队的事务的信息:

  • endTimestamp :看 LAST_QUEUED_TRANSACTION_END_QUEUE_TIMESTAMP

  • immediateCommitTimestamp :看 LAST_QUEUED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP

  • immediateCommitToEndTime : LAST_QUEUED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP 减去 NOW()

  • originalCommitTimestamp :看 LAST_QUEUED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP

  • originalCommitToEndTime : LAST_QUEUED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP 减去 NOW()

  • queueTime : LAST_QUEUED_TRANSACTION_END_QUEUE_TIMESTAMP 减去 LAST_QUEUED_TRANSACTION_START_QUEUE_TIMESTAMP

  • startTimestamp :看 LAST_QUEUED_TRANSACTION_START_QUEUE_TIMESTAMP

  • transaction :看 LAST_QUEUED_TRANSACTION

  • receivedHeartbeats :看 COUNT_RECEIVED_HEARTBEATS

  • receivedTransactionSet :看 RECEIVED_TRANSACTION_SET

  • threadId :看 THREAD_ID

使用多线程从属的实例有一个 workers 部分,其中包含有关工作线程的信息,并匹配 replication_applier_status_by_worker 表中 显示的信息 。

该 lastApplied 部分显示有关工作人员应用的上一个事务的以下信息:

  • applyTime :见 LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP 减号 LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP

  • endTimestamp :看 LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP

  • immediateCommitTimestamp :看 LAST_APPLIED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP

  • immediateCommitToEndTime :见 LAST_APPLIED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP 减号 NOW()

  • originalCommitTimestamp :看 LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP

  • originalCommitToEndTime :见 LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP 减号 NOW()

  • startTimestamp :看 LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP

  • transaction :看 LAST_APPLIED_TRANSACTION

该 currentlyApplying 部分显示有关工作程序当前正在应用的事务的以下信息:

  • immediateCommitTimestamp :看 APPLYING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP

  • immediateCommitToNowTime :见 APPLYING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP 减号 NOW()

  • originalCommitTimestamp :看 APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP

  • originalCommitToNowTime :见 APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP 减号 NOW()

  • startTimestamp :看 APPLYING_TRANSACTION_START_APPLY_TIMESTAMP

  • transaction :看 APPLYING_TRANSACTION

该 lastProcessed 部分包含有关工作人员处理的最后一个事务的以下信息:

  • bufferTime : LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP 减去 LAST_PROCESSED_TRANSACTION_START_BUFFER_TIMESTAMP

  • endTimestamp :看 LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP

  • immediateCommitTimestamp :看 LAST_PROCESSED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP

  • immediateCommitToEndTime : LAST_PROCESSED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP 减去 LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP

  • originalCommitTimestamp :看 LAST_PROCESSED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP

  • originalCommitToEndTime : LAST_PROCESSED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP 减去 LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP

  • startTimestamp :看 LAST_PROCESSED_TRANSACTION_START_BUFFER_TIMESTAMP

  • transaction :看 LAST_PROCESSED_TRANSACTION

如果启用了并行应用程序工作程序,则会包含workers数组中的对象数 transactions 或 recovery 匹配已配置工作程序数以及其他协调程序对象。 显示的信息与 replication_applier_status_by_coordinator 表 中的信息相匹配 。 该对象可以包含:

该 currentlyProcessing 部分包含有关工作人员正在处理的事务的以下信息:

  • immediateCommitTimestamp :看 PROCESSING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP

  • immediateCommitToNowTime : PROCESSING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP 减去 NOW()

  • originalCommitTimestamp :看 PROCESSING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP

  • originalCommitToNowTime : PROCESSING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP 减去 NOW()

  • startTimestamp :看 PROCESSING_TRANSACTION_START_BUFFER_TIMESTAMP

  • transaction :看 PROCESSING_TRANSACTION

worker 如果在 replication_applier_status_by_worker 表 中检测到错误,则对象具有以下信息 :

  • lastErrno :看 LAST_ERROR_NUMBER

  • lastError :看 LAST_ERROR_MESSAGE

  • lastErrorTimestamp :看 LAST_ERROR_TIMESTAMP

connection 如果在 replication_connection_status 表 中检测到错误,则对象具有以下信息 :

  • lastErrno :看 LAST_ERROR_NUMBER

  • lastError :看 LAST_ERROR_MESSAGE

  • lastErrorTimestamp :看 LAST_ERROR_TIMESTAMP

coordinator 如果在 replication_applier_status_by_coordinator 表 中检测到错误,则对象具有以下信息 :

  • lastErrno :看 LAST_ERROR_NUMBER

  • lastError :看 LAST_ERROR_MESSAGE

  • lastErrorTimestamp :看 LAST_ERROR_TIMESTAMP

InnoDB集群和组复制协议

从MySQL 8.0.16开始,Group Replication具有该组通信协议的概念,请参见 第18.4.2.4节“设置组的通信协议版本” 用于背景信息。 组复制通信协议版本通常必须显式管理,并设置为容纳您希望该组支持的最旧的MySQL服务器版本。 但是,只要使用AdminAPI操作更改集群拓扑,InnoDB集群就会自动且透明地管理其成员的通信协议版本。 群集始终使用当前属于群集或加入群集的所有实例都支持的最新通信协议版本。

  • 在集群中添加,删除或重新加入实例,或者在集群上执行重新扫描或重新引导操作时,通信协议版本将自动设置为现在最早的MySQL服务器实例所支持的版本版。

  • 当您通过从群集中删除实例,升级它们并将它们添加回群集来执行滚动升级时,当旧的MySQL Server版本中的最后一个剩余实例从群集中删除之前,通信协议版本会自动升级。它的升级。

要查看群集中使用的通信协议版本,请使用 启用 Cluster.status() 该 extended 选项的功能。 如果 GRProtocolVersion 群集具有仲裁且没有群集成员无法访问, 则会在 字段中 返回通信协议版本 。

运用 cluster.describe()

要获取有关InnoDB集群本身结构的信息,请使用以下 Cluster.describe() 函数:

MySQL的-JS> cluster.describe();
{
    “clusterName”:“testCluster”,
    “defaultReplicaSet”:{
        “名称”:“默认”,
        “拓扑”:[
            {
                “地址”:“ic-1:3306”,
                “label”:“ic-1:3306”,
                “角色”:“HA”
            },
            {
                “地址”:“ic-2:3306”,
                “label”:“ic-1:2306”,
                “角色”:“HA”
            },
            {
                “地址”:“ic-3:3306”,
                “label”:“ic-3:3306”,
                “角色”:“HA”
            }
        ]
    }
}

此函数的输出显示InnoDB集群的结构,包括其所有配置信息,等等。 地址,标签和角色值与“ 检查群集的状态”中 Cluster.status() 描述的值相匹配 。

在实例上检查MySQL版本

以下操作可以报告有关在实例上运行的MySQL Server版本的信息:

  • Cluster.status()

  • Cluster.describe()

  • Cluster.rescan()

行为因 Cluster 对象会话 的MySQL Server版本而异 。

  • Cluster.status()

    如果满足以下任一要求, version 则为对象的每个实例JSON对象返回字符串属性 topology :

    • 该 Cluster 对象的当前会话是8.0.11或更高版本。

    • 该 Cluster 对象的当前会话早于8.0.11版本和 queryMembers 选项启用。

    例如,在运行8.0.16版的实例上:

    “拓扑”:{
        “ic-1:3306”:{
            “地址”:“ic-1:3306”,
            “模式”:“R / W”,
            “readReplicas”:{},
            “角色”:“HA”,
            “状态”:“在线”,
            “版本”:“8.0.16”
    }
    

    例如,在运行版本5.7.24的实例上:

    “拓扑”:{
        “ic-1:3306”:{
            “地址”:“ic-1:3306”,
            “模式”:“R / W”,
            “readReplicas”:{},
            “角色”:“HA”,
            “状态”:“在线”,
            “版本”:“5.7.24”
    }
    
  • Cluster.describe()

    如果 Cluster 对象的当前会话是8.0.11版本或更高版本,一个 version 字符串属性,返回的是每个实例JSON对象 topology 对象

    例如,在运行8.0.16版的实例上:

    “拓扑”:[
        {
            “地址”:“ic-1:3306”,
            “label”:“ic-1:3306”,
            “角色”:“HA”,
            “版本”:“8.0.16”
        }
    ]
    
  • Cluster.rescan()

    如果 Cluster 对象的当前会话是8.0.11或更高版本,并且 Cluster.rescan() 操作检测到不属于该集群的实例, version 则会为该对象的每个实例JSON对象返回 一个 字符串属性 newlyDiscoveredInstance 。

    例如,在运行8.0.16版的实例上:

    “新发现的实例”:[
        {
            “主持人”:“ic-4:3306”,
            “member_id”:“82a67a06-2ba3-11e9-8cfc-3c6aa7197deb”,
            “name”:null,
            “版本”:“8.0.16”
        }
    ]	
    

超级只读和实例

每当组复制停止时,该 super_read_only 变量将设置 ON 为确保不对该实例进行写入。 当您尝试将此类实例与以下AdminAPI命令一起使用时,您可以选择 super_read_only=OFF 在实例上 进行设置 :

  • dba.configureInstance()

  • dba.configureLocalInstance()

  • dba.createCluster()

  • dba.rebootClusterFromCompleteOutage()

  • dba.dropMetadataSchema()

当AdminAPI遇到具有 super_read_only=ON 交互模式 的实例时, 您可以选择进行设置 super_read_only=OFF 。 例如:

MySQL的-JS> var myCluster = dba.createCluster('testCluster')
将在实例'ic @ ic-1:3306'上创建一个新的InnoDB集群。

'ic @ ic-1:3306'的MySQL实例目前有super_read_only 
系统变量设置为保护它免受应用程序的无意更新。 
您必须先取消设置才能对此实例执行任何更改。 
有关详细信息,请参阅:https://dev.mysql.com/doc/refman/en/server-system-variables.html#sysvar_super_read_only。

注意:有'ic @ ic-1:3306'的开放会话。
您可能希望终止这些会话以防止它们执行意外更新: 

1个开放会话'ic @ ic-1:3306'。 


你想禁用super_read_only并继续吗?[Y | N]:

	

显示实例的当前活动会话数。 您必须确保没有应用程序可能无意中写入该实例。 通过回答 y 您确认AdminAPI可以写入实例。 如果列出的实例有多个打开的会话,请在允许AdminAPI设置之前谨慎操作 super_read_only=OFF 。

要强制 super_read_only=OFF 在脚本中 设置函数,请将 clearReadOnly 选项设置为 true 。 例如 dba.configureInstance(instance, {clearReadOnly: true}).

配置实例的自动重新加入

运行MySQL 8.0.16及更高版本的实例支持组复制自动重新加入功能,这使您可以将实例配置为在被驱逐后自动重新加入群集。 有关 背景信息 , 请参见 第18.6.6节“对故障检测和网络分区的响应” 。 AdminAPI提供了一个 autoRejoinTries 选项,用于配置在驱逐后重新加入群集的尝试实例数。 默认情况下,实例不会自动重新加入群集。 您可以 autoRejoinTries 使用以下命令在集群级别或单个实例上 配置该 选项:

  • dba.createCluster()

  • Cluster.addInstance()

  • Cluster.setOption()

  • Cluster.setInstanceOption()

该 autoRejoinTries 选项接受介于0和2016之间的正整数值,默认值为0,这意味着实例不会尝试自动重新加入。 当您使用自动重新加入功能时,您的群集更容忍故障,尤其是诸如不可靠网络之类的临时故障。 但是,如果丢失了仲裁,则不应期望成员自动重新加入群集,因为大多数都需要重新加入实例。

运行MySQL 8.0.12及更高版本的实例具有 group_replication_exit_state_action 变量,您可以使用AdminAPI exitStateAction 选项 配置 该 变量 。 这可以控制在意外离开集群时实例执行的操作。 默认情况下,该 exitStateAction 选项 READ_ONLY, 意味着离开群集的实例意外地变为只读。 如果 exiStateAction 是 ABORT_SERVER 在意外离开集群的情况下,该实例将关闭MySQL,并且必须在它重新加入集群之前再次启动它。 请注意,当您使用自动重新加入功能时,由...配置的操作 exitStateAction 选项仅在所有重新加入群集的尝试失败时发生。

您可能有可能连接到实例并尝试使用AdminAPI进行配置,但此时实例可能正在重新加入群集。 只要您使用以下任何操作,就会发生这种情况:

  • Cluster.status()

  • dba.getCluster()

  • Cluster.rejoinInstance()

  • Cluster.addInstance()

  • Cluster.removeInstance()

  • Cluster.rescan()

  • Cluster.checkInstanceState()

当实例自动重新加入群集时,这些操作可能会提供额外信息。 此外,在使用时 Cluster.removeInstance() ,如果目标实例自动重新加入群集,则操作将中止,除非您传入 force:true 。

管理沙箱实例

沙箱实例运行后,可以使用以下方法随时更改其状态:

  • 停止使用沙盒实例 。 这样可以优雅地停止实例,与之不同 。 dba.stopSandboxInstance(instance) dba.killSandboxInstance(instance)

  • 要启动沙箱实例使用 。 dba.startSandboxInstance(instance)

  • 要杀死沙箱实例使用 dba.killSandboxInstance(instance) 。 这会在没有正常停止的情况下停止实例,并且在模拟意外停止时非常有用。

  • 要删除沙箱实例,请使用 。 这会从文件系统中完全删除沙箱实例。 dba.deleteSandboxInstance(instance)

从InnoDB集群中删除实例

如果您愿意,可以随时从群集中删除实例。 这可以使用该 方法 完成, 如下例所示: Cluster.removeInstance(instance)

MySQL的-JS> cluster.removeInstance('root@localhost:3310')

该实例将从InnoDB集群中删除。取决于实例
无论是否为Seed,元数据会话可能会变为无效。如果是的话,请
启动到Metadata Storage R / W实例的新会话。

试图离开组复制组...

已成功从群集中删除实例“localhost:3310”。

您可以选择传递 interactive 选项以控制是否提示您确认从群集中删除实例。 在交互模式下,系统会提示您继续删除实例(如果无法访问)。 该 cluster.removeInstance() 操作确保从所有集群成员 ONLINE 和实例本身 的元数据中删除 实例。

当被删除的实例具有仍然需要应用的事务时,AdminAPI会等待MySQL Shell dba.gtidWaitTimeout 选项为要应用的事务(GTID) 配置的秒数 。 MySQL Shell dba.gtidWaitTimeout 选项的默认值为60秒, 有关更改默认值的信息 ,请参阅 配置MySQL Shell选项 。 如果 dba.gtidWaitTimeout 在等待应用事务并且 force 选项 false (或未定义) 时达到 定义的超时值, 则会 发出错误并中止删除操作。 如果定义的超时值 dba.gtidWaitTimeout 在等待应用事务并且将该 force 选项设置为 true 然后操作继续而没有错误时到达,并从集群中删除该实例。

重要

该 force 选项仅应 在您要忽略任何错误时使用,例如未处理的事务或实例 ,并且不打算在集群中重用该实例。 从群集中删除实例时忽略错误可能导致实例与群集不同步,从而阻止其稍后重新加入群集。 当您计划不再使用群集中的实例时, 仅使用该 选项,在所有其他情况下,您应始终尝试恢复实例,并仅在可用且健康时将其删除,换句话说,使用状态 。 Cluster.removeInstance(instance) UNREACHABLE force ONLINE

自定义InnoDB集群

创建集群并向其添加实例时,AdminAPI会自动配置组名,本地地址和种子实例等值。 建议大多数部署使用这些默认值,但高级用户可以通过将以下选项传递给 dba.createCluster() 和 来覆盖默认值 Cluster.addInstance() 。

要自定义InnoDB集群创建的复制组的名称,请将该 groupName 选项 传递 给该 dba.createCluster() 命令。 这将设置 group_replication_group_name 系统变量。 该名称必须是有效的UUID。

要自定义实例为来自其他实例的连接提供的地址,请将 localAddress 选项 传递 给 dba.createCluster() 和 cluster.addInstance() 命令。 以格式指定地址 。 这将 在实例上 设置 系统变量。 该地址必须可供集群中的所有实例访问,并且必须仅为内部集群通信保留。 换句话说,不要使用此地址与实例进行通信。 host:port group_replication_local_address

要在实例加入群集时自定义用作种子的实例,请将 groupSeeds 选项 传递 给 dba.createCluster() 和 cluster.addInstance() 命令。 当新实例加入群集并用于向新实例提供数据时,将联系种子实例。 地址被指定为以逗号分隔的列表,例如 host1:port1 , host2:port2 。 这会配置 group_replication_group_seeds 系统变量。

有关更多信息,请参阅这些AdminAPI选项配置的系统变量的文档。

重新加入群集

如果实例离开集群,例如因为它丢失了连接,并且由于某种原因它无法自动重新加入集群,则可能需要在稍后阶段将其重新加入集群。 将实例重新加入群集问题 。 Cluster.rejoinInstance(instance)

小费

如果实例有, super_read_only=ON 那么您可能需要确认AdminAPI可以设置 super_read_only=OFF 。 有关 详细信息, 请参阅 超级只读和实例 。

如果实例尚未保持配置(请参阅 “保持设置” ),则重新启动后实例不会自动重新加入群集。 解决方案是发出 cluster.rejoinInstance() 以便将实例再次添加到集群并确保更改持久化。 将InnoDB集群配置持久保存到实例的选项文件后,它会自动重新加入集群。

如果要重新加入以某种方式更改的实例,则可能必须修改实例以使重新加入过程正常工作。 例如,在还原MySQL Enterprise Backup备份时,会进行 server_uuid 更改。 尝试重新加入此类实例失败,因为InnoDB集群实例由 server_uuid 变量 标识 。 在这种情况下, server_uuid 必须从InnoDB集群元数据中删除 有关实例旧的信息 ,然后 Cluster.rescan() 必须执行必须使用它的新实例将实例添加到元数据中 server_uuid 。 例如:

cluster.removeInstance(“root @ instanceWithOldUUID:3306”,{force:true})

cluster.rescan()

在这种情况下,您必须将 force 选项 传递 给 Cluster.removeInstance() 方法,因为从集群的角度来看实例是无法访问的,我们希望无论如何都要从InnoDB集群元数据中删除它。

从仲裁丢失中恢复群集

如果一个或多个实例失败,则群集可能会失去其仲裁,即能够在新主节点中投票。 如果存在足够实例的故障,组成群集的大多数实例不再对组复制操作进行投票,则会发生这种情况。 当群集丢失仲裁时,您无法再处理与群集的写入事务,也无法更改群集的拓扑,例如通过添加,重新加入或删除实例。 但是,如果您有一个包含InnoDB集群元数据的在线实例,则可以使用仲裁还原集群。 这假设您可以连接到包含InnoDB集群元数据的实例,

重要

此操作具有潜在的危险性,因为如果使用不当会导致裂脑情况,应该被视为最后的手段。 确保该组中没有仍在网络中运行的分区,但无法从您的位置访问。

连接到包含群集元数据的实例,然后使用该 操作,该操作将根据元数据恢复群集 ,然后 将从给定实例定义的角度来看的所有实例添加到已还原的群集。 Cluster.forceQuorumUsingPartitionOf(instance) instance ONLINE

MySQL的-JS> cluster.forceQuorumUsingPartitionOf("ic@ic-1:3306")

  通过使用由[ic @ ic-1:3306]组成的分区,从仲裁丢失中恢复复制集“默认”

  请提供“ic @ ic-1:3306”的密码:******
  恢复InnoDB集群......

  使用实例'ic @ ic-1:3306'中的分区成功恢复了InnoDB集群。

  警告:为避免裂脑情况,请确保复制的所有其他成员
  被删除或连接回已恢复的组。

如果实例未自动添加到群集,例如,如果其设置未保留,请使用 Cluster.rejoinInstance() 手动将实例添加回群集。

还原的群集可能不会也不必包含构成群集的所有原始实例。 例如,如果原始群集由以下五个实例组成:

  • ic-1

  • ic-2

  • ic-3

  • ic-4

  • ic-5

和群集经历脑分裂情况下,与 ic-1 , ic-2 ,和 ic-3 形成而一个分区 ic-4 和 ic-5 形成另一分区。 如果连接到 ic-1 并 Cluster.forceQuorumUsingPartitionOf('ic@ic-1:3306') 恢复群集,则生成的群集将包含以下三个实例:

  • ic-1

  • ic-2

  • ic-3

因为 ic-1 看到 ic-2 和 ic-3 作为 ONLINE ,不看 ic-4 和 ic-5 。

从主要中断重新启动群集

如果您的群集遭受完全中断,您可以确保使用正确的重新配置 dba.rebootClusterFromCompleteOutage() 。 此操作采用MySQL Shell当前连接的实例并使用其元数据来恢复群集。 如果群集的实例已完全停止,则必须启动实例,然后才能启动群集。 例如,如果已重新启动运行沙箱群集的计算机,并且实例位于端口3310,3320和3330,则发出:

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

这可确保沙盒实例正在运行。 在生产部署的情况下,您必须在MySQL Shell之外启动实例。 实例启动后,您需要连接到具有GTID超集的实例,这意味着在中断之前应用了最多事务的实例。 如果您不确定哪个实例包含GTID超集,请连接到任何实例并按照其中的交互消息进行操作 dba.rebootClusterFromCompleteOutage() ,该 消息 检测您连接的实例是否包含GTID超集。 通过发出以下命令重启群集:

MySQL的-JS> var cluster = dba.rebootClusterFromCompleteOutage();

然后, dba.rebootClusterFromCompleteOutage() 操作遵循以下步骤以确保正确地重新配置群集:

  • 检查在MySQL Shell当前连接的实例上找到的InnoDB集群元数据,以查看它是否包含GTID超集,换句话说,是集群应用的事务。 如果当前连接的实例不包含GTID超集,则操作将中止该信息。 有关更多信息,请参阅后续段落。

  • 如果实例包含GTID超集,则会根据实例的元数据恢复群集。

  • 假设您在交互模式下运行MySQL Shell,则会运行一个向导,检查当前可以访问哪个群集实例,并询问您是否要将任何已发现的实例重新加入重新引导的群集。

  • 同样,在交互模式下,向导还会检测当前无法访问的实例,并询问您是否要从重新引导的群集中删除此类实例。

如果您未使用MySQL Shell的交互模式,则可以使用 rejoinInstances 和 removeInstances 选项手动配置在重新引导群集期间应加入或删除的实例。

如果遇到错误,例如 活动会话实例与群集元数据的ONLINE实例相比不是最新的。 那么您连接的实例没有集群应用的事务的GTID超集。 在这种情况下,将MySQL Shell连接到错误消息中建议的实例并 dba.rebootClusterFromCompleteOutage() 从该实例 发出 。

小费

如果实例有, super_read_only=ON 那么您可能需要确认AdminAPI可以设置 super_read_only=OFF 。 有关 详细信息, 请参阅 超级只读和实例 。

要手动检测哪个实例具有GTID超集而不是使用交互式向导,请检查 gtid_executed 每个实例上 的 变量。 例如问题:

MySQL的-SQL> SHOW VARIABLES LIKE 'gtid_executed';

应用了最大 GTID 事务集 的实例 包含GTID超集。

如果此过程失败,并且群集元数据已严重损坏,则可能需要删除元数据并从头开始再次创建群集。 您可以使用删除群集元数据 dba.dropMetadataSchema() 。

警告

dba.dropMetadataSchema() 当无法恢复群集时, 该 方法应仅用作最后的手段。 它无法撤消。

重新扫描群集

如果对AdminAPI命令之外的集群进行配置更改(例如,通过手动更改实例的配置以解决配置问题或在实例丢失后),则需要更新InnoDB集群元数据,以使其与当前的配置相匹配实例。 在这些情况下,请使用该 Cluster.rescan() 操作,该操作使您可以手动或使用交互式向导更新InnoDB群集元数据。 该 Cluster.rescan() 操作可以检测未在元数据中注册的新活动实例并添加它们,或者仍然在元数据中注册的过时实例(不再活动),并将其删除。 您可以根据命令找到的实例自动更新元数据,也可以指定实例地址列表以添加元数据或从元数据中删除。 您还可以更新存储在元数据中的拓扑模式,例如在AdminAPI之外从单主模式更改为多主模式之后。

该命令的语法是 Cluster.rescan([options]) 。 该 options 词典支持以下内容:

  • interactive :boolean值,用于在命令执行中禁用或启用向导。 控制是否提供提示和确认。 默认值等于MySQL Shell向导模式,由 shell.options.useWizards 。

  • addInstances :list,其中包含要添加到元数据的新活动实例的连接数据,或者 “ auto ” 以自动将缺少的实例添加到元数据中。 值 “ auto ” 不区分大小写。

    • 列表中指定的实例将添加到元数据中,而不会提示进行确认

    • 在交互模式下,系统会提示您确认添加未包含在 addInstances 选项中 的新发现的实例

    • 在非交互模式下, addInstances 输出中会报告 未包含在 选项中的 新发现的实例 ,但不会提示您添加它们

  • removeInstances :list,包含要从元数据中删除的过时实例的连接数据,或 “ auto ” 以自动从元数据中删除过时的实例。

    • 列表中指定的实例将从元数据中删除,而不会提示进行确认

    • 在交互模式下,系统会提示您确认删除未包含在 removeInstances 选项中 的过时实例

    • 在非交互模式下, removeInstances 输出中会报告 未包含在 选项中的 过时实例, 但不会提示您删除它们

  • updateTopologyMode :boolean值,用于指示元数据中的拓扑模式(单主或多主)是否应更新(true)或不更新(false)以匹配群集使用的拓扑模式。 默认情况下,元数据不会更新(false)。

    • 如果值为, true 则将InnoDB集群元数据与Group Replication使用的当前模式进行比较,并在必要时更新元数据。 在AdminAPI之外更改群集的拓扑模式后,使用此选项更新元数据。

    • 如果值为, false 那么即使群集的拓扑模式与集群的组复制组使用的拓扑不同,也不会更新有关集群拓扑模式的InnoDB集群元数据

    • 如果未指定该选项且元数据中的拓扑模式与群集的“组复制”组使用的拓扑不同,则:

      • 在交互模式下,系统会提示您确认元数据中拓扑模式的更新

      • 在非交互模式下,如果群集的组复制组使用的拓扑与InnoDB群集元数据之间存在差异,则会报告该拓扑,并且不会对元数据进行任何更改

    • 更新元数据拓扑模式以匹配组复制模式时,将按 InnoDB集群和自动增量中 所述更新所有实例上的自动增量设置 。

检查实例状态

该 cluster.checkInstanceState() 函数可用于验证实例上的现有数据不会阻止它加入集群。 此过程通过验证实例的全局事务标识符(GTID)状态与集群已处理的GTID进行比较来工作。 有关 GTID的 更多信息,请参见 第17.1.3.1节“GTID格式和存储” 。 通过此检查,您可以确定是否可以将已处理事务的实例添加到集群。

以下演示了在运行的MySQL Shell中发布它:

MySQL的-JS> cluster.checkInstanceState('ic@ic-4:3306')

此函数的输出可以是以下之一:

  • OK new:实例没有执行任何GTID事务,因此它不能与集群执行的GTID冲突

  • OK可恢复:实例已执行GTID,这些GTID与集群种子实例的已执行GTID不冲突

  • 错误分歧:实例已执行GTID,该GTID与集群种子实例的已执行GTID不同

  • 错误lost_transactions:实例执行的GTID比集群种子实例的执行GTID更多

可以将具有“正常”状态的实例添加到群集,因为实例上的任何数据都与群集一致。 换句话说,正在检查的实例没有执行任何与集群执行的GTID冲突的事务,并且可以恢复到与其余集群实例相同的状态。

解散InnoDB集群

要解散InnoDB集群,您需要连接到读写实例,例如单主集群中的主实例,然后使用该 Cluster.dissolve() 命令。 这将删除与群集关联的所有元数据和配置,并禁用实例上的组复制。 不会删除在实例之间复制的任何数据。

重要

无法撤消群集的解散。 要再次创建它使用 dba.createCluster() 。

该 Cluster.dissolve() 操作只能配置 ONLINE 可访问的 实例 。 如果您发布的成员无法访问群集的成员 Cluster.dissolve() 命令你必须决定溶解操作应该如何进行。 如果您有可能想要重新加入群集中标识为丢失的任何实例,强烈建议取消溶解操作并首先将缺失的实例重新联机,然后再继续执行溶解操作。 这可以确保所有实例都可以正确更新其元数据,并且不会出现裂脑情况。 但是,如果群集中无法到达的实例已永久离开群集,则除了强制执行溶解操作之外别无选择,这意味着将忽略缺少的实例,并且只有在线实例会受到操作的影响。

警告

强制溶解操作忽略群集实例可能导致在溶解操作期间无法达到的实例继续操作,从而产生裂脑情况的风险。 如果您确定实例无法再次联机,则只强制解析操作以忽略丢失的实例。

在交互模式下,如果在解散操作期间无法访问群集的成员,则会显示交互式提示,例如:

MySQL的-JS> Cluster.dissolve()
群集仍具有以下已注册的ReplicaSet:
{
    “clusterName”:“testCluster”, 
    “defaultReplicaSet”:{
        “名称”:“默认”, 
        “拓扑”:[
            {
                “地址”:“ic-1:3306”, 
                “label”:“ic-1:3306”, 
                “角色”:“HA”
            }, 
            {
                “地址”:“ic-2:3306”, 
                “label”:“ic-2:3306”, 
                “角色”:“HA”
            }, 
            {
                “地址”:“ic-3:3306”, 
                “label”:“ic-3:3306”, 
                “角色”:“HA”
            }
        ]
    }
}
警告:您即将解散整个群集并失去高位
它提供的可用性功能。此操作无法恢复。所有
成员将从其副本集中删除,复制将被停止,
内部恢复用户帐户和群集元数据将被删除。用户
在所有情况下,数据都将保持不变。

您确定要解散群集吗?[y / N]:y

错误:实例'ic-2:3306'无法删除,因为它位于'(MISSING)'
州。请将实例重新置于ONLINE并尝试解散群集
再次。如果永久无法访问实例,则可以选择
继续操作并仅从群集中删除实例
元数据。

您是否仍想继续(仅删除实例元数据)?
[y / N]:y

实例'ic-3:3306'试图离开集群......实例'ic-1:3306'
正试图离开集群......

警告:群集已成功解散,但以下实例是
跳过:'ic-2:3306'。请确保此实例永久不可用
或采取任何必要的手动操作,以确保群集完全解散。

在此示例中,群集由三个实例组成,其中一个实例在发出dissolve时处于脱机状态。 捕获错误,您可以选择如何继续。 在这种情况下,将 ic-2 忽略 缺少的 实例,并且可访问的成员会更新其元数据。

当MySQL Shell以非交互模式运行时(例如,在运行批处理文件时),您可以 Cluster.dissolve() 使用该 force 选项 配置 操作 的行为 。 要强制解析操作忽略任何无法访问的实例,请发出:

MySQL的-JS> Cluster.dissolve({force: true})

可以从群集中删除任何可以访问的实例,并忽略任何无法访问的实例。 本节中有关强制从群集中删除缺失实例的警告同样适用于强制解散操作的此技术。

您还可以使用该 操作 interactive 选项 Cluster.dissolve() 覆盖运行MySQL Shell的模式,例如,在运行批处理脚本时显示交互式提示。 例如:

MySQL的-JS> Cluster.dissolve({interactive: true})

在 dba.gtidWaitTimeout mysql外壳选项配置多长时间 Cluster.dissolve() 操作等待从集群中去除目标实例之前被应用集群的交易,但前提是目标实例 ONLINE 。 如果在等待要删除的任何实例上应用集群事务时达到超时,则会发出错误,除非使用force:true,在这种情况下会跳过错误。

注意

发出后 cluster.dissolve() ,分配给该 Cluster 对象的 任何变量 都不再有效。

保护您的群集

可以将服务器实例配置为使用安全连接。 有关在MySQL中使用SSL的一般信息,请参见 第6.3节“使用加密连接” 。 本节介绍如何配置群集以使用SSL。 另一种安全可能性是配置哪些服务器可以访问群集,请参阅 创建服务器白名单 。

重要

配置群集以使用SSL后,必须将服务器添加到 ipWhitelist 。

使用 dba.createCluster() 设置群集时,如果服务器实例提供SSL加密,则会在种子实例上自动启用它。 将 memberSslMode 选项 传递 给 dba.createCluster() 方法以指定其他SSL模式。 群集的SSL模式只能在创建时设置。 该 memberSslMode 选项是一个字符串,用于配置要使用的SSL模式,默认为 AUTO 。 允许的值为 DISABLED , REQUIRED ,和 AUTO 。 这些模式定义为:

  • 设置 createCluster({memberSslMode:'DISABLED'}) 确保为群集中的种子实例禁用SSL加密。

  • createCluster({memberSslMode:'REQUIRED'}) 然后为群集中的种子实例启用 设置 SSL加密。 如果无法启用,则会引发错误。

  • 设置 createCluster({memberSslMode:'AUTO'}) (默认)然后,如果服务器实例支持,则自动启用SSL加密,如果服务器不支持,则禁用SSL加密。

注意

使用商业版MySQL时,默认情况下启用SSL,您可能需要为所有实例配置白名单。 请参阅 创建服务器白名单 。

发出 cluster.addInstance() 和 cluster.rejoinInstance() 命令时,将根据为种子实例找到的设置启用或禁用实例上的SSL加密。

当使用 createCluster() 与 adoptFromGR 选择采用现有的组复制组,无SSL设置改变所采用的集群:

  • memberSslMode 不能用 adoptFromGR 。

  • 如果采用的集群的SSL设置与MySQL Shell支持的SSL设置不同,换句话说,SSL用于组复制恢复和组通信,则不会修改这两个设置。 这意味着您无法向群集添加新实例,除非您手动更改所采用群集的设置。

MySQL Shell始终为群集复制和组通信启用或禁用群集的SSL,请参见 第18.5.2节“组复制安全套接字层(SSL)支持” 。 被执行的验证并且如果发出错误这些设置是用于种子实例(例如作为的结果不同 dba.createCluster() 使用 adoptFromGR 添加一个新的实例给集群时)。 必须为群集中的所有实例启用或禁用SSL加密。 执行验证以确保在向集群添加新实例时保持此不变量。

该 deploySandboxInstance() 命令默认尝试部署具有SSL加密支持的沙箱实例。 如果不可能,则在没有SSL支持的情况下部署服务器实例。 使用 ignoreSslError 选项设置为false可确保使用SSL支持部署沙箱实例,如果无法提供SSL支持,则会发出错误。 如果 ignoreSslError 为true(默认值),则在操作期间如果无法提供SSL支持且在没有SSL支持的情况下部署服务器实例,则不会发出错误。

创建服务器白名单

当使用群集的 createCluster() , addInstance() 和 rejoinInstance() 方法,您可以选择指定属于群集批准服务器,被称为白名单列表。 通过以这种方式明确指定白名单,您可以提高群集的安全性,因为只有白名单中的服务器才能连接到群集。 使用该 ipWhitelist 选项可 group_replication_ip_whitelist 在实例上 配置 系统变量。 默认情况下,如果未明确指定,白名单将自动设置为服务器具有网络接口的专用网络地址。 要配置白名单,请指定要添加的服务器 ipWhitelist 使用该方法时的选项。 将服务器作为逗号分隔列表传递,并用引号括起来。 例如:

MySQL的-JS> cluster.addInstance("ic@ic-3:3306", {ipWhitelist: "203.0.113.0/24, 198.51.100.110"})

这会将实例配置为仅接受来自地址 203.0.113.0/24 和 服务器的连接 198.51.100.110 。 白名单还可以包括主机名,只有在其他服务器发出连接请求时才会解析主机名。

警告

主机名本质上不如白名单中的IP地址安全。 MySQL执行FCrDNS验证,提供良好的保护级别,但可能会受到某些类型的攻击。 仅在严格必要时指定白名单中的主机名,并确保用于名称解析的所有组件(如DNS服务器)都在您的控制之下。 您还可以使用hosts文件在本地实现名称解析,以避免使用外部组件。

编写AdminAPI脚本

您可以使用脚本自动执行集群配置,这些脚本可以使用MySQL Shell运行。 例如:

外壳> mysqlsh -f setup-innodb-cluster.js
注意

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

示例脚本文件的内容如下所示:

print('MySQL InnoDB集群沙箱设置\ n');
打印( '================================== \ n');
print('设置带有3个MySQL服务器沙盒实例的MySQL InnoDB集群。\ n');
print('实例将安装在〜/ mysql-sandboxes。\ n');
print('它们将在端口3310,3320和3330上运行。\ n \ n');

var dbPass = shell.prompt('请输入MySQL root帐户的密码:',{type:“password”});

尝试{
   print('\ nDeploying the sandbox instances。');
   dba.deploySandboxInstance(3310,{password:dbPass});
   打印('。');
   dba.deploySandboxInstance(3320,{password:dbPass});
   打印('。');
   dba.deploySandboxInstance(3330,{password:dbPass});
   print('。\ nSandbox实例已成功部署。\ n \ n');

   print('设置InnoDB集群...... \ n');
   shell.connect('root @ localhost:3310',dbPass);

   var cluster = dba.createCluster(“prodCluster”);

   print('将实例添加到集群。');
   cluster.addInstance({user:“root”,host:“localhost”,port:3320,password:dbPass});
   打印('。');
   cluster.addInstance({user:“root”,host:“localhost”,port:3330,password:dbPass});
   print('。\ nInstances成功添加到集群。');

   print('\ nInnoDB集群已成功部署。\ n');
} catch(e){
   print('\ n无法创建InnoDB集群。\ n \ n错误:'+
   + e.message +'\ n');
}

配置选举过程

您可以选择配置单主群集如何选择新主节点,例如,将一个实例作为新主节点进行故障转移。 使用该 memberWeight 选项并 在创建群集时 将其传递给 dba.createCluster() and Cluster.addInstance() 方法。 该 memberWeight 选项接受0到100之间的整数值,该值是故障转移时自动主要选举的百分比权重。 当实例具有更高的设置的百分比数时 memberWeight ,更有可能在单主群集中被选为主要。 当主要选举发生时,如果多个实例具有相同的选举 memberWeight 然后,根据字典顺序(最低)的服务器UUID并选择第一个实例来确定实例的优先级。

设置值 memberWeight 可以 group_replication_member_weight 在实例上 配置 系统变量。 组复制将值范围限制为0到100,如果提供更高或更低的值,则自动调整它。 如果未提供任何值,则组复制使用默认值50。 更多信息 , 请参见 第18.4.1.1节“单主模式” 。

例如,要配置一个群集,其中 ic-3 首选实例要故障转移到 ic-1 当前主节点,意外地离开群集 memberWeight ,如下所示:

dba.createCluster('cluster1',{memberWeight:35})
var mycluster = dba.getCluster()
mycluster.addInstance('ic @ ic2',{memberWeight:25})
mycluster.addInstance('ic @ ic3',{memberWeight:50})

配置故障转移一致性

如果主要故障转移在单主模式下发生,则 组复制可以指定故障转移保证(最终或 “ 读取您的写入 ” )(请参见 第18.4.3.2节“配置事务一致性保证” )。 您可以在创建时配置InnoDB集群的故障转移保证,方法是将该 consistency 选项(在8.0.14版中,此选项 failoverConsistency 是现已弃用 的 选项)传递给 dba.createCluster() 操作,该操作将配置 group_replication_consistency 种子实例上的系统变量。 此选项定义在单主组中选择新主节点时使用的新防护机制的行为。 防护限制连接从新主节点写入和读取,直到它应用来自旧主节点的任何挂起的更改积压(有时称为 “ 读取您的写入 ” )。 当防护机制到位时,应用程序实际上不会在应用任何积压的情况下在短时间内向后看时间。 这可确保应用程序不会从新选择的主节点中读取过时信息。

consistency 仅当目标MySQL服务器版本为8.0.14或更高版本时才支持 该 选项,并且添加到已使用该 consistency 选项 配置的群集的实例将 自动配置为 group_replication_consistency 在支持该选项的所有集群成员上具有相同的 实例 。 变量默认值由组复制控制,并且 EVENTUAL 将 consistency 选项 更改 BEFORE_ON_PRIMARY_FAILOVER 为启用防护机制。 或者,使用 consistency=0 了 EVENTUAL 和 consistency=1 为 BEFORE_ON_PRIMARY_FAILOVER 。

注意

consistency 在多主要InnoDB集群上 使用该 选项没有任何效果,但是允许这样做,因为稍后可以通过该 Cluster.switchToSinglePrimaryMode() 操作 将集群更改为单主模式 。

更改群集的拓扑

默认情况下,InnoDB集群以单主模式运行,其中集群具有一个接受读写查询(R / W)的主服务器,并且集群中的所有其余实例仅接受读取查询(R / O) 。 当您将群集配置为在多主模式下运行时,群集中的所有实例都是主要的,这意味着它们同时接受读取和写入查询(R / W)。 如果群集的所有实例都运行MySQL服务器版本8.0.15或更高版本,则可以在群集联机时更改群集的拓扑。 在以前的版本中,必须完全解散并重新创建群集以进行配置更改。 第18.4.2节“配置在线组” ,因此您应遵守配置在线组的规则。

注意

多主模式被认为是高级模式

通常,当主节点意外离开集群时,单主节点会选择新的主节点,例如由于意外停止。 选举过程通常用于选择当前的第二个成为新的主要成员。 要覆盖选举过程并强制特定服务器成为新主服务器,请使用该 函数,其中 指定与应成为新主服务器的实例的连接。 这使您可以配置基础组复制组以选择特定实例作为新主服务器,从而绕过选举过程。 Cluster.setPrimaryInstance(instance) instance

您可以使用以下操作更改在单主服务器和多主服务器之间运行集群的模式(有时称为拓扑):

  • Cluster.switchToMultiPrimaryMode() ,将群集切换到多主模式。 所有实例都成为初选。

  • Cluster.switchToSinglePrimaryMode([instance]) ,将群集切换到单主模式。 如果 instance 指定,则它将成为主要实例,所有其他实例将成为辅助实例。 如果 instance 未指定,则新主节点是具有最高成员权重的实例(如果成员权重相关,则为最低UUID)。

设置InnoDB集群的选项

您可以在实例联机时检查和修改InnoDB群集的适当设置。 要检查群集的当前设置,请使用以下操作:

  • Cluster.options() ,列出其副本服务器和实例的集群配置选项。 all 还可以指定 布尔选项 以包含有关输出中所有组复制系统变量的信息。

您可以在集群级别或实例级别配置InnoDB集群的选项,同时实例保持联机状态。 这样就无需删除,重新配置,然后再添加实例来更改InnoDB集群选项。 使用以下操作:

  • Cluster.setOption(option, value) 全局更改所有群集实例的设置或群集全局设置,例如 clusterName 。

  • Cluster.setInstanceOption(instance, option, value) 更改单个群集实例的设置

将InnoDB集群选项与列出的操作一起使用的方式取决于是否可以将选项更改为在所有实例上都相同。 这些选项在群集(所有实例)和每个实例级别都是可更改的:

  • exitStateAction

  • memberWeight

此选项仅在每个实例级别可更改:

  • label

这些选项仅在群集级别可更改:

  • consistency

  • expelTimeout

  • clusterName

InnoDB集群和自动增量

当您将实例用作InnoDB集群的一部分时,将 配置 auto_increment_increment 和 auto_increment_offset 变量以避免多主集群自动增量冲突的可能性,最大为9(组复制组的最大支持大小)。 用于配置这些变量的逻辑可以概括为:

21.5已知限制

本节介绍InnoDB集群的已知限制。 由于InnoDB集群使用组复制,您还应该了解其局限性,请参见 第18.9.2节“组复制限制” 。

  • 如果在创建全局会话时未指定会话类型,则MySQL Shell会提供自动协议检测,尝试首先创建NodeSession,如果失败则尝试创建ClassicSession。 InnoDB集群由三个服务器实例组成,其中有一个读写端口和两个只读端口,这可能导致MySQL Shell只连接到其中一个只读实例。 因此,建议在创建全局会话时始终指定会话类型。

  • 将非沙盒服务器实例(您已手动配置而非使用的实例 dba.deploySandboxInstance() )添加到群集时,MySQL Shell无法在实例的配置文件中保留任何配置更改。 这导致以下一种或两种情况:

    1. 组复制配置不会保留在实例的配置文件中,并且在重新启动时,实例不会重新加入群集。

    2. 该实例对群集使用无效。 尽管可以使用实例验证实例 dba.checkInstanceConfiguration() ,并且MySQL Shell进行必要的配置更改以使实例为群集使用做好准备,但这些更改不会在配置文件中保留,因此一旦重新启动就会丢失。

    如果仅 a 发生,则重新启动后实例不会重新加入群集。

    如果 b 也发生了,并且您发现重新启动后实例未重新加入群集,则无法使用 dba.rebootClusterFromCompleteOutage() 此情况下 建议 的群集重新联机。 这是因为实例丢失了MySQL Shell所做的任何配置更改,并且由于它们没有持久化,因此在为群集配置之前,实例将恢复到先前的状态。 这会导致组复制停止响应,最终命令超时。

    为避免此问题,强烈建议 dba.configureInstance() 在将实例添加到群集之前 使用 ,以便持久保存配置更改。

  • --defaults-extra-file InnoDB集群服务器实例不支持 使用 选项指定选项文件。 InnoDB集群仅支持实例上的单个选项文件,并且不支持额外的选项文件。 因此,对于使用实例的选项文件的任何操作,应指定主要操作。 如果要使用多个选项文件,则必须手动配置文件,并确保它们已正确更新,并考虑使用多个选项文件的优先级规则,并确保所选设置不会被额外无法识别的选项中的选项错误地覆盖文件。

  • 尝试使用具有解析为与真实网络接口不匹配的IP地址的主机名的实例失败,并显示错误: 此实例将其自己的地址报告为 the hostname 。 组复制通信层不支持此功能。 在基于Debian的实例上,这意味着实例不能使用地址,例如 user@localhost 因为localhost解析为不存在的IP(例如127.0.1.1)。 这会影响使用沙盒部署,沙盒部署通常在单个计算机上使用本地实例。

    解决方法是 report_host 在每个实例上 配置 系统变量以使用计算机的实际IP地址。 检索计算机的IP并添加 到 每个实例 的 文件中。 您需要确保然后重新启动实例以进行更改。 report_host=IP of your machine my.cnf

原文