基于物理复制的主备集群容灾

概述

平凯数据库物理复制用于在多个平凯数据库集群之间建立基于日志的主备复制关系。与逻辑复制相比,物理复制直接复制底层数据,适合主备容灾、主备切换和故障恢复场景。

物理复制支持同城双中心部署,提升集群级高可用能力。该能力支持跨集群同步复制(RPO = 0),也支持异步复制模式以满足异地容灾需求。

核心指标参考(实际以网络、拓扑和负载为准):

  • 故障自动切换时间 (RTO):< 15 秒
  • 演练切换时间 (RTO):< 30 秒
  • 同步复制数据丢失量 (RPO):0
  • 异步复制数据丢失量 (RPO):< 5 秒
  • 写入延迟:同步复制会增加集群的写入延迟,延迟的估计值为“本地落盘时间 + 跨集群网络一次 RTT + 远端落盘时间”。异步复制不会增加写入延迟。

基本概念

阅读本文时,建议先区分以下两组概念:

  • primary / standby:表示集群当前的服务角色。
    • primary:可读可写。
    • standby:只读,不接受普通业务写入。
  • source / replica:表示一对物理复制集群之间的数据流向。
    • source:上游,负责向下游提供日志和快照。
    • replica:下游,负责接收并应用复制数据。

在最常见的一主一备场景中,primary 通常也是 sourcestandby 通常也是 replica。但在链式复制拓扑中,一个中间 standby 集群既可以是上游链路的 replica,也可以是下游链路的 source

使用前准备

在开始前,请确认以下条件均满足:

  • 集群的 TiDB、TiKV、PD 已全部升级到包含物理复制实现的版本。
  • primary / standby 集群均未部署 TiFlash。
  • standby 集群必须为空(不能包含用户创建的数据库或表)。
  • 复制链路两端的所有 TiKV 节点必须启用相关配置项(见下表)。
  • replica 集群需要能够连接 source 集群的某个 TiDB SQL 地址(建议使用 VIP 以保证高可用)。
  • SOURCE_USER 对应的账号必须在 source 集群中拥有 SUPER 权限。
  • 复制链路两端的集群必须能互相访问对方的 PD/TiKV 服务。
  • 客户端需能够处理 TiDB 在部分切换步骤中的自动重启,并能完成重连。

下表所列 TiKV 配置项均为必需项,且要求启用。

配置项作用备注
replicator.enable启动 TiKV 上的 replicator 服务必须开启
raft-engine.enable启用 raft-engine必须开启
raft-engine.enable-log-archive开启 raft-engine 日志归档必须开启
raft-engine.archive-retention-time设置日志归档保留时间必须配置,且大于预期的网络中断时长;建议配置为 48h,但需综合评估磁盘容量是否能承载该时长的日志写入量
resolved-ts.enable启用 resolved-ts必须开启(standby 集群快照读和 FLASHBACK 依赖此项)
resolved-ts.advance-ts-intervalresolved-ts 推进间隔必须配置,间隔越短快照读延迟越低,建议设置为 1s

可通过以下 SQL 检查 TiKV 配置(示例):

SELECT `instance`, `key`, `value` FROM information_schema.cluster_config WHERE `type` = 'tikv' AND `key` IN ( 'replicator.enable', 'raft-engine.enable', 'raft-engine.enable-log-archive', 'raft-engine.archive-retention-time', 'resolved-ts.enable', 'resolved-ts.advance-ts-interval' ) ORDER BY `instance`, `key`;

保护模式

物理复制支持三种保护模式:

模式名称含义说明
MAXIMUM_PERFORMANCE最大性能异步复制提交不等待 standby ACK,优先保证吞吐。
MAXIMUM_PROTECTION最大保护同步复制提交等待 standby ACK,不自动降级。若 standby 故障,primary 会阻塞写入。
MAXIMUM_AVAILABILITY最大可用同步复制,可自动降级提交等待 standby ACK;若阻塞超过 DEGRADE_TIMEOUT,自动降级到 MAXIMUM_PERFORMANCE

DEGRADE_TIMEOUT 定义了 primary 在同步复制下等待 standby ACK 的超时阈值。超过该时间后,系统为保证业务连续性会自动降级为异步。该参数格式为正的 duration 字符串,如 '30s''1m''2h',最小为 1s

