MySQL Shell 9.0  /  MySQL InnoDB 集群  /  监控 InnoDB 集群

7.7 监控 InnoDB 集群

本节介绍如何使用 AdminAPI 监控 InnoDB 集群。

使用 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",
                "memberRole": "PRIMARY",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": "applier_queue_applied",
                "role": "HA",
                "status": "ONLINE"
                "version": "8.0.30"
            },
            "ic-2:3306": {
                "address": "ic-2:3306",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": "applier_queue_applied",
                "role": "HA",
                "status": "ONLINE"
                "version": "8.0.30"
            },
            "ic-3:3306": {
                "address": "ic-3:3306",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": "applier_queue_applied",
                "role": "HA",
                "status": "ONLINE"
                "version": "8.0.30"
            }
        }
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "mysql://icadmin@ic-1:3306"
}

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

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

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

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

  • ssl:集群是否使用安全连接。 根据在 createCluster()addInstance() 期间如何配置 memberSslMode 选项,显示 REQUIREDDISABLED 值。 此参数返回的值对应于实例上 group_replication_ssl_mode 服务器变量的值。 请参阅第 7.6 节,“保护 InnoDB 集群的安全”

  • status:InnoDB 集群的状态。 状态描述了此集群提供的高可用性。 状态为以下之一

    • OK:集群处于联机状态,最多可以容忍 n 个故障。 集群中有三个或更多成员,并且它们都正常运行。

    • OK_PARTIAL:集群处于联机状态,最多可以容忍 n 个故障。 集群中至少有三个成员服务器处于组复制的联机状态。 但是,一个或多个成员服务器当前未作为集群的活动成员参与。

    • OK_NO_TOLERANCE:集群不能容忍任何故障。

    • OK_NO_TOLERANCE_PARTIAL:集群不能容忍任何故障。 集群中的一个或两个成员服务器处于联机状态,但一个或多个服务器处于脱机、恢复、错误或不可达状态。 由于某些成员不可用,因此集群没有足够的容错能力。

    • NO_QUORUM:集群没有仲裁,这意味着复制组的大多数成员服务器都不可用以就决策达成一致,并且无法处理写事务。

    • OFFLINE:组的所有成员都处于脱机状态。

    • ERROR:集群中没有联机成员。

    • UNREACHABLE:无法连接到任何联机成员。

    • UNKNOWN:无法连接到任何联机成员。

    • FENCED_WRITES:集群与写流量隔离。

  • topology:MySQL 服务器实例的状态。 状态为以下之一

    • 实例的主机名:实例的主机名,例如 "localhost:3310"

    • memberRole:组复制插件报告的成员角色,请参阅 replication_group_members 表的 MEMBER_ROLE 列。

    • mode:服务器是读写 (“R/W”) 还是只读 (“R/O”)。 这是从实例上 super_read_only 变量的当前状态以及集群是否具有仲裁派生的。 在以前的版本中,模式的值是从实例是充当主实例还是辅助实例派生的。 通常,如果实例是主实例,则模式为“R/W”,如果实例是辅助实例,则模式为“R/O”。 集群中任何没有可见仲裁的实例都标记为“R/O”,而不管 super_read_only 变量的状态如何。

      注意

      如果成员 status 不是 ONLINE,则 mode 将报告为 n/a

    • replicationLag:返回以下值之一

      • 最后一个事务提交时间戳和最后一个事务应用时间戳之间的时间差,格式为 HH:MM:SS。

        如果使用了多个工作线程,则从执行最旧事务的工作线程中检索该值。

      • null:复制连接或 SQL 线程未运行。

      • applier_queue_applied:应用器队列已应用所有内容。 也就是说,如果最后一个排队的交易和最后一个应用的交易相同,或者应用的交易为 0。

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

    • status:集群中此元素的状态。 状态为以下之一

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

      • OFFLINE:实例已与其他实例断开连接。

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

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

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

        重要

        实例进入 ERROR 状态后,super_read_only 选项将设置为 ON。 要退出 ERROR 状态,必须使用 super_read_only=OFF 手动配置实例。

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

        注意

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

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

  • version:实例上运行的 MySQL 服务器版本。 有关更多信息,请参阅检查实例上的 MySQL 版本

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

  • 0:禁用附加信息,默认设置。

  • 1:包括有关组复制协议版本、组名称、通信栈、集群成员 UUID、集群成员角色和状态(由组复制报告)以及受防护系统变量列表的信息。

  • 2:包括有关连接和应用器处理的事务的信息。

  • 3:包括有关每个集群成员执行的复制的更详细统计信息。

使用布尔值设置 extended 等同于设置整数值 0 和 1。

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

  • 以下 defaultReplicaSet 对象的附加属性

  • 以下每个 topology 对象对象的附加属性

    • fenceSysVars 一个列表,其中包含由 AdminAPI 配置的受防护系统变量的名称。目前考虑的受防护系统变量有 read_onlysuper_read_onlyoffline_mode。系统变量的列出与其值无关。

    • instanceErrors 对于每个实例,显示可以为该实例检测到的任何诊断信息。例如,如果实例是辅助实例,并且 super_read_only 变量未设置为 ON,则会显示警告。此信息可用于故障排除。

    • memberId 每个集群成员的 UUID。

    • memberState 组复制插件报告的成员状态,请参阅 replication_group_members 表的 MEMBER_STATE 列。

