基于物理复制的主备集群容灾
概述
平凯数据库物理复制用于在多个平凯数据库集群之间建立基于日志的主备复制关系。与逻辑复制相比,物理复制直接复制底层数据,适合主备容灾、主备切换和故障恢复场景。
物理复制支持同城双中心部署,提升集群级高可用能力。该能力支持跨集群同步复制(RPO = 0),也支持异步复制模式以满足异地容灾需求。
核心指标参考(实际以网络、拓扑和负载为准):
- 故障自动切换时间 (RTO):< 15 秒
- 演练切换时间 (RTO):< 30 秒
- 同步复制数据丢失量 (RPO):0
- 异步复制数据丢失量 (RPO):< 5 秒
- 写入延迟:同步复制会增加集群的写入延迟,延迟的估计值为“本地落盘时间 + 跨集群网络一次 RTT + 远端落盘时间”。异步复制不会增加写入延迟。
基本概念
阅读本文时,建议先区分以下两组概念:
primary/standby:表示集群当前的服务角色。primary:可读可写。standby:只读,不接受普通业务写入。
source/replica:表示一对物理复制集群之间的数据流向。source:上游,负责向下游提供日志和快照。replica:下游,负责接收并应用复制数据。
在最常见的一主一备场景中,primary 通常也是 source,standby 通常也是 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-interval | resolved-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_HOST 和 SOURCE_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停滞,请检查网络连通性及 TiKVreplicator日志。
修改和管理复制链路
除 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 转成新 primary 的 standby,并建立新的复制链路。
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_PERFORMANCE、MAXIMUM_PROTECTION、MAXIMUM_AVAILABILITY |
DEGRADE_TIMEOUT | 降级超时时长(秒),仅 PROTECTION_MODE = MAXIMUM_AVAILABILITY 时有值 |
STATE | 复制状态:INITIALIZING、ASYNC_REPLICATING、SYNC_REPLICATING、PAUSED、MAYBE_BLOCKING_SUSPENDED、NON_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 | 工作流类型,如 CREATE、DROP、PAUSE、RESUME 等 |
WORKFLOW_INFO | 工作流具体参数信息 |
START_TIME | 启动时间 |
END_TIME | 结束时间 |
WORKFLOW_STATE | 执行状态:PENDING、IN_PROGRESS、COMPLETED |
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
典型运维路径
- 检查配置:部署
primary/standby集群并验证 TiKV 配置。 - 建立链路:在
standby集群执行ADMIN CREATE LOG REPLICATION。 - 观察初始化:通过
INFORMATION_SCHEMA.LR_STATUS_GLOBAL确认INITIALIZING_PROGRESS达到 100%。 - 调整保护模式:初始化完成后,按需切换到
MAXIMUM_PROTECTION或MAXIMUM_AVAILABILITY。 - 日常管理:按需执行暂停、恢复、切换
source或修改保护模式。 - 故障处理:根据故障类型选择计划内切换或计划外激活。
- 接回旧主:旧
primary恢复后,按需执行REINSTATE将其接回链路。 - 清理链路:执行
ADMIN DROP LOG REPLICATION清理状态,并使用ADMIN ACTIVATE STANDBY MODE = FLASHBACK让集群退出standby状态。