创建物理复制

ADMIN CREATE LOG REPLICATION <name> SOURCE_HOST = '<source_tidb_host>' SOURCE_PORT = <source_tidb_port> SOURCE_USER = '<source_tidb_user>' SOURCE_PASSWORD = '<source_tidb_password>' PROTECTION_MODE = MAXIMUM_PERFORMANCE | MAXIMUM_PROTECTION | MAXIMUM_AVAILABILITY [DEGRADE_TIMEOUT = '<duration>'];

ADMIN CREATE LOG REPLICATION 必须在将要成为 standby 的集群上执行。

SOURCE_HOSTSOURCE_PORT 指向 source 集群的 TiDB SQL 地址;SOURCE_USER 需在 source 集群具备 SUPER 权限。

创建物理复制时,语法允许设置 PROTECTION_MODE;未指定时默认 MAXIMUM_PERFORMANCE。为了避免在创建阶段影响 primary 写入,建议创建时不设置保护模式,待初始化完成后再通过 ADMIN ALTER LOG REPLICATION 切换。

若确需设置为 MAXIMUM_AVAILABILITY,必须同时设置 DEGRADE_TIMEOUT

创建后的行为

创建成功后,目标集群会进入 standby 模式:

  • 普通写请求会被禁止。
  • 一部分后台任务(如统计信息自动更新)会被阻塞,这些后台任务的功能完全由 primary 日志同步来实现。
  • standby 集群的 TiKV 会启动日志复制组件连接上游,上游集群通过 region learner 将数据发送到下游。
  • 状态可通过 INFORMATION_SCHEMA.LR_* 系统视图查看。若 INITIALIZING_PROGRESS 停滞,请检查网络连通性及 TiKV replicator 日志。

修改和管理复制链路

CREATE 外,其余管理命令可以在 primary 集群以及复制链路的直接上游/下游集群执行。

修改保护模式

ADMIN ALTER LOG REPLICATION <name> PROTECTION_MODE = MAXIMUM_PERFORMANCE | MAXIMUM_PROTECTION | MAXIMUM_AVAILABILITY [DEGRADE_TIMEOUT = '<duration>'];

暂停复制

ADMIN PAUSE LOG REPLICATION <name>;

暂停后:

  • standby 停止复制,状态变为 PAUSED
  • 若原本为同步复制,系统会先将同步复制切换为异步复制再进入暂停。

恢复复制

ADMIN RESUME LOG REPLICATION <name>;

恢复后:

  • 当前实现会以 MAXIMUM_PERFORMANCE 启动恢复流程;如需同步复制,请再执行 ADMIN ALTER LOG REPLICATION 调整保护模式。

切换 source

ADMIN ALTER LOG REPLICATION <name> CHANGE SOURCE TO <new_source_cluster_id>;

限制如下:

  • 仅支持在当前复制链路为 MAXIMUM_PERFORMANCE 时执行。
  • CHANGE SOURCE 与其他 ALTER 选项互斥,不能在同一条语句中同时修改保护模式或降级超时。
  • source 不能是当前 source,也不能是 replica 自身。
  • source 不能位于当前 replica 的下游子树中(防止形成环)。
  • 复制处于 PAUSED 状态时无法执行。

提示:

CHANGE SOURCE 主要用于链式复制拓扑调整。执行过程中可能触发 primary 短暂禁写,建议在业务低峰期操作。

删除复制

ADMIN DROP LOG REPLICATION <name>;

删除后,系统会清理 primary 上的复制状态和相关元数据。若原本为同步复制,系统会先将复制切换为异步复制再执行 DROP,以避免同步复制在缺少 standby ACK 时导致业务阻塞。被 DROP 的集群(旧 standby)仍处于 standby 状态,如需退出 standby 请执行 ADMIN ACTIVATE STANDBY MODE = FLASHBACK

主备切换

计划内切换 (Switchover)

在当前 primary 集群执行:

ADMIN SWITCHOVER PRIMARY TO <new_primary_cluster_id>;

