一、评估数据库,不能只看"跑得对"
第一篇验证了 JSON 与函数的语法兼容,第二篇搞清了驱动与协议的边界、窗口函数和动态 SQL 的成色。但任何 DBA 都知道,选型评估真正的分水岭在另一条线上------坏得起吗?
手滑删了表,能不能精确救回来?主库突然宕机,业务能不能几秒内切到备库?这篇就在同一台鲲鹏服务器(Ubuntu 22.04 + KingbaseES V009R003C018)上把这两件事做穿:sys_rman 全量/增量备份 → 现场删表 → PITR 按时间点恢复 → 流复制备库 → 故障切换。全程 9 张实拍截图,中途踩到的 5 个坑一个不藏------说实话,这些坑比一路全绿值钱得多。
二、侦察装备:sys_rman 是 pgBackRest 的企业级血统
先看随安装包给了什么:

sys_basebackup、sys_dump/sys_dumpall、sys_restore、sys_waldump、sys_rman 一应俱全。重点是 sys_rman help 打出的命令集------stanza-create、archive-push、backup、restore、info、expire......用过 pgBackRest 的人会当场认出这个血统(版本号 2.27 也对得上)。这是个好消息:pgBackRest 是 PG 生态里生产验证最充分的备份工具之一,支持压缩、增量、并行、PITR,比裸 basebackup 的备份体系高一个档次。
三、搭归档链路:第一个坑就在出厂配置
pgBackRest 系的备份依赖 WAL 归档。看出厂状态:
SQL
SHOW archive_mode; -- always
SHOW archive_command; -- exit 0(占位命令,WAL 直接"假装归档成功"后丢弃)
坑 1:出厂 archive_mode=always ,而 sys_rman 只认 on。 我最初以为 always 已经开了归档、改个 command 就能用,结果 stanza-create 直接报 ERROR [067]: archive_mode=always not supported------自家工具不支持自家出厂默认值。而 archive_mode 是重启级参数,所以"零重启接入备份"是做不到的,老老实实改配置重启:
SQL
ALTER SYSTEM SET archive_mode = 'on';
ALTER SYSTEM SET archive_command =
'/opt/Kingbase/ES/V9/Server/bin/sys_rman --stanza=main
--repo1-path=/home/kingbase/kbbak
--kb1-path=/opt/Kingbase/ES/V9/data
--log-path=/home/kingbase/kbbak archive-push %p';
坑 2:archive_command 里必须带 --kb1-path。 KES 的归档进程传给 %p 的是相对路径(sys_wal/000...),不带这个参数时 archive-push 报 relative wal paths are used,WAL 的 .ready 文件默默堆积、备份卡到超时。坑 3:参数名文档与实现不同步。 sys_rman help 里写的是 --kb-path/--repo-path,实际运行要求带索引的 --kb1-path/--repo1-path(报错 option 'kb-path' must have an index),照着帮助文档敲命令是跑不通的。
排完这三个坑,链路就顺了:

check 通过意味着归档往返(push 进仓库、get 得回来)被真实验证过------这是备份可信的前提。
四、全量 + 增量:84MB 的库备成 11.6MB,7 秒
Bash
sys_rman ... backup --type=full

84MB 的数据目录(2371 个文件)压缩落库 11.6MB ,耗时 7.3 秒。接着模拟业务继续写入(新增 2 名会员,表里 4 → 6 人),再做增量:

增量备份只花 1.4 秒 ,仓库里只多了 1.8MB ------info 里能看到 incr 挂在 full 的引用链上。对每天几百 GB 变更量的生产库,这个"全量打底 + 增量滚动"的结构就是备份窗口的生命线。
五、灾难现场与时间穿越:一次失败教会我的 PITR 精度课
好戏开场。先记住"这一刻",然后手滑:

