MySQL InnoDB Cluster为MySQL提供了完整的高可用性解决方案。通过使用MySQL Shell附带的AdminAPI,可以轻松地配置和管理至少三个MySQL服务器实例。每个MySQL服务器实例都运行MySQL组复制,它提供了具有内置故障转移功能的复制数据的机制。AdminAPI消除了直接在InnoDB中使用组复制的需要。MySQL路由器可以根据您部署的服务器自动进行自我配置,从而将客户端应用程序透明地连接到服务器实例。如果服务器实例发生意外故障,则将自动重新配置。在唯一的单主服务器模式下,InnoDB具备了读写器服务器实例-主服务器。如果主服务器发生故障,则辅助服务器将自动升级为主服务器角色。MySQL路由器会检测到此情况下的客户端应用程序转发到新的主服务器。配置为具有多个主数据库。
要求
InnoDB的群集使用组复制,因此服务器实例必须满足组复制的要求。
使用Innodb的引擎存储
InnoDB的群集的任何实例都要启用性能模式
MySQL Shell需要Python2.7环境。
MySQL的路由器的--bootstrap选项可以使InnoDB的集群的元数据进行自我配置。这将自动配置MySQL路由器,以将连接路由连接到服务器实例。客户端应用程序连接到MySQL路由器提供的端口,万一发生意外故障,InnoDB Cluster会自动进行自我调整,并且MySQL Router会检测到更改。这消除了客户端应用程序处理故障转移的需要。
使用--bootstrap选项而不是手动配置MySql Royter,因为这可确保MySQL Router从InnoDB Cluster的元数据中获取其配置
建议将MySQL路由器与应用程序部署在同一主机上。使用生产部署时,建议将一个MySQL路由器实例部署到一个承载客户端应用程序的每台计算机上。也可以将MySQL路由器部署到应用程序实例通过其连接的通用计算机上。
安装mysqlshell
安装mysqlrouter
沙箱部署
沙箱部署:将InnoDB Cluster的组件安装到一台计算机上。仅在一台计算机上本地进行
启动mysqlshell
shell> mysqlsh
创建实例
mysql-js> dba.deploySandboxInstance(3310)
连接到种子MySQL服务器实例时创建InnoDB可用,种子实例包含要复制到其他实例的数据;两种连接方式系都可以
mysql-js> \connect root@localhost:3310
mysql-js> shell.connect('root@localhost:3310')
以当前连接的实例作为种子创建InnoDB,cluster是返回的创建的对象,testCluster是对象名
mysql-js> var cluster = dba.createCluster('testCluster')
将第二个实例添加到InnoDB cluster
mysql-js> cluster.addInstance('root@localhost:3320')
连接到每个实例,将InnoDB Cluster所需的配置持久化到该实例的每个选项文件中
mysql-js> \connect root@localhost:port_number
mysql-js> dba.configureLocalInstance('root@localhost:port_number')
生产部署
配置每个服务器实例的report_host=本机真实IP或配置每个服务器的主机,然后在每个服务器实例上配置所有实例的DNS解析
my.cnf
[mysqld]
report_host=192.168.11.128
配置主机名
hostnamectl set-hostname --static s1.server.com
配置DNS解析
vim /etc.hosts
192.168.11.111 s1.server.com
查看实例的ip和主机名中,在后续的实例中使用ip或主机名都可以
SELECT coalesce(@@report_host,@@hostname);
修改所有实例配置
binlog_checksum = NONE
binlog_format = ROW
enforce_gtid_consistency = ON
gtid_mode = ON
log_bin=/server/log_bin
log_slave_updates = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
report_port = 3306
transaction_write_set_extraction = XXHASH64
-- 自动增量避免多主集群发生自动增量冲突的可能性
/*
如果组以单主要模式运行
auto_increment_increment=1
auto_increment_offset=2
*/
/*
如果多主模式集群有7个或更少实例时
auto_increment_increment=7
auto_increment_offset=1 + server_id % 7
*/
/*
如果多主模式集群有8个或更多实例时
auto_increment_increment = 实例数量
auto_increment_offset = 1 + server_id % 实例数量
*/
/*
mysql8支持,设置二进制日志的有效期限(以秒为单位)。
有效期结束后,可以自动删除二进制日志文件,默认2592000
*/
binlog_expire_logs_seconds = 2592000
创建集 群
连接实例
shell> mysqlsh --uri root@localhost:3306
检查该实例的设置是否适合InnoDB Cluster,并创建集群管理用户。
dba.configureInstance('root@localhost:3306',{clusterAdmin: "'cluster_user'@'192.168.11.%'",mycnfPath:'/etc/my.cnf',restart:true})
clusterAdmin:要创建的InnoDBCluster管理员用户的名称
支持标准的MySQL帐户名称格式、用户名和主机名的标识符或字符串。
默认情况下,如果不加引号,则假定输入为字符串。
如果不指定clusterAdmin,方法会提示你是否自动创建一个账号用于管理实例,创建的实例会自动包含所需权限。如果指定已有用户需要以下权限
mycnfPath是配置文件的位置,如果不指定位置方法会自动扫描到文件;
方法找到文件后会扫描到文件的配置是否符合要求,如果不符合将会列出来,并提示是否需要自动配置。
restart:布尔值,用于指示应执行目标实例的远程重新启动以完成操作。
创建用户后需要使用新用户重新连接mysqlsh,因为root账户不能创建集群
shell> mysqlsh --uri cluster_user@localhost:3306
创建实例:
ipAllowlist白名单,只有指定网段的IP才允许连接
var cluster = dba.createCluster('prodCluster',{ipAllowlist:'192.168.11.0/24'})
添加实例到集群
检查新实例的配置,在新实例上执行;或者提供一个可以连接到新实例的账号,账号需要有创建用户的权限
dba.configureInstance('root@192.168.11.130:3306',{clusterAdmin: "'cluster_user'@'192.168.11.%'",mycnfPath:'/etc/my.cnf',restart:true})
检查集群是否可以添加到进群中
cluster.checkInstanceState('cluster_user@192.168.11.130:3306')
添加实例
mysql8.0.17之后可以指定recoveryMethod:'clone',使新实例以克隆的方式恢复数据
mysql-js> cluster.addInstance('cluster_user@192.168.11.130:3306',{ipAllowlist:'192.168.11.0/24'})
支持waitRecovery整数选项:
0:不要等待恢复,让恢复过程在后台完成;
1:等待恢复过程完成;
2(默认):等待恢复过程完成;并显示详细的静态进度信息;
3:等待恢复过程完成;并显示详细的动态进度信息(进度条);
为所有实例保留InnoDB Cluster元数据,登录到每个实例,将配置保存到本机。
shell> mysqlsh --uri cluster_user@192.168.11.130:3306
mysql-js> dba.configureLocalInstance('cluster_user@192.168.11.130:3306',{clusterAdmin: 'cluster_user@192.168.11.%',clusterAdminPassword: 'password'})
clusterAdmin和clusterAdminPassword选项,可以在调用函数时配置调用用户和密码。clusterAdmin支持用户名和主机名的标识符或字符串
采用现有组复制部署
使用MySQL Shell连接到组成员然后创建实例,新群集与组的模式匹配。如果采用的组以单主要模式运行,则将创建一个单主要集群。如果采用的组以多主要模式运行,则将创建一个多主要群集。
shell> mysqlsh --uri ic@ic-1:3306
mysql-js> var cluster = dba.createCluster('prodCluster', {adoptFromGR: true});
MySQL Router引导MySQL Cluster集群
创建MySQL Router在群集的每个引导程序上所需要的的内部帐户
mysqlsh> testCluster.setupRouterAccount('myRouter1@localhost')
使用setupRouterAccount()来重新配置现有用户(8.0.20之前版本配置的)
mysqlsh> testCluster.setupRouterAccount('myOldRouter@localhost', {'update':1})
引导集群:系统会提示您输入要使用的MySQL实例的实例密码和加密密钥。该加密密钥用于加密MySQL路由器用于连接的实例密码。然后显示可用于连接到InnoDB的端口。此时,MySQL路由器尚未启动,因此无法路由连接。引导程序是一个独立的过程。
shell> mysqlrouter --bootstrap cluster_user@192.168.11.128:3306 --directory /tmp/myrouter --account myRouter1 --user=mysqlrouter
--directory在指定文件夹创建一个独立的路由器
--account指定路由器的账户
--user启动mysqlrouter使用的账号
其他引导项
--account-create,指定帐户创建策略,以防止使用错误的用户帐户意外启动。
- if-not-exists(默认):两种方式引导;重用该帐户(如果存在),否则创建它。
- always:仅在帐户尚不存在时进行引导;并创建它。
- never:仅在帐户已经存在时进行引导;并重复使用。
--account-host,引导过程中创建的账户主机模式,默认为%,可以指定多次,引导通过删除和重新创建用户来重用现有的路由器帐户,并且此用户重新创建过程适用于每个主机
MySQL Router引导过程创建了一个mysqlrouter.conf文件,其设置基于在cluster_user@192.168.11.128:3306中检索到的生成元数据的设置。根据检索到的InnoDB Cluster元数据,MySQL Router自动创建一个配置文件,其中包括一个meta_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
user=mysql_router1_jy95yozko3k2
metadata_cluster=prodCluster
ttl=300
配置MySQL路由器后如果添加另一个服务器实例,需要更改bootstrap_server_addresses对元数据进行更新。使用MySQL Router --bootstrap重新启动,或手动编辑mysqlrouter.conf文件bootstrap_server_addresses部分并重新启动MySQL路由器。
生成的MySQL路由器配置将创建到连接到TCP的TCP端口。创建使用经典的MySQL协议和X协议与生成通信的端口。 生产实例如果要使用X协议,则需要在每个实例上安装和配置X插件。替换的可用TCP端口为:
6446 - 用于连接经典的MySQL协议读写会话,MySQL路由器将传入的连接重定向到主服务器实例。
6447 - 用于连接经典的MySQL协议只读会话,MySQL路由器将传入的连接重定向到辅助服务器实例之一
64460 - 用于连接X协议读写会话,MySQL路由器将传入的连接重定向到主服务器实例。
64470 - 用于连接X协议只读会话,MySQL的路由器将传入的连接重定向到辅助服务器实例之一。
使用--conf-base-port选项,可以在引导MySQL路由器时替换上述端口,指定一个值然后其他链接端口在这个指定端口上一次加1,例如指定6446,那么经典的MySQL协议只读会话为6447,X协议读写会话为6448,X协议只读会话为6449
当使用单一主集群时,默认情况下MySQL路由器发布X协议和经典MySQL协议端口,客户端连接到该端口进行读写会话,并将其重定向到集群的单一主集群。使用多主集群,读写会话以轮询的方式重定向到主实例之一。对于进入的只读连接,MySQL路由器也以循环的方式将连接重定向到一个次要实例
启动MySQL路由器
shell> mysqlrouter &
如果引导时使用--directory,那么在--directory指定的目录中存在独立的启动脚本
cd /tmp/myrouter
./start.sh
要验证您实际连接到的实例,只需针对端口状态变量发出SQL查询。
连接路由器
shell> mysqlsh --uri root@localhost:6446
mysql-js> \sql
Switching to SQL mode... Commands end with ;
mysql-sql> select @@hostname;
+-----------+
| @@hostname|
+-----------+
| s128.com |
可以针对一个群集或副本集引导MySQL路由器的多个实例,显示所有已注册的MySQL路由器实例的列表
Cluster.listRouters()
结果提供有关每个已注册的MySQL路由器实例的信息,例如其在元数据中的名称,主机名,端口等
删除已注册的路由器,路由器名称在listRouters方法中查看
Cluster.removeRouterMetadata('myrouter1')
内部恢复用户
作为组复制的一部分,InnoDB集群创建了内部恢复用户,允许在集群中服务器之间的连接,内部用户使用的主机名取决于是否配置了ipAllowlist选项。如果没有配置ipAllowlist,它默认为AUTOMATIC,并且使用通配符%字符和主机名值localhost创建内部用户。配置完ipAllowlist后,将为ipAllowlist列表中的每个地址创建一个内部用户。每个内部用户都有一个随机生成的密码。从版本8.0.18开始,AdminAPI允许您更改为内部用户生成的密码。用户将获得以下授权:
GRANT REPLICATION SLAVE ON *.* to internal_user;
内部用户帐户在种子实例上创建,然后复制到群集中的其他实例。内部用户是:
- 通过发行dba.createCluster()创建新集群时生成
- 通过发出Cluster.addInstance()将新实例添加到集群时生成
Cluster.rejoinInstance()当使用该ipAllowlist选项指定主机名时,该操作还可能导致生成新的内部用户。考虑到ipAllowlist使用的值,将删除所有以前存在的内部用户,并创建一个新的内部用户 。
Cluster.rejoinInstance({ipAllowlist: "192.168.1.1/22"});
MySQL Clone
在MySQL 8.0.17中,InnoDB Cluster集成了MySQL Clone插件以提供自动配置连接实例的功能。检索群集数据以便实例可以与群集同步的过程称为分布式恢复。当实例需要恢复集群的事务时,我们区分 施主(即提供数据的集群实例)和接收者(接收者)。MySQL Clone无需依赖异步复制来恢复事务,而是在施主实例上拍摄数据快照,然后将快照传输到接收者。克隆操作期间,接收器中的所有先前数据都会被破坏。但是,所有未存储在表中的MySQL设置都将保留。克隆操作将快照传输到接收器后,如果群集在传输快照时已处理了事务,则将使用异步复制来恢复任何必需的数据,以使接收器与群集同步。与实例使用异步复制恢复所有事务相比,这可以更加高效,并且可以避免由清除的GTID引起的任何问题,从而使您能够快速为InnoDB Cluster设置新实例。
与使用MySQL Clone相比,增量恢复是其中加入集群的实例仅使用异步复制从集群中恢复实例的过程。将InnoDB集群配置为使用MySQL Clone时,加入集群的实例将使用MySQL Clone或增量恢复来恢复集群的事务。默认情况下,集群会自动选择最合适的方法,但是您可以选择配置此行为,例如强制克隆,以替换加入实例已处理的所有事务。
在交互模式下使用MySQL Shell时,默认情况下,如果群集不确定它是否可以继续进行恢复,则会提供一个交互式提示。
默认情况下,在可以使用MySQL Clone插件的实例上创建新集群时,它将自动安装并且该集群配置为支持克隆
禁用集群的MySQL Clone
dba.createCluster('testCluster', {'disableCloneBoolean':true})
Cluster.checkInstanceState()验证使用MySQL Clone的群集实例,如果该实例没有二进制日志,例如因为已清除二进制日志,但Clone可用且未禁用,则该操作会提供警告
dba.checkInstanceConfiguration() 对具有可用的MySQL Clone但被禁用的实例运行该操作时,将显示警告
集群状态
cluster.status()
clusterName:在期间分配给此集群的名称 dba.createCluster()。
defaultReplicaSet:属于InnoDB群集并包含数据集的服务器实例
primary:仅在集群以单主模式运行时显示。显示当前主实例的地址。如果未显示此字段,则说明集群正在多主模式下运行。
ssl:集群是否使用安全连接。显示REQUIRED或的 值DISABLED,具体取决于 或 memberSslMode期间选项的配置方式。
status:集群中此元素的状态。对于整个群集,这描述了此群集提供的高可用性。状态为以下之一:
ONLINE:实例处于联机状态并且正在参与集群。
OFFLINE:实例已失去与其他实例的连接。
RECOVERING:实例正在尝试通过使其成为ONLINE成员之前检索所需的事务来与集群同步 。
UNREACHABLE:实例已失去与集群的通信。
ERROR:实例在恢复阶段或应用事务时遇到错误。(实例进入ERROR 状态后,该 super_read_only 选项将设置为ON。要退出 ERROR状态,您必须使用手动配置实例 super_read_only=OFF。)
(MISSING):实例的状态,该实例是已配置集群的一部分,但当前不可用(该MISSING状态特定于InnoDB群集,不是组复制生成的状态。MySQL Shell使用此状态指示已在元数据中注册但在实时群集视图中找不到的实例。)
topology:已添加到集群的实例
Host name of instance:实例的主机名,例如localhost:3310。
role:此实例在集群中提供什么功能。当前仅HA,以实现高可用性。
mode:服务器是读写(“ R / W”)还是只读(“ R / O”)。该模式指示R/W (可读和可写)或R/O(只读)。在单主数据库模式下,只有一个标记为“ R / W”的实例可以执行更新数据库的事务,因此它是主数据库。如果该实例由于任何原因(例如意外停止)而变得不可访问,则其余的“ R / O”实例之一将自动取代
groupInformationSourceMember:用于获取有关集群的信息的内部连接,显示为类似URI的连接字符串。通常,最初用于创建集群的连接其位置,并成为新的“ R / W”主实例。在多主数据库模式下,所有实例均标记为“ R / W”,并且没有单个选举的主数据库。
mysql8.0开始支持extended 选项(整数或布尔值):Cluster.status({'extended':1})
0:禁用其他信息,默认
1:包括有关组复制协议版本,组名称,集群成员UUID,集群成员角色和状态(由组复制报告)以及受防护系统变量列表的信息
2:包括有关通过连接和应用程序处理的事务的信息
3:包括有关每个群集成员执行的复制的更详细的统计信息。
为1时会额外输出
GRProtocolVersion 是群集中使用的组复制协议版本
groupName 是组的名称,UUID
fenceSysVars包含启用的受防护系统变量名称的列表
memberId 每个集群成员的UUID
memberRole组复制插件报告的成员角色
memberState组复制插件报告的成员状态
查看集群结构和所有配置信息
cluster.describe();
命令
检查实例状态
验证实例上的现有数据是否可以加入集群,此过程通过与群集已处理的GTID进行比较来验证实例的全局事务标识符状态来进行。
cluster.checkInstanceState('ic@ic-4:3306')
具有良好状态的实例可以添加到关联中,因为实例上的任何数据都与集群一致。换句话说,正在检查的实例已经执行任何与GTID冲突的事务,并且可以恢复到与其余实例相同的状态
此函数的输出可以是以下之一:
- OK new:实例尚未执行任何GTID事务,因此它不会与集群执行的GTID冲突
- OK recoverable:实例已执行的GTID与集群种子实例的已执行的GTID不冲突
- ERROR diverged:实例已执行的GTID与集群种子实例的已执行GTID发生了偏差
- ERROR lost_transactions:实例的已执行GTID数量比集群种子实例的已执行GTID数量更多
检查实例配置
在配置实例时检查配置,这样可以确保满足群集要求,而无需更改实例上的任何配置。这不会检查实例上的任何数据
dba.checkInstanceConfiguration(instance)
dba.configureInstance([instance][, options])
检查该实例的设置是否适合InnoDB Cluster使用。显示不符合InnoDB Cluster所需的设置。并提示是否需要自动配置。提示包含以下3列信息
- Variable:无效的配置变量。
- Current Value:无效配置变量的当前值。
- Required Value:配置变量的必需值。
instance:要检查的实例 'root@localhost:3006'
options
- mycnfPath:MySQL实例选项文件的路径
- outputMycnfPath:写入MySQL实例选项文件的备用输出路径。
- password:连接使用的密码。
- clusterAdmin:要创建的InnoDBCluster管理员用户的名称。支持标准的MySQL帐户名称格式。支持用户名和主机名的标识符或字符串。默认情况下,如果不加引号,则假定输入为字符串。
- clusterAdminPassword:使用的InnoDB Cluster管理员帐户clusterAdmin的密码,明文写出存在风险,不写会提示输入密码。
- interactive:布尔值,用于禁用命令执行中的交互式向导,以便不向用户提供提示,也不显示确认提示。
- restart:布尔值,用于指示应执行目标实例的远程重新启动以完成操作。
离开集群
在单主要模式下,如果当前主节点离开群集,则将辅助实例之一选作新的主实例,实例的优先级最低server_uuid.MySQL路由器读写将连接重定向到新选出的主数据库,如果当前从节点离开集群,则MySQL路由器将停止连接到该实例。
在多主要模式下,如果当前的“ R/W”实例离开集群,则MySQL路由器串行传输连接到其他主数据库
mysql-js> dba.killSandboxInstance('cluster_user@192.168.11.129')
在mysql shell中查看当前连接的端口,第一条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 |
+--------+
获取集群实例对象
不指定name获取默认集群对象
mysql-js> var cluster1 = dba.getCluster(name, [options])
设置实例为只读
dba.configureInstance(instance, {clearReadOnly: true})
管理沙箱实例
要停止沙箱实例,请使用dba.stopSandboxInstance(instance)。 killSandboxInstance(实例),这会优雅地停止实例。
要启动沙箱实例,请使用dba.startSandboxInstance(实例)
要杀死沙箱实例,请使用dba.killSandboxInstance(实例)这会在没有适当停止的情况下停止实例,并且在模拟意外停止时很有用。
要删除沙箱实例,请使用dba.deleteSandboxInstance(instance)这将完全从文件系统中删除沙箱实例。
删除集群实例
mysql-js> cluster.removeInstance('root@localhost:3310')
可以指定force选项,为true时将忽略错误,但是可能会导致实例与群集不同步,以后可能无法重新加入群集,仅在计划不再在群集中使用该实例时才使用
删除元数据
dba.dropMetadataSchema()
自定义集群
dba.createCluster('cluster1', {'groupName':'uuid','localAddress':'host:port'})
groupName定义复制组的名称。这将设置group_replication_group_name变量。名称必须是有效的UUID。
localAddress定义实例为其他实例的连接提供的地址,将设置group_replication_local_address。
集群的实例使用不同端口进行不同类型的通信,除了3307和33060(x协议通信默认),集群中实例之间还存在用于内部连接的端口,不用于客户端连接,由localAddress配置,可配置group_replication_local_address,并且必须打开此端口,以便群集中的实例可以相互通信。创建集群或将实例添加到集群时,默认情况下,localAddress端口的计算方法目标实例port*10+1,结果不能超过65535;
重新加入集群
如果某个实例意外离开了无法自动重新加入,在以后将其重新加入
cluster.rejoinInstance("ic-1@%")
恢复集群
如果或一个实例多个失败,则群集可能会无法自动选择主服务器。使用forceQuorumUsingPartitionOf设置主服务器
mysql-js> cluster.forceQuorumUsingPartitionOf("localhost:3310")
重启重置集群
如果集群完全崩溃,重启实例然后使用dba.rebootClusterFromCompleteOutage()来恢复群集
它使用MySQL Shell连接到该实例作为新的种子实例,并根据该实例的现有元数据恢复集群。如果此过程失败,并且导致元数据已严重损坏。则可能需要删除元数据并从头开始重新创建集群。
mysql-js> shell.connect('root@localhost:3310');
mysql-js> var cluster = dba.rebootClusterFromCompleteOutage();
扫描集群实例
通过手动更改实例的配置解决配置问题或丢失实例后,需要更新InnoDB群集元数据,以使其与数据库的当前配置匹配
Cluster.rescan([options])
options选项
interactive:布尔值,用于禁用或启用命令执行中的向导
addInstances:列出要添加到元数据的新活动实例的连接数据,或者列出“ auto ”以将丢失的实例自动添加到元数据
列表中指定的实例将添加到元数据中,而不提示您进行确认
removeInstances:列出要从元数据中删除的过时实例的连接数据,或者列出“ auto ”以从元数据中自动删除过时的实例。
列表中指定的实例将从元数据中删除,而不会提示您进行确认
updateTopologyMode:布尔值,用于指示元数据中的拓扑模式(单主要或多主要)是否应该更新(真)或不更新(假)以匹配集群使用的拓扑模式。默认情况下,不更新元数据(false)
如果值为true则将InnoDB Cluster元数据与组复制正在使用的当前模式进行比较,并在必要时更新元数据。在AdminAPI之外对集群的拓扑模式进行更改后,请使用此选项来更新元数据。
如果值为false则即使有关集群拓扑模式的InnoDB集群元数据与集群的组复制组使用的拓扑不同,也不会更新
如果未指定该选项,并且元数据中的拓扑模式不同于群集的“组复制”组使用的拓扑,则:
在交互模式下,系统将提示您确认元数据中拓扑模式的更新
在非交互模式下,如果集群的组复制组使用的拓扑与InnoDB集群元数据之间存在差异,则会报告该拓扑,并且不对元数据进行任何更改
分解集群
连接到一个读写实例,例如单主要指向中的主要实例,在实例上分解组复制。在实例之间复制的任何数据都不会被删除。无法撤消分解。
mysql-js> cluster.dissolve({force:true})
The cluster was successfully dissolved.
Replication was disabled but user data was left intact.
force强制执行分解操作以忽略任何无法访问的实例
更改集群拓扑
将集群切换到多主模式。所有实例都成为主实例
Cluster.switchToMultiPrimaryMode()
群集切换到单主要模式。如果指定instance,则它将成为主要实例。如果未指定instance,则新的主节点是成员权重最高的实例
Cluster.switchToSinglePrimaryMode([instance])
配置集群
列出了集群及其实例的配置选项
Cluster.options()
全局更改所有群集实例的设置或群集全局设置
Cluster.setOption(option, value)
更改群集单个实例的设置
luster.setInstanceOption(instance, option, value)
全局和单子实例可修改
exitStateAction
memberWeight
及单个实例可修改
label
仅全局可修改
consistency
expelTimeout
clusterName
配置实例的自动重新加入
dba.createCluster('user@localhost',{autoRejoinTries:1})
Cluster.addInstance('user@localhost',{autoRejoinTries:1})
Cluster.setOption(autoRejoinTries,1)
Cluster.setInstanceOption('user@localhost',{autoRejoinTries:1})
MySQL 8.0.16及更高版本的实例支持组复制自动重新加入功能
autoRejoinTries选项,配置实例被驱逐后重新加入群集的尝试次数,默认情况下,实例不会自动重新加入集群;autoRejoinTries值为0-2016
MySQL 8.0.12及更高版本的实例可以使用exitStateAction选项配置集群,
- READ_ONLY(默认):离开群集的实例意外变为只读
- OFFLINE_MODE(MySQL 8.0.18及以上才有):离开集群的实例将变为只读,并进入脱机模式,在该模式下,实例将断开现有客户端的连接并且不接受新连接
- ABORT_SERVER:实例离开群集,MySQL将关闭,必须重新启动它才能重新加入群集
重置内部恢复帐户的密码
从8.0.18开始可以使用,该操作会在每个在线实例上为内部恢复帐户设置一个新的随机密码。如果无法访问实例,则操作将失败
Cluster.resetRecoveryAccountsPassword()
标记元数据
8.0.21开始支持
在集群实例上设置标签,可以将实例标记为不可用,以便应用程序和路由器将其视为脱机
myCluster.setInstanceOption(instance,option,value)
/*
instance是目标实例的连接字符串
option必须是格式名称空间
value参数是在指定的名称空间中应该分配给option的值,如果值为null,则从指定的名称空间中删除该选项
对于属于集群的实例,setInstanceOption()操作只接受标记名称空间
*/
查看标签
myCluster.options()
从路由删除实例
mysql-js> myCluster.setInstanceOption(icadmin@ic-1:3306, "tag:_hidden", true);
恢复实例,删除标签后,MySQL路由器会自动将实例添加回路由目标
mysql-js> myCluster.setInstanceOption(icadmin@ic-1:3306, "tag:_hidden", false);
安全连接集群
将群集配置为使用SSL后,必须将服务器添加到ipWhitelist
当使用dba.createCluster()建立一个集群,如果服务器实例提供SSL加密,然后它会自动在种子实例启用。将memberSslMode选项传递给dba.createCluster()方法以指定其他SSL模式。该成员的SSL模式只能在创建时设置。该成员SslMode选项是一个字符串,用于配置要使用的SSL模式,可以为自动。允许其已禁用。这些模式定义为:
createCluster({memberSslMode:'DISABLED'})为群集中的种子实例禁用SSL加密
createCluster({memberSslMode:'REQUIRED'})为集群中的种子实例设置启用SSL加密。如果无法启用,则会引发错误
createCluster({memberSslMode: 'AUTO'})(默认)如果服务器实例支持,则 置然后自动启用SSL加密;如果服务器不支持SSL加密,则禁用。
商业版本的MySQsh启用SSL,需要为所有实例配置白名单
memberSslMode不能与adoptFromGR一起使用
创建服务器白名单
使用createCluster(),addInstance()和rejoinInstance()方法时,可以选择指定该关联的已批准服务器的列表,称为白名单。通过以这种方式显式指定白名单,可以提高级别的安全性,因为只有白名单中的服务器才能连接到副本。有时情况下,如果未明确指定,则白名单将自动设置为服务器具有网络接口的专用网络地址。使用ipWhitelist配置白名单。从MySQL 5.7.21开始,白名单还可以包含主机名,只有在其他服务器发出的连接请求时才能解析这些主机名。主机名本质上不如白名单中的IP地址安全
仅接受来自地址203.0.113.0/24和198.51.100.110的服务器的连接
mysql-js> cluster.addInstance("ic@ic-3:3306",{ipWhitelist:"203.0.113.0/24,198.51.100.110"})
限制条件
由于InnoDB群集正在使用组复制,因此您还应该注意组限制
AdminAPI不支持Unix可以进行连接。MySQLShell不会阻止您尝试使用与嵌套的交替连接,而尝试使用与可用的大量连接会导致意外的结果。
MySQL的路由器-引导命令行选项不接受的IPv6地址
商业版的MySQL路由器的AppArmor的设置不正确,解决方法是编辑AppArmor的配置文件配置文件,/etc/apparmor.d/usr.sbin。 并修改包含/usr/sbin/mysqld使用MySQL路由器路径的行/usr/sbin/mysqlrouter。
将adoptFromGR选项与dba.createCluster()功能结合使用,该实例已成为复制组的一部分。这仅在MySQL Shell的替代向导模式下发生。一种解决方法是通过使用--no-wizard命令选项启动mysqlsh来替换向导模式。InnoDB Cluster服务器实例不支持使用。 --defaults-extra-file选项指定选项文件。InnoDB Cluster在实例上仅支持替代选项文件,因此不支持其他选项文件。因此,对于使用实例的选项文件进行的任何操作,应指定主要操作。如果要使用多个选项文件,则必须手动配置文件,并考虑到使用多个选项文件的优先规则,并确保它们已正确更新,并确保所需的设置不会被其他无法识别的选项中的选项错误地覆盖文件。
InnoDB Cluster不管理手动配置的异步复制通道。组复制和AdminAPI不能确保异步复制仅在主复制上处于活动状态,并且状态不会跨实例复制。这可能导致复制不再起作用的各种情况。因此,也不支持在一个InnoDB集群和另一个InnoDB集群之间进行复制。
InnoDB ReplicaSet
shell8.0.19增加了InnoDB ReplicaSet
AdminAPI包括对InnoDB ReplicaSet的支持,能够以类似于InnoDB Cluster的方式管理一组运行基于异步GTID的复制的MySQL实例
InnoDB ReplicaSet由一个主副本和多个副副本(传统上称为MySQL复制源和副本)组成
MySQL Router支持针对InnoDB ReplicaSet的引导
部署
仅支持运行MySQL 8.0及更高版本的实例
仅支持基于GTID的复制,二进制日志文件复制与InnoDB ReplicaSet不兼容
仅支持基于行的复制(RBR),不支持基于语句的复制(SBR)
不支持复制过滤器
不允许在任何实例上使用非托管复制通道
一个ReplicaSet最多包含一个主实例,并且支持一个或多个第二实例。尽管可以添加到副本集的辅助副本数量没有限制,但是连接到副本集的每个MySQL路由器都必须监视每个实例。因此,添加到ReplicaSet的实例越多,必须执行的监视越多。
ReplicaSet必须完全由MySQL Shell管理。例如,复制帐户由MySQL Shell创建和管理。不支持在MySQL Shell之外对实例进行配置更改
与MySQL路由器一起使用时,生成的MySQL Router配置文件中的唯一区别是添加了cluster_type=rs选项
配置
-- 配置复制集的管理账户,权限与集群相同
mysql-js> dba.configureReplicaSetInstance('root@rs-1:3306', {clusterAdmin: "'rsadmin'@'rs-1%'"});
mysql-js> \connect root@rs-1:3306
-- 创建实例
mysql-js> var rs = dba.createReplicaSet("example")
/*添加副本,副本的恢复与InnoDB Cluster的方式几乎相同,MySQL Shell尝试自动选择合适的恢复方法。
如果无法选择,MySQL Shell会提示您使用什么。*/
rs.addInstance('root@rs-2')
采用现有的复制设置
-- 所有复制通道都必须处于活动状态,并且通过GTID集验证的事务集必须保持一致,满足条件时,属于拓扑的所有实例将自动添加到副本集
mysql-js> rs = dba.createReplicaSet('testadopt', {'adoptFromAR':1})
命令
查看复制集状态
rs.status()
获取复制集的名称
rs.name
rs.getName()
删除实例
rs.removeInstance()
重新加载实例
rs.rejoinInstance()
将主数据库更改为另一个实例,当前的主节点降级为辅助节点,变为只读
rs.setPrimaryInstance()
强制设置副本集中的主实例,setPrimaryInstance不生效时可以安全的切换新的主数据库,如果未提供目标实例(或为null),则会自动选择最新实例并将其升级为新的主要实例。
rs.forcePrimaryInstance()
限制
InnoDB ReplicaSet本身不能提供高可用性
没有自动故障转移。如果主服务器不可用,则需要使用AdminAPI手动触发故障转移,然后才能再次进行任何更改。但是,辅助实例仍然可用于读取。
无法防止由于意外停止或不可用而导致部分数据丢失。暂停之前尚未应用的事务可能会丢失。
无法防止意外退出或不可用后出现不一致情况。如果故障转移在辅助节点仍可用的情况下提升了辅助节点(例如,由于网络分区),则可能会引起不一致。
InnoDB ReplicaSet不支持多主要模式。使用允许所有成员进行写操作的经典复制拓扑不能保证数据的一致性。
读取横向扩展受到限制,因为InnoDB ReplicaSet基于异步复制,因此无法像组复制那样对流控制进行调整。
所有辅助成员都从一个来源复制。对于某些特定方案或用例,这可能会对源产生影响。例如,正在进行许多非常小的更新