限制与建议:

  • 仅支持相邻 primary/standby 之间的切换。
  • 切换前复制链路不能处于暂停状态。
  • 建议先确认目标集群在 INFORMATION_SCHEMA.LR_CLUSTER_STATUS_GLOBAL 中的 SWITCHOVER_READY = 'YES'
  • 切换过程中,系统会自动完成 primary 禁止写入、追平数据和 primary/standby 角色切换。期间 TiDB 节点会自动重启。
  • 切换完成后,请更新业务侧的 VIP、DNS 或连接串。建议在业务低峰期操作。

计划外切换 (Failover)

当确认 primary 集群已断开连接时,在当前 standby 集群执行:

-- 模式一:回退到一致性快照点 ADMIN ACTIVATE STANDBY MODE = FLASHBACK; -- 模式二:强制提交已接收数据(仅限同步复制,可确保 RPO = 0) ADMIN ACTIVATE STANDBY MODE = FORCE_COMMIT;

使用 FORCE_COMMIT 前,必须确认当前复制为同步复制,且原 primary 尚未执行 ADMIN DROP LOG REPLICATION;同时确认原 primary 已彻底停机或网络隔离。若已经执行 ADMIN DROP LOG REPLICATION,只能使用 FLASHBACK

将旧 primary 重新接回(REINSTATE

MAXIMUM_PROTECTION 模式下完成 ACTIVATE STANDBY(原 standby 已切换为新的 primary)后,如需将原 primary 故障恢复并重新接回新的 primary,可执行 REINSTATE。在该模式下,旧 primary 故障恢复时因缺少 standby ACK 导致 TiDB 无法启动。此操作只能通过 pd-ctl 在旧 primary 集群对应的 PD 上发起。

通过 pd-ctl 在旧 primary 集群对应的 PD 上发起:

pd-ctl -u http://<old-primary-pd-host>:2379 log-replication reinstate <new-primary-id> <new-log-replication-name>

示例:

pd-ctl -u http://127.0.0.1:2379 log-replication reinstate 1024 dr_reinstate

REINSTATE 会把旧 primary 转成新 primarystandby,并建立新的复制链路。

standby 集群的快照读

standby 模式下,TiDB 提供快照读(Snapshot Read),其可用时间戳以 CHECKPOINT_TS 为准。

  • 实时性:读取的是 standby 集群本地已应用的最新数据,可能落后于 primary
  • 一致性:同一条 SQL 语句内具备一致性快照。
  • 监控指标:快照读延迟可通过 INFORMATION_SCHEMA.LR_STATUS_GLOBAL 中的 CHECKPOINT_LAG 观察。

查看复制状态

核心状态视图说明

以下 LR_*INFORMATION_SCHEMA 的系统视图(内存表),字段值来自 PD。部分字段在未就绪或不适用时为 NULL

INFORMATION_SCHEMA.LR_STATUS_GLOBAL

物理复制的全局链路状态,主要字段如下:

字段说明
NAME复制链路名称
REPLICA_CLUSTER_ID下游集群 ID
SOURCE_CLUSTER_ID上游集群 ID
PROTECTION_MODE保护模式:MAXIMUM_PERFORMANCEMAXIMUM_PROTECTIONMAXIMUM_AVAILABILITY
DEGRADE_TIMEOUT降级超时时长(秒),仅 PROTECTION_MODE = MAXIMUM_AVAILABILITY 时有值
STATE复制状态:INITIALIZINGASYNC_REPLICATINGSYNC_REPLICATINGPAUSEDMAYBE_BLOCKING_SUSPENDEDNON_BLOCKING_SUSPENDED
CHECKPOINT_TS全局快照读时间戳
CHECKPOINT_TIME对应 CHECKPOINT_TS 的物理时间
CHECKPOINT_LAG快照读延迟(秒)
INITIALIZING_PROGRESS初始化进度百分比
LAST_HEARTBEAT_TIME最近一次心跳更新时间

当尚未产生 CHECKPOINT_TS 或尚未收到心跳时,CHECKPOINT_*LAST_HEARTBEAT_TIME 为空。

INFORMATION_SCHEMA.LR_CLUSTER_STATUS_GLOBAL

参与复制链路的各集群角色与就绪状态,主要字段如下:

字段说明
CLUSTER_ID集群 ID
SOURCE_CLUSTER_ID该集群的上游集群 ID(PRIMARY 行为空)
ROLE角色:PRIMARY / STANDBY
SWITCHOVER_READY是否具备计划内切换条件:YES / NO / UNKNOWN
FAILOVER_READY是否具备计划外切换条件:YES / NO / UNKNOWN
LOG_REPLICATION_STATE该集群视角的复制状态(PRIMARY 行为空)
LAST_HEARTBEAT_TIME该集群最近一次上报心跳的时间(PRIMARY 行为空)

该视图会包含一行 PRIMARY 记录;其余 STANDBY 行对应各条复制链路。

INFORMATION_SCHEMA.LR_WORKFLOW_HISTORY_GLOBAL

物理复制的工作流执行历史,主要字段如下:

字段说明
WORKFLOW_ID工作流唯一 ID
LOG_REPLICATION_NAME关联的复制链路名称
REPLICA_CLUSTER_ID下游集群 ID
SOURCE_CLUSTER_ID上游集群 ID
WORKFLOW_TYPE工作流类型,如 CREATEDROPPAUSERESUME
WORKFLOW_INFO工作流具体参数信息
START_TIME启动时间
END_TIME结束时间
WORKFLOW_STATE执行状态:PENDINGIN_PROGRESSCOMPLETED
WORKFLOW_STATE_INFO执行状态的详细信息,仅在 IN_PROGRESS 时有内容,其余状态为空
INITIATOR_CLUSTER_ID发起操作的集群 ID

WORKFLOW_STATE 用于展示工作流的执行状态;如需进一步排查,可结合 WORKFLOW_STATE_INFO 与时间字段进行判断。

INFORMATION_SCHEMA.LR_STATUS_LOCAL

当前连接集群的本地复制元数据(Key-Value 形式),用于诊断本地状态。VALUE 为字符串,可能出现字面量 NULL

常见键值如下:

KEY说明
cluster_id本集群 ID
role当前角色:PRIMARY / STANDBY
has_replica是否存在下游复制链路(true / false
last_global_update最近一次全局状态更新时间(格式:YYYY-MM-DD HH:MM:SS
source_cluster_id上游集群 ID(仅 STANDBY
source_pd_addrs上游 PD 地址列表(逗号分隔,仅 STANDBY
log_replication_name复制链路名称(仅 STANDBY
log_replication_state复制状态(仅 STANDBY
switchover_ready计划内切换就绪状态(仅 STANDBY
failover_ready计划外切换就绪状态(仅 STANDBY
checkpoint_ts本地可见的快照读时间戳(仅 STANDBY
checkpoint_lag快照读延迟(仅 STANDBY,值为时长字符串,如 3s
initializing_progress初始化进度百分比(仅 STANDBY
protection_mode保护模式(仅 STANDBY
degrade_timeout降级超时(仅 STANDBY,值为时长字符串,如 30s,不适用时为 NULL

示例查询

SELECT NAME, STATE, PROTECTION_MODE, CHECKPOINT_LAG FROM information_schema.lr_status_global;

输出参考:

NAME | STATE | PROTECTION_MODE | CHECKPOINT_LAG ---------+-------------------+------------------------+--------------- dr_east | SYNC_REPLICATING | MAXIMUM_PROTECTION | 3

典型运维路径

  1. 检查配置:部署 primary/standby 集群并验证 TiKV 配置。
  2. 建立链路:在 standby 集群执行 ADMIN CREATE LOG REPLICATION
  3. 观察初始化:通过 INFORMATION_SCHEMA.LR_STATUS_GLOBAL 确认 INITIALIZING_PROGRESS 达到 100%。
  4. 调整保护模式:初始化完成后,按需切换到 MAXIMUM_PROTECTIONMAXIMUM_AVAILABILITY
  5. 日常管理:按需执行暂停、恢复、切换 source 或修改保护模式。
  6. 故障处理:根据故障类型选择计划内切换或计划外激活。
  7. 接回旧主:旧 primary 恢复后,按需执行 REINSTATE 将其接回链路。
  8. 清理链路:执行 ADMIN DROP LOG REPLICATION 清理状态,并使用 ADMIN ACTIVATE STANDBY MODE = FLASHBACK 让集群退出 standby 状态。