• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 使用InnoDB集群

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

    • 使用dba.checkInstanceConfiguration()
    • 使用配置实例dba.configureLocalInstance()
    • 使用以下方法检索InnoDB集群dba.getCluster()
    • 使用cluster.describe()
    • 使用以下命令检查集群的状态Cluster.status()
    • 监视恢复操作
    • InnoDB集群和组复制协议
    • 在实例上检查MySQL版本
    • 超级只读和实例
    • 为InnoDB集群配置用户
    • 配置实例的自动重新加入
    • 管理沙箱实例
    • InnoDB集群和二进制日志清除
    • 从InnoDB集群中删除实例
    • 自定义InnoDB集群
    • 重新加入集群
    • 从仲裁丢失中恢复群集
    • 从主要中断中重启集群
    • 重新扫描群集
    • 检查实例状态
    • 分解一个InnoDB集群
    • 保护您的集群
    • 创建服务器白名单
    • 脚本AdminAPI
    • 配置选举过程
    • 配置故障转移一致性
    • 更改集群的拓扑
    • 设置InnoDB集群的选项
    • InnoDB集群和自动增量

    使用dba.checkInstanceConfiguration()

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

    mysql-js> dba.checkInstanceConfiguration('icadmin@ic-1:3306')
    Please provide the password for 'icadmin@ic-1:3306': ***
    Validating MySQL instance at ic-1:3306 for use in an InnoDB cluster...
    
    This instance reports its own address as ic-1
    Clients and other cluster members will communicate with it through this address by default.
    If this is not correct, the report_host MySQL system variable should be changed.
    
    Checking whether existing tables comply with Group Replication requirements...
    No incompatible tables detected
    
    Checking instance configuration...
    
    Some configuration options need to be fixed:
    +--------------------------	+---------------	+----------------	+--------------------------------------------------	+
    | Variable	| Current Value	| Required Value	| Note	|
    +--------------------------	+---------------	+----------------	+--------------------------------------------------	+
    | binlog_checksum	| CRC32	| NONE	| Update the server variable	|
    | enforce_gtid_consistency	| OFF	| ON	| Update read-only variable and restart the server	|
    | gtid_mode	| OFF	| ON	| Update read-only variable and restart the server	|
    | server_id	| 1	|	| Update read-only variable and restart the server	|
    +--------------------------	+---------------	+----------------	+--------------------------------------------------	+
    
    Please use the dba.configureInstance() command to repair these issues.
    
    {
        "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": "1",
                "option": "server_id",
                "required": ""
            }
        ],
        "status": "error"
    }
    

    对计划用作集群一部分的每个服务器实例重复此过程。运行后生成的报告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

    shell>sudo -i mysqlsh --uri=instance
    

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

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

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

    使用以下方法检索InnoDB集群dba.getCluster()

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

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

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

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

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

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

    使用cluster.describe()

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

    mysql-js> cluster.describe();
    {
        "clusterName": "testCluster",
        "defaultReplicaSet": {
            "name": "default",
            "topology": [
                {
                    "address": "ic-1:3306",
                    "label": "ic-1:3306",
                    "role": "HA"
                },
                {
                    "address": "ic-2:3306",
                    "label": "ic-2:3306",
                    "role": "HA"
                },
                {
                    "address": "ic-3:3306",
                    "label": "ic-3:3306",
                    "role": "HA"
                }
            ]
        }
    }
    

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

    使用以下命令检查集群的状态Cluster.status()

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

    重要

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

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

    mysql-js> var cluster = dba.getCluster()
    mysql-js> cluster.status()
    {
        "clusterName": "testcluster", 
        "defaultReplicaSet": {
            "name": "default", 
            "primary": "ic-1:3306", 
            "ssl": "REQUIRED", 
            "status": "OK", 
            "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", 
            "topology": {
                "ic-1:3306": {
                    "address": "ic-1:3306", 
                    "mode": "R/W", 
                    "readReplicas": {}, 
                    "role": "HA", 
                    "status": "ONLINE"
                }, 
                "ic-2:3306": {
                    "address": "ic-2:3306", 
                    "mode": "R/O", 
                    "readReplicas": {}, 
                    "role": "HA", 
                    "status": "ONLINE"
                }, 
                "ic-3:3306": {
                    "address": "ic-3:3306", 
                    "mode": "R/O", 
                    "readReplicas": {}, 
                    "role": "HA", 
                    "status": "ONLINE"
                }
            }
        }, 
        "groupInformationSourceMember": "mysql://icadmin@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群集,不是组复制生成的状态。MySQL Shell使用此状态来指示已在元数据中注册但在实时集群视图中找不到的实例。

    • topology:已添加到集群的实例。
    • Host name of instance:实例的主机名,例如localhost:3310。
    • role:此实例在集群中提供什么功能。当前仅HA,以实现高可用性。
    • mode:服务器是读写(“ R / W”)还是只读(“ R / O”)。从8.0.17版本开始,这是从super_read_only实例上变量的当前状态以及群集是否具有仲裁的派生而来的。在以前的版本中,mode的值是从实例作为主要实例还是辅助实例得出的。通常,如果实例是主要实例,则模式为“ R / W”,如果实例是次要实例,则模式为“ R / O”。群集中没有可见仲裁的所有实例都标记为“ R / O”,而不管super_read_only变量的状态如何。
    • groupInformationSourceMember:用于获取有关群集信息的内部连接,显示为类似URI的连接字符串。通常,最初用于创建集群的连接。

    要显示有关群集的更多信息,请使用该extended选项。从8.0.17版本开始,该extended选项支持整数或布尔值。要配置提供的其他信息,请使用以下值:Cluster.status({'extended':value})

    • :禁用其他信息,默认
    • :包括有关组复制协议版本,组名称,集群成员UUID,集群成员角色和状态(由组复制报告)以及受防护系统变量列表的信息
    • :包括有关通过连接和应用程序处理的事务的信息
    • :包括有关每个群集成员执行的复制的更详细的统计信息。

    设置extended使用布尔值是相当于现有8.0.17设置整数值0和1在版本中,extended选择是仅布尔值。同样,以前的版本使用queryMembersBoolean选项提供有关集群中实例的更多信息,这等效于设置extended为3。queryMembers不建议使用该选项,并计划在将来的版本中删除该选项。

    发出Cluster.status({'extended':1})extended选项设置为时true,输出包括:

    • defaultReplicaSet对象的以下附加属性:

      • GRProtocolVersion是群集中使用的组复制协议版本。

        小费

        InnoDB集群管理正在自动使用的组复制协议版本,有关更多信息,请参见 InnoDB集群和组复制协议。

      • groupName是组的名称,UUID。
    • 对象的每个对象的以下附加属性topology

      • fenceSysVars包含启用的受防护系统变量名称的列表。目前认为围栏系统变量read_onlysuper_read_onlyoffline_mode
      • memberId每个集群成员的UUID。
      • memberRole组复制插件报告的成员角色,请参阅表的MEMBER_ROLEreplication_group_members
      • memberState组复制插件报告的会员状态,请参阅表MEMBER_STATEreplication_group_members

    要参见有关恢复和常规事务I / O,适当的工作线程统计信息和任何滞后的信息;如果启用了并行应用,则应用程序协调器统计信息;错误,并且I / O和应用程序线程发出的其他信息使用值2和3。值3等于将不赞成的queryMembers选项设置为true。使用这些值时,将打开与集群中每个实例的连接,以便可以查询其他特定于实例的统计信息。输出中包含的确切统计信息取决于实例的状态和配置以及服务器版本。此信息与replication_group_member_stats表格,请参阅匹配列的说明以获取更多信息。包含在输出中ONLINEtransactions部分的实例。包含在输出中RECOVERINGrecovery部分的实例。设置extended为2时,无论哪种情况,这些部分都可以包含以下内容:

    • 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

    设置extended为3时,该connection部分显示replication_connection_status表中的信息。该connection部分可以包含以下内容:

    currentlyQueueing节包含有关当前排队的事务的信息:

    • immediateCommitTimestamp:看QUEUEING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP
    • immediateCommitToNowTimeQUEUEING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP减号NOW()
    • originalCommitTimestamp:看QUEUEING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP
    • originalCommitToNowTimeQUEUEING_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
    • immediateCommitToEndTimeLAST_QUEUED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP减号NOW()
    • originalCommitTimestamp:看LAST_QUEUED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP
    • originalCommitToEndTimeLAST_QUEUED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP减号NOW()
    • queueTimeLAST_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节显示有关工作程序执行的最后一笔交易的以下信息:

    • applyTimeLAST_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
    • immediateCommitToEndTimeLAST_APPLIED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP减号NOW()
    • originalCommitTimestamp:看LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP
    • originalCommitToEndTimeLAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP减号NOW()
    • startTimestamp:看LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP
    • transaction:看LAST_APPLIED_TRANSACTION

    currentlyApplying节显示有关工作者当前正在应用的事务的以下信息:

    • immediateCommitTimestamp:看APPLYING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP
    • immediateCommitToNowTimeAPPLYING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP减号NOW()
    • originalCommitTimestamp:看APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP
    • originalCommitToNowTimeAPPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP减号NOW()
    • startTimestamp:看APPLYING_TRANSACTION_START_APPLY_TIMESTAMP
    • transaction:看APPLYING_TRANSACTION

    lastProcessed节包含有关工作程序处理的最后一笔交易的以下信息:

    • bufferTimeLAST_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
    • immediateCommitToEndTimeLAST_PROCESSED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP减号LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP
    • originalCommitTimestamp:看LAST_PROCESSED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP
    • originalCommitToEndTimeLAST_PROCESSED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP减号LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP
    • startTimestamp:看LAST_PROCESSED_TRANSACTION_START_BUFFER_TIMESTAMP
    • transaction:看LAST_PROCESSED_TRANSACTION

    如果启用了并行应用程序工作程序,则工作程序数组中的对象数在配置的工作程序中transactions或与之recovery匹配,并包括一个附加的协调程序对象。显示的信息与replication_applier_status_by_coordinator表中的信息匹配。该对象可以包含:

    currentlyProcessing节包含有关工作者正在处理的事务的以下信息:

    • immediateCommitTimestamp:看PROCESSING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP
    • immediateCommitToNowTimePROCESSING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP减号NOW()
    • originalCommitTimestamp:看PROCESSING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP
    • originalCommitToNowTimePROCESSING_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

    监视恢复操作

    的输出Cluster.status()显示有关RECOVERING状态中实例恢复操作进度的信息。将显示有关使用MySQL Clone或增量恢复进行实例恢复的信息。监视以下字段:

    • recoveryStatusText字段包括有关使用的恢复类型的信息。当MySQL Clone运行时,该字段显示“正在克隆”。当增量恢复正常工作时,该字段显示“正在进行分布式恢复”。
    • 使用MySQL Clone时,该recovery字段包括一个包含以下字段的字典:

      • cloneStartTime:克隆过程开始的时间戳
      • cloneState:克隆进度的状态
      • currentStage:克隆过程已达到的当前阶段
      • currentStageProgress:当前阶段的进度占完成进度的百分比
      • currentStageState:当前阶段状态

      示例Cluster.status()输出,为简洁起见进行了修剪:

                          ...
                          "recovery": {
                          "cloneStartTime": "2019-07-15 12:50:22.730", 
                          "cloneState": "In Progress", 
                          "currentStage": "FILE COPY", 
                          "currentStageProgress": 61.726837675213865, 
                          "currentStageState": "In Progress"
                          }, 
                          "recoveryStatusText": "Cloning in progress", 
                          ...
      
    • 使用增量恢复时,该recovery字段包括一个包含以下字段的字典:

      • stategroup_replication_recovery频道状态

      输出示例Cluster.status(),为简洁起见,对其进行了裁剪:

                          ...
                          "recovery": {
                          "state": "ON"
                          }, 
                          ...
      

    InnoDB集群和组复制协议

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

    • 当实例添加到群集,从群集中删除或重新加入群集,或者在群集上执行重新扫描或重新引导操作时,通信协议版本会自动设置为该实例支持的版本,该版本现在是最早的MySQL Server版。
    • 当通过从群集中删除实例,对其进行升级并将它们重新添加到群集中来进行滚动升级时,如果从旧群集中删除了旧MySQL Server版本的最后一个剩余实例,则会自动升级通信协议版本。它的升级。

    看在集群中使用的通信协议版本,使用Cluster.status()与所述功能extended选项设置。如果GRProtocolVersion群集具有仲裁且没有群集成员不可访问,则在字段中返回通信协议版本。

    在实例上检查MySQL版本

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

    • Cluster.status()
    • Cluster.describe()
    • Cluster.rescan()

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

    • Cluster.status()

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

      • Cluster对象的当前会话是8.0.11或更高版本。
      • Cluster对象的当前会话的运行速度低于8.0.11版本早的版本,但extended选项设置为3(或已经过时queryMemberstrue)。

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

      "topology": {
          "ic-1:3306": {
              "address": "ic-1:3306",
              "mode": "R/W",
              "readReplicas": {},
              "role": "HA",
              "status": "ONLINE",
              "version": "8.0.16"
      }
      

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

      "topology": {
          "ic-1:3306": {
              "address": "ic-1:3306",
              "mode": "R/W",
              "readReplicas": {},
              "role": "HA",
              "status": "ONLINE",
              "version": "5.7.24"
      }
      
    • Cluster.describe()

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

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

      "topology": [
          {
              "address": "ic-1:3306",
              "label": "ic-1:3306",
              "role": "HA",
              "version": "8.0.16"
          }
      ]
      
    • Cluster.rescan()

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

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

      "newlyDiscoveredInstances": [
          {
              "host": "ic-4:3306",
              "member_id": "82a67a06-2ba3-11e9-8cfc-3c6aa7197deb",
              "name": null,
              "version": "8.0.16"
          }
      ]
      

    超级只读和实例

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

    • dba.configureInstance()
    • dba.configureLocalInstance()
    • dba.dropMetadataSchema()

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

    mysql-js> var myCluster = dba.dropMetadataSchema()
    Are you sure you want to remove the Metadata? [y/N]: y
    The MySQL instance at 'localhost:3310' currently has the super_read_only system
    variable set to protect it from inadvertent updates from applications. You must
    first unset it to be able to perform any changes to this instance.
    For more information see:
    https://dev.mysql.com/doc/refman/en/server-system-variables.html#sysvar_super_read_only.
    
    Do you want to disable super_read_only and continue? [y/N]: y
    
    Metadata Schema successfully removed.
    

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

    要强制super_read_only=OFF在脚本中设置功能,请将clearReadOnly选项set 传递给true。例如dba.configureInstance(instance,{clearReadOnly: true}).

    为InnoDB集群配置用户

    创建可管理InnoDB集群的用户的推荐方法是clusterAdmindba.configureInstance()dba.configureLocalInstance()操作中使用该选项。如果要手动配置可以管理InnoDB集群的用户,则该用户需要以下特权,而所有这些特权都具有GRANT OPTION

    • 在*全局权限。*为RELOADSHUTDOWNPROCESSFILESELECTSUPERREPLICATION SLAVEREPLICATION CLIENTCREATE USERSYSTEM_VARIABLES_ADMINPERSIST_RO_VARIABLES_ADMIN
    • 为架构特定的权限mysql_innodb_cluster_metadata.*ALTERALTER ROUTINECREATECREATE ROUTINECREATE TEMPORARY TABLESCREATE VIEWDELETEDROPEVENTEXECUTEINDEXINSERTLOCK TABLESREFERENCESSHOW VIEWTRIGGERUPDATE,和mysql.*INSERTUPDATEDELETE

    如果仅需要读操作(例如,为了监视而创建用户),则可以使用具有更多受限特权的帐户。为用户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;
    

    有关更多信息,请参见“账户权限控制”。

    配置实例的自动重新加入

    运行MySQL 8.0.16及更高版本的实例支持组复制自动重新加入功能,该功能使您可以将实例配置为在被驱逐后自动重新加入群集。有关背景信息,请参见“对故障检测和网络分区的响应”。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,,这意味着离开群集的实例意外变为只读。如果exitStateAction设置为OFFLINE_MODE(从MySQL 8.0.18起可用),则离开群集的实例会意外变为只读,并进入脱机模式,在该模式下,实例将断开现有客户端的连接,并且不接受新连接(具有管理员特权的客户端除外)。如果exitStateAction设置为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集群和二进制日志清除

    在MySQL 8中,二进制日志会自动清除(由定义binlog_expire_logs_seconds)。这意味着已经运行了更长时间的集群binlog_expire_logs_seconds最终可能不包含具有完整二进制日志的实例,该二进制日志包含实例所应用的所有事务。这可能导致需要在实例加入群集之前自动配置实例,例如使用MySQL Enterprise Backup。运行8.0.17及更高版本的实例支持MySQL Clone插件,该插件通过提供不依赖增量恢复的自动置备解决方案来解决此问题,请参见“将MySQL Clone与InnoDB群集一起使用”。运行早于8.0.17的版本的实例仅支持增量恢复,结果是,取决于实例所运行的MySQL版本,可能必须自动设置实例。否则,依赖分布式恢复的操作(例如Cluster.addInstance()等等)可能会失败。

    在运行早期版本的MySQL的实例上,以下规则用于二进制日志清除:

    • 运行版本低于8.0.1的实例不会自动清除二进制日志,因为默认值为expire_logs_days0。
    • 运行版本低于8.0.1但低于8.0.4的实例将在30天后清除二进制日志,因为默认值为expire_logs_days30。
    • 运行版本高于8.0.10的实例在30天后清除二进制日志,因为默认值为binlog_expire_logs_seconds 2592000,默认值为expire_logs_days0。

    因此,根据群集运行的时间长短,可以清除二进制日志,并且您可能必须手动设置实例。同样,如果您手动清除二进制日志,则可能会遇到相同的情况。因此,强烈建议您升级到8.0.17之后的MySQL版本,以充分利用MySQL Clone为分布式恢复提供的自动配置,并在为InnoDB集群配置实例时最大程度地减少停机时间。

    从InnoDB集群中删除实例

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

    mysql-js> cluster.removeInstance('root@localhost:3310')
    
    The instance will be removed from the InnoDB cluster. Depending on the instance
    being the Seed or not, the Metadata session might become invalid. If so, please
    start a new session to the Metadata Storage R/W instance.
    
    Attempting to leave from the Group Replication group...
    
    The instance 'localhost:3310' was successfully removed from the cluster.
    

    您可以选择传入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仅当您要忽略任何错误(例如未处理的事务或实例为)并且不打算在群集中重用该实例时,才应将该选项与一起使用。从集群中删除实例时忽略错误可能会导致实例与集群不同步,从而阻止它在以后重新加入集群。仅在计划不再在群集中使用该实例时才使用该选项,在所有其他情况下,您应始终尝试恢复该实例,并仅在该实例可用且状态良好时(即状态为status)将其删除。Cluster.removeInstance(instance)UNREACHABLEforceONLINE

    自定义InnoDB集群

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

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

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

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

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

    重新加入集群

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

    小费

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

    如果实例没有配置,实例的配置将保留(请参阅 Persisting Settings),重新启动后该实例不会自动重新加入群集。解决方案是发出cluster.rejoinInstance()该实例,以便将该实例再次添加到群集中,并确保更改得以保留。将InnoDB集群配置持久保存到实例的选项文件后,它将自动重新加入集群。

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

    cluster.removeInstance("root@instanceWithOldUUID:3306", {force: true})
    
    cluster.rescan()
    

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

    从仲裁丢失中恢复群集

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

    重要

    此操作潜在危险,因为如果使用不当,可能会造成裂脑情况,应视为万不得已。绝对确保该组中没有分区仍在网络中的某个位置运行,但是无法从您所在的位置访问。

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

    mysql-js> cluster.forceQuorumUsingPartitionOf("icadmin@ic-1:3306")
    
      Restoring replicaset 'default' from loss of quorum, by using the partition composed of [icadmin@ic-1:3306]
    
      Please provide the password for 'icadmin@ic-1:3306': ******
      Restoring the InnoDB cluster ...
    
      The InnoDB cluster was successfully restored using the partition from the instance 'icadmin@ic-1:3306'.
    
      WARNING: To avoid a split-brain scenario, ensure that all other members of the replicaset
      are removed or joined back to the group that was restored.
    

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

    还原的集群可能(也不一定)包含组成该集群的所有原始实例。例如,如果原始群集包含以下五个实例:

    • ic-1
    • ic-2
    • ic-3
    • ic-4
    • ic-5

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

    • ic-1
    • ic-2
    • ic-3

    因为ic-1看到ic-2ic-3作为ONLINE,不看ic-4ic-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的交互模式,则可以使用rejoinInstancesremoveInstances选项手动配置实例,这些实例应在集群重启时加入或删除。

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

    小费

    要手动检测哪个实例具有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:布尔值,用于禁用或启用命令执行中的向导。控制是否提供提示和确认。默认值等于由指定的MySQL Shell向导模式shell.options.useWizards
    • addInstances:列出要添加到元数据的新活动实例的连接数据,或者列出“ auto ”以将丢失的实例自动添加到元数据。值“ auto ”不区分大小写。

      • 列表中指定的实例将添加到元数据中,而不提示您进行确认
      • 在交互模式下,系统将提示您确认是否添加了该addInstances选项中未包括的新发现实例。
      • 在非交互方式下,未包含在addInstances选项中的新发现实例将在输出中报告,但不会提示您添加它们
    • removeInstances:列出要从元数据中删除的过时实例的连接数据,或者列出“ auto ”以从元数据中自动删除过时的实例。

      • 列表中指定的实例将从元数据中删除,而不会提示您进行确认
      • 在交互方式下,系统将提示您确认删除removeInstances选项中未包括的过时实例。
      • 在非交互方式下,未包含在removeInstances选项中的过时实例将在输出中报告,但不会提示您删除它们
    • updateTopologyMode:布尔值,用于指示元数据中的拓扑模式(单主要或多主要)是否应该更新(真)或不更新(假)以匹配集群使用的拓扑模式。默认情况下,不更新元数据(false)。

      • 如果值为,true则将InnoDB群集元数据与组复制正在使用的当前模式进行比较,并在必要时更新元数据。在AdminAPI之外对群集的拓扑模式进行更改后,请使用此选项来更新元数据。
      • 如果值为,false则即使有关集群拓扑模式的InnoDB集群元数据与集群的组复制组使用的拓扑不同,也不会更新
      • 如果未指定该选项,并且元数据中的拓扑模式与群集的“组复制”组使用的拓扑不同,则:

        • 在交互模式下,系统将提示您确认元数据中拓扑模式的更新
        • 在非交互模式下,如果集群的组复制组使用的拓扑与InnoDB集群元数据之间存在差异,则将报告该拓扑,并且不对元数据进行任何更改
      • 当元数据拓扑模式更新为与组复制模式匹配时,所有实例上的自动增量设置都将按照InnoDB集群和自动增量中所述进行更新。

    检查实例状态

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

    下面演示了如何在运行中的MySQL Shell中发布此代码:

    mysql-js> cluster.checkInstanceState('icadmin@ic-4:3306')
    

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

    • 好的,新的:实例尚未执行任何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()
    The cluster still has the following registered instances:
    {
        "clusterName": "testCluster", 
        "defaultReplicaSet": {
            "name": "default", 
            "topology": [
                {
                    "address": "ic-1:3306", 
                    "label": "ic-1:3306", 
                    "role": "HA"
                }, 
                {
                    "address": "ic-2:3306", 
                    "label": "ic-2:3306", 
                    "role": "HA"
                }, 
                {
                    "address": "ic-3:3306", 
                    "label": "ic-3:3306", 
                    "role": "HA"
                }
            ]
        }
    }
    WARNING: You are about to dissolve the whole cluster and lose the high
    availability features provided by it. This operation cannot be reverted. All
    members will be removed from the cluster and replication will be stopped,
    internal recovery user accounts and the cluster metadata will be dropped. User
    data will be maintained intact in all instances.
    
    Are you sure you want to dissolve the cluster? [y/N]: y
    
    ERROR: The instance 'ic-2:3306' cannot be removed because it is on a '(MISSING)'
    state. Please bring the instance back ONLINE and try to dissolve the cluster
    again. If the instance is permanently not reachable, then you can choose to
    proceed with the operation and only remove the instance from the Cluster
    Metadata.
    
    Do you want to continue anyway (only the instance metadata will be removed)?
    [y/N]: y
    
    Instance 'ic-3:3306' is attempting to leave the cluster...  Instance 'ic-1:3306'
    is attempting to leave the cluster...
    
    WARNING: The cluster was successfully dissolved, but the following instance was
    skipped: 'ic-2:3306'. Please make sure this instance is permanently unavailable
    or take any necessary manual action to ensure the cluster is fully dissolved.
    

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

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

    mysql-js> Cluster.dissolve({force: true})
    

    从群集中删除所有可以到达的实例,所有不可达的实例都将被忽略。本节中有关强制从群集中删除丢失的实例的警告同样适用于这种强制执行溶解操作的技术。

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

    mysql-js> Cluster.dissolve({interactive: true})
    

    dba.gtidWaitTimeoutmysql外壳选项配置多长时间Cluster.dissolve()操作集群交易等待从集群中删除一个目标实例之前应用,但只有当目标实例ONLINE。如果在等待将集群事务应用于任何要删除的实例上时达到超时,则发出错误,除非使用force:true,否则将跳过该错误。

    注意

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

    保护您的集群

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

    重要

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

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

    • 设置createCluster({memberSslMode:'DISABLED'})可确保为群集中的种子实例禁用SSL加密。
    • createCluster({memberSslMode:'REQUIRED'})然后为集群中的种子实例启用设置 SSL加密。如果无法启用,则会引发错误。
    • 设置createCluster({memberSslMode:'AUTO'})(默认)然后,如果服务器实例支持SSL加密,则将自动启用SSL加密;如果服务器不支持SSL加密,则将禁用。
    注意

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

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

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

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

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

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

    创建服务器白名单

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

    mysql-js> cluster.addInstance("icadmin@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运行。例如:

    shell>mysqlsh -f setup-innodb-cluster.js
    
    注意

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

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

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

    配置选举过程

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

    设置值将在实例上memberWeight配置group_replication_member_weight系统变量。组复制将值范围限制在0到100之间,如果提供更高或更低的值,则会自动对其进行调整。如果未提供任何值,则组复制将使用默认值50。有关更多信息,请参见“单主模式”。

    例如,在当前主数据库意外离开群集的ic-3情况下,配置首选实例进行故障转移ic-1的群集memberWeight,如下所示:

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

    配置故障转移一致性

    如果主故障转移发生在单主模式下,则组复制提供了指定故障转移保证(最终或“读取写入内容”)的能力(请参见“配置事务一致性保证”)。您可以在创建时通过将consistency选项(在版本8.0.16之前是该failoverConsistency选项(现在不建议使用该选项))传递给dba.createCluster()操作来配置InnoDB集群的故障转移保证,该操作将配置group_replication_consistency种子实例上的系统变量。此选项定义在单主要组中选举新的主要组时使用的新防护机制的行为。栅栏限制了从新主数据库进行写入和读取的连接,直到它应用了来自旧主数据库的更改的任何待处理积压工作(有时称为“读取您的写入内容”)。在建立隔离机制的同时,应用程序在任何积压情况下都不会在短时间内看到时间倒退。这样可以确保应用程序不会从新当选的主数据库中读取过时的信息。

    consistency如果目标MySQL服务器版本为8.0.14或更高版本,并添加到已配置了一个群集实例时,才支持选项consistency的选择会自动配置为拥有group_replication_consistency上有选择支持所有群集成员相同。变量默认值由组复制控制,为EVENTUAL,更改consistency选项BEFORE_ON_PRIMARY_FAILOVER以启用防护机制。或者使用consistency=0for EVENTUALconsistency=1for BEFORE_ON_PRIMARY_FAILOVER

    注意

    consistency在多主要InnoDB集群上使用该选项无效,但被允许,因为稍后可以通过该Cluster.switchToSinglePrimaryMode()操作将集群更改为单主要模式。

    更改集群的拓扑

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

    注意

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

    通常,当当前主节点意外退出集群时,例如由于意外停机,单主节点集群会选择新的主节点。选举过程通常用于选择当前哪个中学作为新的中学。要覆盖选举过程并强制特定服务器成为新的主服务器,请使用函数,其中指定了到实例的连接,该实例应成为新的主服务器。这使您可以配置基础的组复制组,以选择特定实例作为新的主实例,从而绕过选举过程。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_incrementauto_increment_offset变量被配置为避免大小为9(组复制组的最大支持大小)的多主集群发生自动增量冲突的可能性。用于配置这些变量的逻辑可以总结为:

    • 如果组以单主要模式运行,则设置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%实例数。