要查看有关恢复和常规事务 I/O、应用器工作线程统计信息和任何延迟的信息;应用器协调器统计信息(如果启用了并行复制应用器);错误以及来自接收器和应用器线程的其他信息,请对 extended 使用值 2 或 3。当您使用这些值时,将打开与集群中每个实例的连接,以便可以查询其他特定于实例的统计信息。输出中包含的确切统计信息取决于实例的状态和配置以及服务器版本。此信息与 replication_group_member_stats 表中显示的信息相匹配,有关更多信息,请参阅匹配列的说明。 ONLINE 的实例在输出中包含 transactions 部分。 RECOVERING 的实例在输出中包含 recovery 部分。当您将 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 表中的信息。

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

  • 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 部分显示以下有关工作线程应用的最后一笔交易的信息

  • 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 部分包含以下有关工作线程处理的最后一笔交易的信息

  • 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

如果启用了并行复制应用器,则 transactionsrecovery 中的 workers 数组中的对象数量与已配置的工作线程数量相匹配,并且包含一个额外的协调器对象。显示的信息与 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

如果在 replication_applier_status_by_worker 表中检测到错误,则 worker 对象将包含以下信息

  • lastErrno:请参阅 LAST_ERROR_NUMBER

  • lastError:请参阅 LAST_ERROR_MESSAGE

  • lastErrorTimestamp:请参阅 LAST_ERROR_TIMESTAMP

如果在 replication_connection_status 表中检测到错误,则 connection 对象将包含以下信息

  • lastErrno:请参阅 LAST_ERROR_NUMBER

  • lastError:请参阅 LAST_ERROR_MESSAGE

  • lastErrorTimestamp:请参阅 LAST_ERROR_TIMESTAMP

如果在 replication_applier_status_by_coordinator 表中检测到错误,则 coordinator 对象将包含以下信息

  • lastErrno:请参阅 LAST_ERROR_NUMBER

  • lastError:请参阅 LAST_ERROR_MESSAGE

  • lastErrorTimestamp:请参阅 LAST_ERROR_TIMESTAMP

监控恢复操作

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

  • recoveryStatusText 字段包含有关正在使用的恢复类型的信息。当 MySQL 克隆正在工作时,该字段显示 正在克隆。当增量恢复正在工作时,该字段显示 分布式恢复正在进行中

  • 当使用 MySQL 克隆时,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",
    ...
  • 当使用增量恢复并且 extended 选项设置为 1 或更大时,recovery 字段包含一个字典,其中包含以下字段

    • stategroup_replication_recovery 通道的状态

    • recoveryChannel:为执行增量恢复的实例或恢复通道状态未关闭的实例显示。增量恢复利用接收器线程从源接收事务,应用器线程在实例上应用接收的事务。提供以下信息

      • applierQueuedTransactionSetSize:当前排队的、等待应用的事务数。

      • applierState:复制应用器的当前状态,ONOFF

      • applierStatus:应用器线程的当前状态。applierThreadState 字段中显示的状态的汇总。可以是以下之一

        • APPLIED_ALL:没有排队的交易等待应用

        • APPLYING:有交易正在应用

        • ON:线程已连接,并且没有排队的交易

        • ERROR:应用交易时出错

        • OFF:应用器线程已禁用

      • applierThreadState:任何应用器线程的当前状态。提供有关应用器线程正在执行的操作的确切详细信息。有关更多信息,请参见 复制 SQL 线程状态

      • receiverStatus:接收器线程的当前状态。receiverThreadState 字段中显示的状态的汇总。可以是以下之一

        • ON:接收器线程已成功连接并准备好接收

        • CONNECTING:接收器线程正在连接到源

        • ERROR:接收交易时出错

        • OFF:接收器线程已正常断开连接

      • receiverThreadState:接收器线程的当前状态。提供有关接收器线程正在执行的操作的确切详细信息。有关更多信息,请参见 复制 I/O(接收器)线程状态

      • source:正在应用的交易的来源。

    示例 Cluster.status() 输出,为了简洁起见进行了删减

    ...
    "recovery": {
                        "recoveryChannel": {
                            "applierQueuedTransactionSetSize": 2284, 
                            "applierStatus": "APPLYING", 
                            "applierThreadState": "Opening tables", 
                            "receiverStatus": "ON", 
                            "receiverThreadState": "Queueing master event to the relay log", 
                            "source": "ic-2:3306"
                        }, 
                        "state": "ON"
                    },
    ...

InnoDB Cluster 和组复制协议

组复制具有组通信协议的概念,有关更多信息,请参见 设置组的通信协议版本。组复制通信协议版本通常必须明确管理,并设置为适应您希望组支持的最旧 MySQL 服务器版本。但是,每当使用 AdminAPI 操作更改集群拓扑时,InnoDB Cluster 都会自动透明地管理其成员的通信协议版本。集群始终使用当前是集群一部分或正在加入集群的所有实例支持的最新通信协议版本。

  • 将实例添加到集群、从集群中删除实例或重新加入集群,或者对集群执行重新扫描或重新启动操作时,通信协议版本会自动设置为现在位于最早 MySQL 服务器版本的实例支持的版本。

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

要查看集群中使用的通信协议版本,请使用启用了 extended 选项的 Cluster.status() 函数。通信协议版本在 GRProtocolVersion 字段中返回,前提是集群具有仲裁并且没有集群成员不可达。

检查实例上的 MySQL 版本

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

  • Cluster.status()

  • Cluster.describe()

  • Cluster.rescan()

行为因 Cluster 对象会话的 MySQL 服务器版本而异。

  • Cluster.status()

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

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

    • Cluster 对象的当前会话运行的版本低于 8.0.11,但 extended 选项设置为 3。

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

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

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

    例如,在运行版本 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() 操作检测到不属于该集群的实例,则会为 newlyDiscoveredInstance 对象的每个实例 JSON 对象返回 version 字符串属性。

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

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