备份完不算完,先还原到临时库验一遍

备份脚本挂了定时,监控面板天天绿着,备份目录里每天躺一个新文件,看着挺让人安心。可真要用它的那天------误删了一张表、或者机器坏了得换一台恢复------不少人才头一次发现:这备份还原不回来。文件是空的、少了几个对象、版本对不上,各种情况都有。

备份「跑成功了」和备份「真能用」,中间隔着一次几乎没人主动做的事:把它还原出来看看。这篇就干这一件事,把一个 custom 备份还原到临时库,再一项一项验过去------数据对不对、对象全不全、约束还在不在、业务查询跑不跑得通。第 1 篇讲过的 sys_dumpsys_restore 参数这里不重复,重点是一套验证的思路。

照例说一句账号:这篇要建库、删库,是 DBA 的活,所以用 system 连。日常开发查查改改,普通用户就够,别一上来就抱着管理员账号。演示库叫 backup_src_db,三张表的结构是商品、客户、订单那一套,带主键、外键、唯一约束、check、索引和一个视图,数据里也有中文。

先给源库留一组基线

备份之前,先在源库查一组数据记下来。注意不是查「表在不在」,而是查几个业务上能说明问题的值:

scss 复制代码
ksql -h 127.0.0.1 -p 54321 -U system -d backup_src_db -c "
select
  count(*) as order_count,
  sum(total_amount) as amount_sum,
  max(created_at) as last_created_at
from t_bak_order;"
​
ksql -h 127.0.0.1 -p 54321 -U system -d backup_src_db -c "
select * from v_bak_customer_amount order by customer_id;"

订单表 5 行、金额合计 1235.10、最后一单是 2026-06-30 09:50:00;视图按客户汇总,张三 2 单 288.50、李四 2 单 880.00、王五 1 单 66.60。

为什么不直接 select count(*) 完事?因为行数对得上,不代表数据没错位。少灌了一行金额、某个字段乱了序,单看行数发现不了。金额合计、最后一条时间这种指标,掺进了具体的值,恢复后拿来对账才靠得住。这组数就是后面验证的「标准答案」。

备份,然后先别急着还原

备份成 custom 格式,文件放进一个带日期的目录:

bash 复制代码
BACKUP_DIR=/acowbo/kingbase/backups/verify_20260630
mkdir -p "$BACKUP_DIR"
​
sys_dump -h 127.0.0.1 -p 54321 -U system -d backup_src_db -F c -f "$BACKUP_DIR/backup_src_db.dump"
ls -lh "$BACKUP_DIR/backup_src_db.dump"
​
sys_restore -l "$BACKUP_DIR/backup_src_db.dump" | sed -n '1,80p'

文件 6.7K,躺在那儿了。但文件存在只是第一层------里面装的东西齐不齐,得用 sys_restore -l 看一眼归档目录再说。

输出头部写着这份归档的身份:dbname: backup_src_dbTOC Entries: 20Format: CUSTOM、从 12.1 的库导出。下面 Selected TOC Entries 一条条列着里面有什么:wmsys 这个 KES 自带的 schema、两张表 t_bak_customert_bak_order、序列、视图 v_bak_customer_amount、表数据、各种约束、那个 idx_bak_order_customer_created 索引、还有外键 t_bak_order_customer_id_fkey。该有的对象都在清单里。

这一步的意义在于,还没动手恢复,就能先确认备份不是个空壳------20 个 TOC 条目、表数据和约束都列着,至少归档本身是完整的。custom 格式能这么列目录,纯文本备份就得自己 grep 了。

还原到临时库,别碰源库

关键一点:还原到一个新建的临时库,不要往源库上还原。临时库名字起得显眼点,一看就知道是干嘛的:

perl 复制代码
ksql -h 127.0.0.1 -p 54321 -U system -d app_db -c "drop database if exists backup_verify_db;"
ksql -h 127.0.0.1 -p 54321 -U system -d app_db -c "create database backup_verify_db;"
​
sys_restore -h 127.0.0.1 -p 54321 -U system -d backup_verify_db -v "$BACKUP_DIR/backup_src_db.dump"

-vsys_restore 把每一步都打出来:连接、建 wmsys schema、建两张表、建序列、建视图、灌数据------这里能看到 finish restoring contents of table "public.t_bak_customer" 3 rowst_bak_order 5 rows,行数和源库对得上;再往下建主键、唯一约束、索引,最后建外键 t_bak_order_customer_id_fkey。整个恢复过程一步不落地走完了。

不过 -v 跑完没报错,只能说「还原命令成功了」,不等于「数据和源库一致」。命令成功是必要条件,不是充分条件,下面还得自己查。

数据对不对,两边拉出来比

源库和临时库各跑一遍同样的汇总,把库名也查出来,并排放着看:

scss 复制代码
ksql -h 127.0.0.1 -p 54321 -U system -d backup_src_db -c "
select 'backup_src_db' as db_name,
  count(*) as order_count, sum(total_amount) as amount_sum, max(created_at) as last_created_at
from t_bak_order;"
​
ksql -h 127.0.0.1 -p 54321 -U system -d backup_verify_db -c "
select 'backup_verify_db' as db_name,
  count(*) as order_count, sum(total_amount) as amount_sum, max(created_at) as last_created_at
from t_bak_order;"

两边都是 5 / 1235.10 / 2026-06-30 09:50:00,跟备份前那组基线一字不差。到这儿,数据这一关算过了------不是因为命令没报错,是因为这几个业务指标真对上了。

对象、约束、索引,一个都不能少

数据对上了,还得看结构。备份恢复从来不只是几行数据的事,约束、索引、视图都是恢复结果的一部分。先看表和视图:

perl 复制代码
ksql -h 127.0.0.1 -p 54321 -U system -d backup_verify_db -c "\dt"
ksql -h 127.0.0.1 -p 54321 -U system -d backup_verify_db -c "\dv"

\dt 两张表 t_bak_customert_bak_order 都在。\dv 列出来三个视图,别被多出来的两个吓到------sys_stat_statementssys_stat_statements_all 是 KES 自带的统计视图,跟这个库的备份没关系,你要找的是 v_bak_customer_amount,它在。

再把订单表的约束和索引拉出来看定义:

ini 复制代码
ksql -h 127.0.0.1 -p 54321 -U system -d backup_verify_db -c "
select c.conname, c.contype, _get_constraintdef(c.oid) as constraint_def
from _constraint c
where c.conrelid = 'public.t_bak_order'::regclass
order by c.conname;"

ksql -h 127.0.0.1 -p 54321 -U system -d backup_verify_db -c "
select indexname, indexdef from _indexes
where schemaname = 'public' and tablename = 't_bak_order'
order by indexname;"

订单表上五个约束全回来了:外键 customer_id 指向客户表、order_no 的唯一约束、order_status 限定 paid/pending/refund 的 check、total_amount > 0 的 check、还有主键。索引也在,包括那个 (customer_id, created_at desc) 的联合索引。

这一步要是省了,很容易掉坑:假如恢复只回来了数据、没回来约束,库当时看着一切正常,等后面业务往里写脏数据,外键和 check 不拦了,问题就埋下了。所以约束在不在,得专门确认,不能默认它跟着数据一起回来了。

跑业务查询,再故意撞一次约束

光「能查」还不够,得让数据真正参与一次业务逻辑。先跑视图:

css 复制代码
ksql -h 127.0.0.1 -p 54321 -U system -d backup_verify_db -c "
select * from v_bak_customer_amount order by customer_id;"

视图算出来张三 288.50、李四 880.00、王五 66.60,和源库基线完全一致------说明视图定义、底层的 join 和聚合都正常工作。

然后故意撞一下约束,插一条客户根本不存在的订单:

less 复制代码
ksql -h 127.0.0.1 -p 54321 -U system -d backup_verify_db -c "
insert into t_bak_order(order_no, customer_id, total_amount, order_status, created_at)
values ('BKO-BAD-001', 999, 10.00, 'paid', timestamp '2026-06-30 10:00:00');"

外键直接把它顶回来了:

sql 复制代码
ERROR:  insert or update on table "t_bak_order" violates foreign key constraint "t_bak_order_customer_id_fkey"
DETAIL:  Key (customer_id)=(999) is not present in table "t_bak_customer".

这一下才算把约束验透。前面 constraint 里查到约束定义存在,那只是「定义在」;这里真插一条非法数据被拦下来,证明的是约束「在干活」。两者不是一回事------定义还在、但因为某种原因没生效的情况,是真会发生的。

备份文件本身也得能追溯

最后补一组文件层面的信息,记下来:

bash 复制代码
ls -lh "$BACKUP_DIR/backup_src_db.dump"
sha256sum "$BACKUP_DIR/backup_src_db.dump"

文件大小能一眼看出异常------突然冒出来一个 0 字节或者小得离谱的备份,多半是哪步出错了。sha256 这串哈希的用处要说准确:它能在备份传到异地、归档一段时间之后,核对文件有没有被改动或损坏。但它只管「文件这串字节还是不是原来那串」,证明不了「这个库能恢复」------能不能恢复,是前面还原到临时库、把数据和对象逐项验过来确认的。哈希和恢复验证是两件事,别拿哈希对得上当作备份可用。

这套流程到底验出了什么

回头看一遍:备份前留了基线,备份后先用 sys_restore -l 确认归档不是空壳,还原到临时库、不碰源库,数据按业务指标对账,表/视图/约束/索引逐项查过,又拿一条非法写入确认约束真在拦,最后给文件留了大小和哈希。一个备份能走完这一套,才敢说它「能用」,而不只是「跑成功了」。

也得把话说清楚:这验的是「备份文件可用性」,不是一次生产恢复。真到线上恢复,还要考虑停机窗口、连接和权限切换、应用怎么切过去、要恢复到哪个时间点------那是另一篇的事。但反过来说,连还原到临时库这关都没过的备份,上面那些就更无从谈起。备份这东西,定时跑起来只是开了个头,定期捞出来验一遍,它才真正成了你的后路。

相关推荐
Csvn2 小时前
📊 SQL 入门 Day 22:视图与物化视图
后端·sql
Csvn2 小时前
🐍 Day 4: Python 控制流 — 条件、循环与推导式的艺术
后端·python
2601_953720822 小时前
【计算机毕业设计】基于Vue与Spring Boot的高校兼职信息服务平台设计与实现
spring boot·后端·课程设计
再吃一根胡萝卜4 小时前
用 Rust 写一个桌面悬浮图标:为什么它比 Python 更适合 AI 桌面工具?
后端
IT_陈寒4 小时前
Vue的computed属性把我坑惨了,原来我一直用错姿势
前端·人工智能·后端
evans在进步5 小时前
Spring Boot 核心机制详解:可执行 JAR、CORS、静态资源与配置绑定
spring boot·后端·jar
Sayuanni%35 小时前
SpringBoot 从注解到源码:核心知识点总结
java·spring boot·后端
陈随易6 小时前
Bun v1.4 更新总结:把浏览器、图片、定时任务和工程工具都装进一个运行时
前端·后端·程序员
人间凡尔赛7 小时前
2026 后端架构三驾马车:Wasm 容器上 K8s、存算分离与 AI 原生
后端·云原生·架构