20.2.5 InnoDB 集群的生产部署

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

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

图 20.2 生产部署

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

Important

与沙盒部署不同,在沙盒部署中,所有实例都本地部署到一台计算机上,对于生产部署,必须在实例上发出dba.configureLocalInstance()之前连接到每台计算机并在本地运行 MySQL Shell。这样可以确保所有配置更改都可持久保存到实例的选项文件中。这还要求您有权访问服务器并具有执行 MySQL Shell 所需的权限。

要将服务器的连接信息传递给 AdminAPI,请使用 URI 类型字符串。有关更多信息,请参见使用类似 URI 的连接字符串进行连接

User Privileges

用于 Management 实例的用户帐户不必是 root 帐户,但是除了完整的 MySQLManagement 员特权(SUPERGRANT OPTIONCREATEDROP)之外,还需要为用户分配 InnoDB 集群元数据 table 的完全读写特权。等等)。创建用户以 Management 集群的首选方法是将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;

在此过程中,示例中使用了用户ic

Configuring Hostname

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

  • 配置每台计算机以将其他计算机的 IPMap 到主机名。有关详细信息,请参见您的 os 文档。这是推荐的解决方案。

  • 设置 DNS 服务

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

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

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

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

Verbose Logging

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

shell> mysqlsh --log-level=DEBUG3

建议使用DEBUG3,有关更多信息,请参见--log-level。设置DEBUG3时,MySQL Shell 日志文件包含诸如Debug: execute_sql( ... )之类的行,其中包含作为每个 AdminAPI 调用的一部分执行的 SQL 查询。对于基于 Unix 的系统,MySQL Shell 生成的日志文件位于~/.mysqlsh/mysqlsh.log中;在 Microsoft Windows 系统上,它位于%APPDATA%\MySQL\mysqlsh\mysqlsh.log中。有关更多信息,请参见MySQL Shell 日志记录和调试

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

mysql-js> dba.verbose=2

这将启用 AdminAPI 调用的最大输出。可用的输出级别为:

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

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

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

检查实例配置

从服务器实例创建生产部署之前,需要检查每个实例上的 MySQL 是否已使用dba.checkInstanceConfiguration()函数正确配置。这样可以确保实例满足第 20.2.2 节“ InnoDB 集群要求”。这不会检查实例上的任何数据,有关更多信息,请参见检查实例状态。下面演示了如何在运行中的 MySQL Shell 中发布此代码:

mysql-js> dba.checkInstanceConfiguration('ic@ic-1:3306')

Please provide the password for 'ic@ic-1:3306':
Validating instance...

The instance 'ic-1:3306' is not valid for Cluster usage.

The following issues were encountered:

- Some configuration options need to be fixed.

+----------------------------------+---------------+----------------+--------------------------------------------------+
| Variable                         | Current Value | Required Value | Note                                             |
+----------------------------------+---------------+----------------+--------------------------------------------------+
| binlog_checksum                  | CRC32         | NONE           | Update the server variable or restart the server |
| enforce_gtid_consistency         | OFF           | ON             | Restart the server                               |
| gtid_mode                        | OFF           | ON             | Restart the server                               |
| log_bin                          | 0             | 1              | Restart the server                               |
| log_slave_updates                | 0             | ON             | Restart the server                               |
| master_info_repository           | FILE          | TABLE          | Restart the server                               |
| relay_log_info_repository        | FILE          | TABLE          | Restart the server                               |
| transaction_write_set_extraction | OFF           | XXHASH64       | Restart the server                               |
+----------------------------------+---------------+----------------+--------------------------------------------------+

Please fix these issues , restart the server and try again.

{
  "config_errors": [
    {
      "action": "server_update",
      "current": "CRC32",
      "option": "binlog_checksum",
      "required": "NONE"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "enforce_gtid_consistency",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "gtid_mode",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "0",
      "option": "log_bin",
      "required": "1"
    },
    {
      "action": "restart",
      "current": "0",
      "option": "log_slave_updates",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "FILE",
      "option": "master_info_repository",
      "required": "TABLE"
    },
    {
      "action": "restart",
      "current": "FILE",
      "option": "relay_log_info_repository",
      "required": "TABLE"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "transaction_write_set_extraction",
      "required": "XXHASH64"
    }
  ],
  "errors": [],
  "restart_required": true,
  "status": "error"
}
mysql-js>

对计划用作群集一部分的每个服务器实例重复此过程。运行dba.checkInstanceConfiguration()之后生成的报告提供了有关在 continue 之前所需的任何配置更改的信息。报告最后部分的restart_required字段告诉您实例上的 MySQL 是否需要重新启动才能检测到对配置文件所做的任何更改。

配置实例

如果在针对实例运行dba.checkInstanceConfiguration()所生成的报告中已确定配置问题,则它不满足第 20.2.2 节“ InnoDB 集群要求”的要求。因此,您需要连接到计算机并重新配置服务器实例。 AdminAPI 提供了dba.configureLocalInstance()函数,该函数查找 MySQL 服务器的选项文件并对其进行修改,以确保为 InnoDB 集群正确配置了实例。或者,根据报告中的信息手动更改实例的选项文件。有关更多信息,请参见第 4.2.2.2 节“使用选项文件”。无论您以何种方式进行配置更改,都可能必须重新启动 MySQL 以确保检测到配置更改。

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

