
KingbaseES V9 物理备份实战用 sys_rman 做增量备份与 PITR 时间点恢复说个真事。去年有位同事在生产库上跑了个DROP TABLE订单表五百多万行。当时是周五下午快下班整个人都懵了。最后靠物理备份加 WAL 归档把数据全救回来了——从删表到恢复大概四十分钟。从那以后我对备份这事儿就有点强迫症了。金仓的物理备份工具叫sys_rman跟 pgBackRest 一个路子。原理不难懂先拷一份数据文件当底子然后持续把 WAL 日志归档存着。出事了就把底子铺回去日志一段段重放想恢复到哪秒都行。这个能力叫 PITRPoint-In-Time Recovery。sys_dump做不到这个它只能恢复到你上次导出的那一刻中间的数据全没了。还有俩词儿混个脸熟就行RPO 就是能容忍丢多少数据sys_dump的 RPO 就是上次导出到出事这段时间可能差好几个小时甚至一天RTO 是多久能把库拉起来。物理备份加归档能把 RPO 压到秒级所以生产基本都会配这套不是可选项是底线。下面在一台单机 V9R1C10 上走一遍完整流程。环境很简单数据目录/opt/kingbase/data备份仓库放/opt/kingbase/backup。仓库和数据目录别放同一块盘啊盘坏了备份跟着一起没等于白做。先把归档打开PITR 的前提是 WAL 归档开着。改kingbase.confwal_level replica archive_mode on archive_command sys_rman archive-push --config/opt/kingbase/backup/sys_rman.conf --stanzakingbase %f %p max_wal_senders 10逐行说下干嘛的。wal_levelreplica是流复制和归档的最低门槛再低就不行了。archive_command就是 WAL 段写满之后默认 16MB 一个执行这条命令把它推到仓库%f是文件名%p是路径。max_wal_senders10留够连接数给复制和归档用一般够。改完sys_ctl reload就生效了不用重启。这里有个坑我踩过。archive_modeon之后如果归档命令一直失败比如仓库路径权限不对WAL 会堆在pg_wal里直到磁盘撑爆。别问我怎么知道的——第一次配的时候就是仓库目录属主搞错了第二天早上运维打电话说磁盘 95% 了才发现。所以开之前务必确认仓库路径可写这个真不是废话。另外sys_hba.conf要放行备份用的超级用户host all system 127.0.0.1/32 md5 host replication system 127.0.0.1/32 md5第一条让sys_rman能连库调内部函数第二条给流复制拉 WAL 用。改完 reload。初始化备份环境sys_rman自己有一份运行时配置sys_rman.conf描述仓库在哪、实例是谁。金仓推荐用脚本自动生成手改容易漏字段出问题。你需要先准备一份初始化配置sys_backup.conftarget-db127.0.0.1 target-port54321 target-usersystem target-pass你的密码 repo-path/opt/kingbase/backup repo-arch-path/opt/kingbase/backup/archive oper-userkingbase这份跟kingbase.conf不是一回事啊——前者是告诉sys_rman工具去哪连库、备份往哪存后者是数据库自己的运行参数。两套东西各管各的别搞混了。然后执行初始化cd/opt/kingbase/install/Server/bin ./sys_backup.sh init ./sys_backup.sh startinit这一步做的事情挺多的校验仓库能不能写、创建 stanza给实例贴个标签用的、做一次全量基线备份、跑一轮归档自测。任何一步不过直接报错不会让你带着隐患往下走。start是把定时任务挂进系统 crontab。其实init内部等价于这两条命令知道的话排错方便# 创建 stanza实例标签备份前必须有./sys_rman--config/opt/kingbase/backup/sys_rman.conf--stanzakingbase stanza-create# 自检仓库、归档、链路通不通./sys_rman--config/opt/kingbase/backup/sys_rman.conf--stanzakingbase checkcheck通过会打印一堆ok看着挺爽的。这一步能提前暴露仓库不可写、归档命令不通之类的问题比真到了要恢复的时候才发现强太多了。还有一句——仓库目录里面存着备份集状态和 WAL 归属这些元数据千万别手动去删改里面的文件否则恢复能力直接废掉。别手贱。日常备份怎么跑初始化完了之后日常备份就两条命令的事。全量./sys_rman--config/opt/kingbase/backup/sys_rman.conf--stanzakingbase backup增量只存变过的数据块./sys_rman--config/opt/kingbase/backup/sys_rman.conf--stanzakingbase--typeincr backup也支持--typediff差异备份基于最近一次全量。很多人搞不清增量和差异的区别。简单说吧差异备份始终拿最近一次全量做参照所以越往后备份越大增量是基于上一次任意备份不管全量还是增量只存变化块最省空间但恢复的时候得沿着备份链一路往前拼缺了中间任何一环都不行。我这边 412 MB 的数据目录全量大概 180 MB每天增量只有几 MB。线上常见做法是周末做一次全量、工作日做差异、日间再做增量在空间和恢复速度之间取平衡。看备份集状态./sys_rman--config/opt/kingbase/backup/sys_rman.conf--stanzakingbase info输出长这样stanza: kingbase status: ok db (current) wal archive min/max : 000000010000000000000003 / 00000001000000000000000A full backup: 20260804-093000F timestamp start/stop: 2026-08-04 09:30:00 / 09:31:12 lsn start/stop : 0/3000028 / 0/3000138 database size : 412MB, backup size: 180MB incr backup: 20260804-093000F_20260805-020000I timestamp start/stop: 2026-08-05 02:00:00 / 02:00:18 backup size : 4.2MB重点看wal archive min/max这行——它告诉你归档里 WAL 覆盖的时间范围。要做 PITR 恢复到某个时间点那个时间点对应的 WAL 必须在这个区间内否则恢复不了。平时顺手确认一下归档是不是真的在流动ls-lh/opt/kingbase/backup/archive/kingbase/看到文件时间戳在更新就说明通了。也可以在库里查SELECTarchived_count,last_archived_walFROMsys_stat_archiver;last_archived_wal在往前走就没问题。建议把这个检查接到监控里别靠人肉去看。来一次真实的 PITR 恢复假设下午 15:30 有人误执行了DROP TABLE perf_demo.orders;但 15:00 还有一批业务数据刚写入。目标恢复到 15:25——删表之前、且包含那批新数据。先停库、挪走旧数据目录先确认备份和归档都在./sys_ctl stop-D/opt/kingbase/datamv/opt/kingbase/data /opt/kingbase/data_bak_20260804注意是mv不是rm啊旧的留着万一恢复出来不对还能推倒重来。这一步没得商量——别偷懒直接 rm出了事哭都没地方哭。然后 restore 把基础备份铺回去./sys_rman--config/opt/kingbase/backup/sys_rman.conf--stanzakingbase restore这步会重建data目录并自动写入restore_command。目标时间需要补进kingbase.auto.confrestore_command sys_rman archive-get --config/opt/kingbase/backup/sys_rman.conf --stanzakingbase %f %p recovery_target_time 2026-08-04 15:25:00 recovery_target_action pauserecovery_target_actionpause就是重放到 15:25 后暂停库处于只读恢复态给你机会上去验数据。除了pause还有promote直接打开结束恢复和shutdown到了就关库。我个人习惯用pause毕竟恢复完不验一下就开出去万一不对更麻烦。嫌手动改配置麻烦的话一步到位也行./sys_rman--config/opt/kingbase/backup/sys_rman.conf\--stanzakingbase --target-time2026-08-04 15:25:00restore工具会自动把时间写进去。接着启动库进入恢复模式./sys_ctl start-D/opt/kingbase/data启动后看日志能看到它在不断回放 WAL到达 15:25 后暂停。这时候连上去验证\c testSELECTcount(*)FROMperf_demo.orders;-- 应该返回 5000000表还在数据完整。没问题的话结束恢复SELECTsys_wal_replay_resume();执行完库脱离恢复模式正常读写。整个过程没动过原来的data_bak_20260804随时可以重来。恢复成功后数据目录会多出一个.history文件比如00000002.historyls/opt/kingbase/data/*.history这说明本次恢复产生了一条新时间线timeline。每次 PITR 恢复都会进新时间线避免恢复出来的日志和原来的日志打架。以后想换个时间点恢复直接重跑restore --target-time...就行时间线继续递增。几件日常要注意的事备份策略这块我们线上是每天一次全量cron 默认就会跑业务高峰期中间再加几次增量。这样恢复的时候选最近的全量 中间的增量 归档 WAL 重放比纯靠全量恢复快得多。备份越来越多仓库迟早被撑爆。设个保留策略让它自动清理repo1-retention-full7 repo1-retention-full-typecount repo1-path/opt/kingbase/backup意思是保留最近 7 份全量超出的连同依赖的增量一起回收。注意只要某份全量还在保留期内它依赖的 WAL 归档就不会被删PITR 能力不受影响。监控方面盯两件事就够了归档延迟仓库里的 WAL 跟不上主库产生的速度以及最后一次成功备份的时间。这两个任何一个异常容灾就有缺口。接到告警群里吧人肉巡检不靠谱半夜三更谁盯着看啊。最后这条最重要——备份不做恢复验证等于没备份。每个月拿最近的备份在隔离环境里 restore 一次确认能起来、数据对得上。真出事了你才知道流程哪里会卡住。我们现在是写进了每月运维清单里强制执行的不跑完不算完。踩坑记录说几个我踩过的坑。有一次归档命令一直失败pg_wal堆了几十个 G磁盘直接报警。原因是开archive_mode前没确认仓库路径可写修了权限就好了。这种问题排查起来其实不难就是出事的时候慌。还有一次info报 WAL 缺失恢复直接报错退出。查了半天发现有人觉得归档占空间手动删了一段。补回来才恢复成功。所以归档目录千万不能手动删哪怕看着没用。恢复完库只读那次也挺有意思。业务那边反馈连不上数据库以为恢复了其实没完——忘了跑sys_wal_replay_resume()pause 模式下库确实只读。这事儿后来变成了我们组里的段子。最坑的是手动改了sys_rman.conf备份行为变得很奇怪查了半天发现改错了一个路径。后来直接用 init 重新生成了一份再也不手改了。还有个低级错误——仓库和数据放同一块盘结果盘坏了备份也没了。后来迁到独立磁盘上。这种常识性的东西真出事的时候才会想起来。最后sys_rman这套东西上手不难真要靠得住就两件事归档链路不能断恢复流程要练熟。它和sys_dump不是替代关系——sys_dump适合跨版本迁移或者单表级恢复物理备份加归档才是整机崩溃和时间点回滚的正解。前面说的那位同事删表的事之后我们把恢复演练写进了每月运维清单。到现在还没再出过大事故希望你们也用不上这套恢复流程吧。但真要用的时候至少得确保它真能跑通——不然备份做了等于白做。