参考官方文档:
https://dev.mysql.com/doc/refman/5.7/en/mysql-innodb-cluster-creating.html
20.2.1 实施方案
InnoDB集群支持以下部署方案:
- Sandbox deployment:如果要在提交完整生产部署之前测试InnoDB集群,则提供的沙箱功能使您可以在本地计算机上快速设置集群。 使用所需配置创建沙盒服务器实例,您可以尝试InnoDB集群以熟悉所使用的技术。
- Production deployment:如果要在完整生产环境中使用InnoDB集群,则需要配置所需数量的计算机,然后将服务器实例部署到计算机上。 通过生产部署,您可以充分利用InnoDB集群的高可用性功能。
重要
sanbox部署不适合在完整的生产环境中使用。
20.2.2 InnoDB 集群需求
在安装InnoDB集群的生产部署之前,请确保您要使用的服务器实例满足以下要求。
- InnoDB集群使用组复制,因此您的服务器实例必须满足相同的要求。 请参见第17.7.1节“组复制要求”。 AdminAPI提供dba.checkInstanceConfiguration()方法以验证实例是否满足组复制要求,并使用dba.configureLocalInstance()方法配置实例以满足要求。
注意:
使用sandbox部署时,实例将自动被配置满足这些要求。
- MySQL Shell用于配置在InnoDB集群中使用的服务器的配置脚本需要访问Python 2.7版。 对于sandbox部署,在用于部署的单台机器上需要Python,生产部署需要在每个服务器实例上部署Python。
在Windows上,MySQL Shell包含Python,不需要用户配置。 在Unix上,必须将Python作为shell环境的一部分。 要检查您的系统是否正确配置了Python,请发出:
/usr/bin/env python
如果Python解释器启动,则无需进一步操作。 如果上一个命令失败,请在/usr/bin/python和您选择的Python二进制文件之间创建一个软链接。
20.2.3 安装的方式
用于安装InnoDB集群的方法取决于您打算使用的部署类型。 对于sandbox部署,将InnoDB集群的组件安装到单个计算机上。 sandbox部署是单个计算机的本地部署,因此安装只需在本地计算机上完成一次。 同样,不需要单独连接到实例进行配置,sandbox实例是本地的。 对于生产部署,请将组件安装到要添加到群集的每台计算机上。 生产部署使用运行MySQL服务器实例的多个远程主机,因此您需要使用SSH或Windows远程桌面等工具连接到每台计算机,以执行安装组件和配置服务器实例等任务。 可以使用以下安装InnoDB集群的方法:
使用以下文档下载和安装组件:
- MySQL Server - see Chapter 2, Installing and Upgrading MySQL.
- MySQL Shell - see Section 19.3.1, “Installing MySQL Shell”.
- MySQL Router - see Installing MySQL Router.
一点安装好所需的软件,那么就可以选择部署方式了
20.2.4 InnoDB 集群的 sandbox 部署
本节介绍如何设置sandbox InnoDB集群部署。 您可以使用包含AdminAPI的MySQL Shell创建和管理InnoDB集群。 本节假设您熟悉MySQL Shell,请参阅MySQL Shell 8.0(https://dev.mysql.com/doc/mysql-shell/8.0/en/)(MySQL 8.0的一部分)以获取更多信息。
初部署和使用MySQL的本地sandbox 实例是开始探索InnoDB集群的好方法。 在生产服务器上部署之前,您可以在本地完全测试InnoDB集群。 MySQL Shell具有内置功能,可为在本地部署方案中,对使用组复制的sandbox实例创建正确配置。
部署 sandbox 实例
MySQL Shell包含AdminAPI,它添加了dba全局变量,该变量提供了管理sandbox 实例的功能。 在此示例设置中,您使用dba.deploySandboxInstance()创建三个沙箱实例。
通过发出命令从命令提示符启动MySQL Shell:
shell> mysqlsh
除了本机SQL模式之外,MySQL Shell还提供两种脚本语言模式,JavaScript和Python。 在本指南中,MySQL Shell主要用于JavaScript模式。 当MySQL Shell启动时,它默认处于JavaScript模式。 通过为JavaScript模式发出\js来切换模式,为py模式发出\py,为SQL模式发出\sql。 通过发出\js命令确保您处于JavaScript模式,然后执行:
mysql-js> dba.deploySandboxInstance(3310)
注意:
在JavaScript和Python模式下,不需要使用分号终止命令。
传递给deploySandboxInstance()的参数是MySQL服务器实例侦听连接的TCP端口号。 默认情况下,sandbox是在Unix系统上名为$ HOME/mysql-sandboxes/port的目录中创建的。 对于Microsoft Windows系统,该目录为%userprofile%\MySQL\mysql-sandboxes\port。
将提示实例的root密码。
重要:
每个实例都有自己的密码。 在本教程中为所有沙箱定义相同的密码使其更容易,但请记住在生产部署中为每个实例使用不同的密码。
要部署其他sandbox服务器实例,请在端口3310处重复沙盒实例所遵循的步骤,选择不同的端口号。 对于每个其他sandox实例发布:
mysql-js> dba.deploySandboxInstance(port_number)
要遵循本教程,请为三个sandbox服务器实例使用端口号3310,3320和3330。 发布:
mysql-js> dba.deploySandboxInstance(3320)
mysql-js> dba.deploySandboxInstance(3330)
创建 sandbox InnoDB 集群
下一步是在连接到种子MySQL Server实例时创建InnoDB集群。 种子实例包含要复制到其他实例的数据。 在此示例中,sandbox实例为空白的,因此我们可以选择任何实例。
将MySQL Shell连接到种子实例,在本例中是端口3310处的实例:
mysql-js> \connect root@localhost:3310
\connect MySQL Shell命令是shell.connect()方法的快捷方式:
mysql-js> shell.connect('root@localhost:3310')
连接后,AdminAPI可以写入本地实例的选项文件。 这与使用生产部署不同,在生产部署中,您需要连接到远程实例并在实例上本地运行MySQL Shell应用程序,然后AdminAPI才能写入实例的选项文件。
使用dba.createCluster()方法创建InnoDB集群,并将当前连接的实例作为种子:
mysql-js> var cluster = dba.createCluster('testCluster')
createCluster()方法将InnoDB集群元数据部署到选定的实例,并将当前连接的实例添加为种子实例。 createCluster()方法返回被创建的集群,在上面的示例中,它被分配给集群变量。 传递给createCluster()方法的参数是赋予此InnoDB集群的符号名称,在本例中为testCluster。
Tip
如果实例的super_read_only = ON,则可能需要确认AdminAPI可以设置super_read_only = OFF。
将实例添加到InnoDB群集
下一步是向InnoDB集群添加更多实例。 由种子实例执行的任何事务都会在添加时由每个辅助实例重新执行。 本教程使用先前在端口3320和3330创建的sandbox实例。
近创建了此示例中的种子实例,因此它几乎为空。 因此,几乎没有需要从种子实例复制到辅助实例的数据。 在生产环境中,种子实例上有现有数据库,您可以使用MySQL Enterprise Backup等工具确保辅助数据在复制开始之前具有匹配的数据。 这避免了数据从主数据库复制到辅助数据库时长时间延迟的可能性。
将第二个实例添加到InnoDB集群:
mysql-js> cluster.addInstance('root@localhost:3320')
提示输入root用户的密码。
添加第三个实例:
mysql-js> cluster.addInstance('root@localhost:3330')
提示输入root用户的密码。
此时,您已创建了一个包含三个实例的集群:一个主服务器和两个辅助服务器。
Tip:
如果实例是sandbox,则在addInstance()中只能指定localhost。 这也适用于发出createCluster()之后的隐式addInstance()。
持久化配置
将sandbox 添加到群集后,必须将InnoDB群集所需的配置保留到每个实例的选项文件中。 连接到每个实例。
mysql-js> \connect instance
发出dba.configureLocalInstance(instance)。
mysql-js> dba.configureLocalInstance('instance')
系统会提示您输入实例的密码。 配置更改将保存到实例。
重要:
如果在连接到实例时未发出dba.configureLocalInstance(),则配置不会保存到选项文件。 这不会阻止实例初加入群集,但它确实意味着实例无法自动重新加入群集,例如在停止之后。
重复连接到添加到群集的每个sandbox实例并保持配置的过程。 对于此示例,我们在端口3310,3320和3330处添加了sandbox实例。因此,请为端口3320和3330发出此信息:
mysql-js> \connect root@localhost:port_number)
mysql-js> dba.configureLocalInstance('root@localhost:port_number)
要检查是否已创建集群,请使用集群实例的status()函数。
20.2.5 InnoDB集群的生产部署
在生产环境中工作时,组成InnoDB集群的MySQL服务器实例作为网络的一部分在多台主机上运行,而不是在单机上运行, 在继续执行这些说明之前,必须将所需的软件安装到要作为服务器实例添加到群集的每台计算机上,请参见第20.2.3节“安装方法”。
下图说明了您在本节中使用的方案场景:
重要:
与sandbox部署(其中所有实例都本地部署到一台计算机)不同,对于生产部署,您必须连接到每台计算机并在本地运行MySQL Shell,然后才能在实例上发出dba.configureLocalInstance()。 这可确保将任何配置更改保留在实例上的选项文件中。 这还要求您可以访问服务器以及执行MySQL Shell所需的权限。
要将服务器的连接信息传递给AdminAPI,请使用URI类型字符串。
用户权限
用于管理实例的用户帐户不必是root帐户,但除了完整的MySQL管理员权限外,还需要为InnoDB集群元数据表分配完全读写权限(SUPER,GRANT OPTION,CREATE, DROP等)。 为用户your_user提供管理InnoDB集群发布所需的权限:
GRANT ALL PRIVILEGES ON mysql_innodb_cluster_metadata.* TO your_user@'%' WITH GRANT OPTION;
GRANT RELOAD, SHUTDOWN, PROCESS, FILE, SUPER, REPLICATION SLAVE, REPLICATION CLIENT, CREATE USER ON *.* TO your_user@'%' WITH GRANT OPTION;
GRANT SELECT ON *.* TO your_user@'%' WITH GRANT OPTION;
如果仅需要读取操作(例如用于监视目的),则可以使用具有更多受限特权的帐户。 为用户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被用于此例子中。
配置 主机名
组成集群的生产实例在不同的计算机上运行,因此每台计算机必须具有的主机名,并且能够解析在集群中运行服务器实例的其他计算机的主机名。 如果不是这种情况,您可以:
- 配置每台计算机以将每台其他计算机的IP映射到主机名。 (/etc/hosts)
- 设置DNS服务
- 将每个实例的MySQL配置中的report_host变量配置为合适的外部可访问地址
在此过程中,主机名ic-number用于示例中。
要验证是否正确配置了MySQL服务器的主机名,请执行以下查询以查看实例如何将其自己的地址报告给其他服务器,并尝试使用返回的地址从其他主机连接到该MySQL服务器:
SELECT coalesce(@@report_host, @@hostname);
详细记录
使用生产部署时,为MySQL Shell配置详细日志记录会很有用,日志中的信息可以帮助您查找和解决在准备j将服务器实例作为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日志级别之外,您还可以在每次调用API后配置Admin Shell在MySQL Shell中提供的输出量:
mysql-js> dba.verbose=2
这将启用AdminAPI调用的大输出。 可用的输出水平是:
- 0或OFF是默认值。 这提供了小的输出,是不进行故障排除时的推荐级别。
- 1或ON会将每次调用的详细输出添加到AdminAPI。
- 2将调试输出添加到详细输出,提供有关每次调用AdminAPI的内容的完整信息。
检查实例配置
在从服务器实例创建生产部署之前,您需要使用dba.checkInstanceConfiguration()函数检查每个实例上的MySQL是否已正确配置。 这可确保实例满足第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()之后生成的报告提供了有关所需的任何配置更改的信息,然后才能继续。 报告后部分中的restart_required字段告诉您实例上的MySQL是否需要重新启动才能检测对配置文件所做的任何更改。
配置实例
如果通过对实例运行dba.checkInstanceConfiguration()生成的报告中有被标识的配置问题,则它不满足第20.2.2节“InnoDB群集要求”。 因此,您需要连接到计算机并重新配置服务器实例。 AdminAPI提供了dba.configureLocalInstance()函数,该函数查找MySQL服务器的选项文件并对其进行修改以确保为InnoDB集群正确配置实例。 或者,根据报告中的信息手动更改实例的选项文件。 有关更多信息,请参见第4.2.6节“使用选项文件”。 无论您进行配置更改的方式如何,您可能必须重新启动MySQL以确保检测到配置更改。
建议的方法是登录远程计算机,以root用户身份运行MySQL Shell,然后连接到本地MySQL服务器:
shell> sudo -i mysqlsh --log-level=DEBUG3
dba.configureLocalInstance()方法验证合适的用户是否可用于群集使用,该群集用于群集成员之间的连接。 默认情况下,root用户无法进行远程登录,因此您有三个选项可以继续配置:为root用户启用远程连接,创建新用户或不是前面2个的选项。 以下示例演示了第二个选项,即为群集使用创建新用户。
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服务器。
dba.configureLocalInstance()函数还接受clusterAdmin和clusterAdminPassword选项,这些选项使您可以在调用函数时配置集群用户和密码。 clusterAdmin支持用户名和主机名的标识符或字符串。 默认情况下,如果不加引号,则假定input是一个字符串。 例如:
mysql-js> dba.configureLocalInstance('ic@ic-1:3306', \ {clusterAdmin: 'icadmin@ic-1%',clusterAdminPassword: 'password'});
创建集群
准备好实例后,使用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.
注意:
如果遇到与无法访问的元数据相关的错误,则可能已配置环回网络接口。 要正确使用InnoDB群集,请禁用环回接口。
要检查是否已创建集群,请使用集群实例的status()函数
Tips
一旦服务器实例属于一个集群,只使用MySQL Shell和AdminAPI来管理它们是很重要的。 尝试在实例添加到群集后手动更改组复制的配置是不被支持的。 同样,不支持修改对InnoDB集群至关重要的服务器变量,例如在使用AdminAPI配置实例后的server_uuid。
使用cluster.addInstance(instance)函数向集群添加更多实例,其中instance是要连接到本地实例的URI类型字符串。 必须已为集群使用配置实例。 群集中至少需要三个实例才能容忍一个实例的失败。 添加更多实例会增加对实例失败的容忍度。 向集群问题添加实例:
mysql-js> cluster.addInstance('ic@ic-2:3306');
要验证是否已添加实例,请使用集群实例的status()函数。
重要
在此阶段,服务器实例已添加到群集,但InnoDB群集元数据的更改仅在您当前连接到的实例上进行。 要持久化群集中的所有实例的配置,您必须连接到每个实例并在已添加的每个实例上发出dba.configureLocalInstance()。 这对于确保实例在离开群集时重新加入群集至关重要。
要为所有实例保留InnoDB集群元数据,请登录到被添加到集群的每个实例并在本地运行MySQL Shell。
shell> mysqlsh
使用\ connect命令登录MySQL服务器。 执行dba.configureLocalInstance('instance')函数,其中instance是一个URI类型字符串,用于连接本地实例。 例如:
mysql-js> dba.configureLocalInstance('ic@ic-2:3306')
对添加到群集的每个服务器实例重复此过程。 同样,如果您修改群集结构(例如更改实例数),则需要为每个服务器实例重复此过程,以便相应地为群集中的每个实例更新InnoDB群集元数据。
部署集群后,您可以配置MySQL路由以提供高可用性.
20.2.6 采用组复制部署
如果您具有组复制的现有部署,并且希望使用它来创建集群,请将adoptFromGR选项传递给dba.createCluster()函数。 创建的InnoDB集群会匹配复制组是运行在以单主数据库还是多主数据库下。
Tip:
组复制成员可能包含MyISAM表。 在将组用于InnoDB集群之前,将所有此类表转换为InnoDB。
要采用现有的组复制组,请使用MySQL Shell连接到组成员。 在以下示例中,采用单主组。 我们连接到gr-member-2,一个辅助实例,而gr-member-1作为组的主。 使用dba.createCluster()创建一个集群,并传入adoptFromGR选项。 例如:
mysql-js> var cluster = dba.createCluster('prodCluster', {adoptFromGR: true});
A new InnoDB cluster will be created on instance 'root@gr-member-2:3306'.
Creating InnoDB cluster 'prodCluster' on 'root@gr-member-2: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
新群集与组的模式匹配。 如果采用的组以单主模式运行,则会创建单主群集。 如果采用的组以多主模式运行,则会创建多主集群。 例如:
mysql-js> cluster.status(); { "clusterName": "prodCluster", "defaultReplicaSet": { "name": "default", "primary": "gr-member-1:3306", "ssl": "REQUIRED", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": { "gr-member-2:3306": { "address": "gr-member-2:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "gr-member-1:3306": { "address": "gr-member-1:3306", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "gr-member-3:3306": { "address": "gr-member-3:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" } } } }
如上所示,新创建的集群是单主集群,并使用gr-member-1作为主。