shell> sudo -i mysqlsh --log-level=DEBUG3

dba.configureLocalInstance()方法验证是否有合适的用户可用于群集使用,该用户用于群集成员之间的连接。默认情况下,root 用户无法执行远程登录,因此,您有三个选项可以 continue 进行配置:为 root 用户启用远程连接,创建新用户或前两个选项都不是。以下示例演示了第二个选项,即创建一个新用户以使用集群。接受的用户名格式遵循标准的 MySQL 帐户名格式,请参见第 6.2.4 节“指定帐户名”

mysql-js> dba.configureLocalInstance('root@localhost:3306')

Please provide the password for 'root@localhost:3306':

Please specify the path to the MySQL configuration file: /etc/mysql/mysql.conf.d/mysqld.cnf
Validating instance...

The configuration has been updated but it is required to restart the server.
{
  "config_errors": [
    {
      "action": "restart",
      "current": "OFF",
      "option": "enforce_gtid_consistency",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "gtid_mode",
      "required": "ON"
      },
    {
      "action": "restart",
      "current": "0",
      "option": "log_bin",
      "required": "1"
    },
    {
      "action": "restart",
      "current": "0",
      "option": "log_slave_updates",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "FILE",
      "option": "master_info_repository",
      "required": "TABLE"
    },
    {
      "action": "restart",
      "current": "FILE",
      "option": "relay_log_info_repository",
      "required": "TABLE"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "transaction_write_set_extraction",
      "required": "XXHASH64"
    }
  ],
  "errors": [],
  "restart_required": true,
  "status": "error"
}
mysql-js>

Tip

如果实例具有super_read_only=ON,则可能需要确认 AdminAPI 可以设置super_read_only=OFF。有关更多信息,请参见超级只读和实例

dba.checkInstanceConfiguration()一样,标识了配置要求,但是这次修改了所选的配置文件。为了使配置更改生效,您可能需要重新启动 MySQL Server。

dba.configureLocalInstance()函数还接受clusterAdminclusterAdminPassword选项,这使您可以在调用函数时配置集群用户和密码。 clusterAdmin支持用户名和主机名的标识符或字符串。默认情况下,如果不加引号,则假定 Importing 为字符串。例如:

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

授予该用户User Privileges中描述的 Management 用户的特权。

创建集群

准备好实例后,使用dba.createCluster()函数创建集群。您在其上运行 MySQL Shell 的计算机用作群集的种子实例。种子实例将复制到您添加到群集中的其他实例,从而使它们成为种子实例的副本。登录到实例并在本地运行 MySQL Shell。

shell> mysqlsh --uri ic@ic-1:3306

Creating a Session to 'ic@ic-1:3306'
Enter password: *********
Classic Session successfully established. No default schema selected.

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

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

      A new InnoDB cluster will be created on instance 'ic@ic-1:3306'.

      Creating InnoDB cluster 'prodCluster' on 'ic@ic-1:3306'...
      Adding Seed Instance...

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

Tip

如果实例具有super_read_only=ON,则可能需要确认 AdminAPI 可以设置super_read_only=OFF。有关更多信息,请参见超级只读和实例

Note

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

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

Tip

一旦服务器实例属于群集,仅使用 MySQL Shell 和 AdminAPI 对其进行 Management 就很重要。不支持在实例上将组复制添加到群集后对其进行手动更改的尝试。同样,不支持在使用 AdminAPI 配置实例后修改对 InnoDB 群集至关重要的服务器变量,例如server_uuid

使用cluster.addInstance(instance)函数向集群添加更多实例,其中* instance *是用于连接到本地实例的 URI 类型字符串。必须已为群集使用配置了实例。集群中至少需要三个实例,以使其能够容忍一个实例的故障。添加更多实例会增加实例失败的容忍度。要将实例添加到集群问题:

mysql-js> cluster.addInstance('ic@ic-2:3306');

要验证是否已添加实例,请使用群集实例的status()函数。

Important

在此阶段,服务器实例已添加到集群,但是 InnoDB 集群元数据的更改仅在当前连接到的实例上进行。要使配置更改对于集群中的所有实例持久存在,必须连接到每个实例,并在添加的每个实例上本地发出dba.configureLocalInstance()。这对于确保实例在离开集群时重新加入集群至关重要。

要为所有实例保留 InnoDB 集群元数据,请登录到添加到集群的每个实例,然后在本地运行 MySQL Shell。

shell> mysqlsh

使用\connect命令登录 MySQL 服务器。执行dba.configureLocalInstance('instance')函数,其中* instance *是连接到本地实例的 URI 类型字符串。例如:

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

Tip

如果实例具有super_read_only=ON,则可能需要确认 AdminAPI 可以设置super_read_only=OFF。有关更多信息,请参见超级只读和实例

对添加到群集的每个服务器实例重复此过程。同样,如果您修改集群结构(例如,更改实例数),则需要对每个服务器实例重复此过程,以相应地为集群中的每个实例更新 InnoDB 集群元数据。

部署群集后,可以配置 MySQLRouter 以提供高可用性,请参阅第 20.3 节“将 MySQLRouter 与 InnoDB 集群一起使用”