SQL
SELECT current_timestamp(6); -- 2026-07-13 20:57:45.371602,存档
DROP TABLE member; -- 灾难
SELECT count(*) FROM member; -- ERROR: relation "member" does not exist
然后停库、PITR 恢复到手滑前一刻、重启:
Bash
sys_ctl stop
sys_rman ... restore --delta --type=time \
--target="2026-07-13 20:57:45.371602" --target-action=promote
sys_ctl start # 回放 WAL 到目标时间点,自动提升上线

--delta 模式只比对差异文件,restore 本体 453 毫秒 ;启动后回放 WAL 精确停在目标时刻,验证查询:6 | 张伟,李娜,王强,赵敏,孙丽,周杰****------表连同 6 名会员完整穿越回来,删表操作如同没发生过。
但必须坦白:我第一次恢复失败了,表没回来。 排查数据库日志才看懂:
Plain
starting point-in-time recovery to 2026-07-13 20:48:45+08
last completed transaction was at log time 2026-07-13 20:48:44.988160+08
那个 44.988 的"最后完成事务"就是 DROP TABLE 本身 。坑 4:MySQL 兼容模式下 now() 只有秒级精度且会四舍五入 ------我第一次用 now() 记录时刻,实际约 44.5 秒被记成了 45 秒,恢复目标落在了删表动作(44.988 秒)之后 12 毫秒,于是 WAL 回放把 DROP 也一起放了进来。换成微秒精度的 current_timestamp(6) 后一次成功(有趣的是 now(6) 依然只输出秒级,两个函数行为不一致)。PITR 场景下,恢复目标的时间精度必须高于事故操作的时间间隔,这一课在测试环境交学费,远好过在生产。
顺带一个小发现:--type=immediate(恢复到备份一致点)在这个版本会报 ASSERT: option 'target' is null,被强制要求带 --target------与上游 pgBackRest 行为不一致,用 --type=time 绕过即可。
六、主备搭建:license 边界与"克隆传染"
坑 5(本篇最重要的评估情报):开发版授权不含主备复制组件。 备库第一次启动直接 FATAL:
Plain
FATAL: DataWatch is not supported by current license file,
but primary_conninfo is set to not NULL
WARNING: max_connections should be less than or equal than 10 (restricted by license)
开发版 license(365 天那个)不支持 DataWatch(金仓的流复制/高可用组件),还限制最多 10 个连接。做 HA 评估请直接从官网下载"标准版/专业版/企业版-180 天"授权------我换上企业版授权后一切正常。这条信息在下载页上没有醒目提示,希望能帮后来者省半天排查。
第二个障碍是"克隆传染":sys_basebackup -R 会把主库的 kingbase.auto.conf 原样带到备库,里面躺着主库的 archive_command(--kb1-path 指向主库目录,校验必炸)和之前 PITR 留下的 recovery_target_* 参数(备库会去找一条不存在的时间线,FATAL: recovery target timeline 3 does not exist)。解法是启动备库前追加覆盖这些继承参数:
Bash
sys_basebackup -p 54321 -U system -D /opt/Kingbase/ES/V9/standby -R -X stream
cat >> /opt/Kingbase/ES/V9/standby/kingbase.auto.conf <<EOF
port = 54322
archive_mode = off
restore_command = ''
recovery_target_time = ''
recovery_target_timeline = 'latest'
EOF
(细节:recovery_target_action 是枚举参数,置空串会直接拒绝启动,跳过它即可。)

54321 主(is_standby = f)、54322 备(t),单机双实例主备就位------生产上把备库放到第二台机器,步骤完全相同。
七、复制验证与故障切换:0.7 毫秒延迟,一条命令接管
三连验证:主库写入 → 备库即查即得;备库写入 → 被只读保护拒绝;主库视角看复制状态:

Plain
主库 INSERT 陈晨 → 备库立刻查到 143 | 陈晨 | 8800
备库 INSERT → ERROR: cannot execute INSERT in a read-only transaction
sys_stat_replication → streaming | async | replay_lag 00:00:00.000731
回放延迟 0.7 毫秒 (同机零网络开销的理想值,跨机房会到毫秒~十毫秒级,但机制完全一致)。然后是最硬核的一幕------把主库 -m immediate 硬停(模拟掉电级故障),一条命令提升备库:

Plain
sys_ctl -D .../standby promote
→ waiting for server to promote.... done / server promoted
→ is_standby: f
→ UPDATE member SET points = points + 100 ... RETURNING → 陈晨 | 8900
从主库死亡到新主接受写入,全程秒级。当然这是手动 promote;生产环境应部署金仓的集群管理组件做自动故障检测与切换(配合 VIP 或应用端多主机连接串),但底层机制正是这一套。
八、本篇结论:能力矩阵与踩坑清单
能力矩阵(均为实测):
| 能力 | 实测结果 |
|---|---|
| 全量备份 | ✅ 84MB→11.6MB 压缩,7.3s |
| 增量备份 | ✅ 552KB、1.4s,链式引用 |
| 归档链路体检(check) | ✅ push/get 往返验证 |
| PITR 按时间点恢复 | ✅ 微秒级 target,精确停在删表前,数据零丢失 |
| 流复制备库 | ✅ replay_lag 0.7ms(同机) |
| 备库只读保护 | ✅ 写入被拒 |
| 手动故障切换 | ✅ promote 秒级完成,新主立即可写 |
踩坑清单(现象 → 根因 → 解法):
| # | 坑 | 解法 |
|---|---|---|
| 1 | archive_mode=always not supported------出厂值自家工具不认 |
改 on 并重启 |
| 2 | archive-push 报相对路径错误,WAL 堆积 | archive_command 里加 --kb1-path |
| 3 | 帮助文档写 --kb-path,实际要 --kb1-path |
按带索引形式传参 |
| 4 | PITR 目标用 now() 记录,恢复把 DROP 一起回放 |
MySQL 模式 now() 秒级四舍五入,用 current_timestamp(6) |
| 5 | 备库 FATAL:license 不含 DataWatch / 连接数限 10 | 开发版授权不支持 HA,换官网企业版 180 天授权 |
| 5.1 | 备库继承主库 auto.conf 导致启动失败 | 启动前覆盖 restore_command/recovery_target_*/archive_mode |
九、给金仓的建议(本篇干货浓度最高的部分)
-
出厂
archive_mode=always与 sys_rman 不兼容,等于默认配置和自家备份工具打架------要么让 sys_rman 支持 always,要么出厂改 on,要么在文档里加显著警示。 -
sys_rman help** 的参数名与实现对齐**(--kb-pathvs--kb1-path),照文档敲命令跑不通对新用户是硬伤。 -
下载页为各版本授权标注能力边界:开发版不含 DataWatch、限 10 连接,这两条信息值得放在授权文件下载按钮旁边,而不是让用户从备库的 FATAL 日志里发现。
-
MySQL 兼容模式
now()的秒级精度 在 PITR/审计场景是隐蔽风险,建议文档警示,或让now(6)真正输出微秒(当前now(6)与current_timestamp(6)行为不一致)。 -
sys_basebackup -R可考虑自动清理/注释掉克隆自主库的 recovery 与归档参数,或在启动报错时给出指向性提示。 -
restore --type=immediate不应强制要求--target(与上游 pgBackRest 语义不一致)。
十、系列总结
三篇走完,"从兼容到进阶"的完整评估路径闭环:
-
第一篇(语法层) :JSON 与函数 12 项测 9 项全绿,
INSERT()/FORMAT()两个函数级差异,均有一行级替代方案; -
第二篇(协议层) :兼容在语法不在协议,迁移 = 换驱动 jar + 改 URL + 占位符
?→$N;窗口函数全绿; -
第三篇(运维层):备份/PITR/主备/切换能力完整且工程化(pgBackRest 血统),但默认配置、文档精度、授权说明这些"外围体验"还有明显打磨空间。