只恢复一张表,别把整个库都还回去

0 阅读6分钟

配置表被人改乱了、一张临时表被误清了、想单独捞一张表的数据去比对——这类事只牵扯一张表,为它把整个库还原一遍就太重了。custom 备份支持从整库归档里挑对象出来恢复,sys_restore-t 就是干这个的。

这篇把单表恢复的流程跑一遍,但重点不在「怎么恢复成功」,而在恢复出来的东西到底完不完整。提前说结论:单表恢复能把表和数据捞回来,可它没你想的那么听话,恢复完最好回头查一眼。照例用 system 连,建库删库要它。

先确认 sys_restore 认 -t

参数先看帮助:

sys_restore --help | grep -E "table|-t|--table"

确认 sys_restore 支持按表恢复

要找的是这行:

-t, --table=NAME          restore named relation (table, view, etc.)

-t 从归档里挑出指定的关系来恢复。留意它的措辞是 named relation——挑的是「这个名字的表/视图」这个对象本身。帮助最后还写了一句 -t 可以和 -n 等选项组合。这个「只挑对象本身」的说法,后面会成为关键。

现场:一个库里三张表

源库 app_schema 下放三张表:t_customert_order 是对照,t_config 是这次要单独恢复的目标。选 t_config 是因为它没有外键,看着最「干净」——先记住这个「干净」,后面会发现它也没那么干净。

select 't_customer' as table_name, count(*) from app_schema.t_customer
union all
select 't_order' as table_name, count(*) from app_schema.t_order
union all
select 't_config' as table_name, count(*) from app_schema.t_config;

源库准备三张表

t_customer 2 行、t_order 2 行、t_config 3 行,三张表都有数据。

整库备份,恢复时再挑对象

单表恢复的备份,通常就是一份普通的整库 custom 备份——备的时候全备下来,恢复的时候再从里面挑:

sys_dump -h 127.0.0.1 -p 54321 -U system \
  -F c \
  -f /acowbo/kingbase/backups/table_20260630/table_src_db.dump \
  table_src_db

ls -lh /acowbo/kingbase/backups/table_20260630

生成包含多张表的 custom 备份

一个 4.6K 的整库备份,三张表都在里头。custom 格式的价值就在这——一份归档,恢复时按需取用。

先看清单,确认目标表在里面

恢复前先把归档目录列出来,确认要的表在、顺带看看它带了些什么:

sys_restore -l /acowbo/kingbase/backups/table_20260630/table_src_db.dump \
  > /acowbo/kingbase/backups/table_20260630/table_src_db.list

grep "t_config" /acowbo/kingbase/backups/table_20260630/table_src_db.list
grep -E "t_customer|t_order|t_config" /acowbo/kingbase/backups/table_20260630/table_src_db.list

归档清单里确认目标表

单独 grep t_config,抓出来三条:

702; 1259 17069 TABLE app_schema t_config system
6463; 0 17069 TABLE DATA app_schema t_config system
5923; 2606 17073 CONSTRAINT app_schema t_config t_config_pkey system

这里就有个信息值得记住:t_config 在归档里不是一个整体,而是拆成了三条独立的条目——TABLE(表定义)、TABLE DATA(表数据)、CONSTRAINT(主键 t_config_pkey)。它的主键是一条单独的记录,跟表和数据是分开列的。这个细节等会儿要用到。第二条 grep 把三张表都列出来,确认整库备份里对象齐全。

只恢复 t_config 到临时库

建临时库,先把 app_schema 建出来(不然恢复表定义时找不到 schema),再用 -t 只恢复这一张表:

ksql -h 127.0.0.1 -p 54321 -U system -d table_restore_db -c "create schema app_schema;"

sys_restore -h 127.0.0.1 -p 54321 -U system \
  -d table_restore_db \
  -t t_config \
  -v \
  /acowbo/kingbase/backups/table_20260630/table_src_db.dump

只恢复 t_config 到临时库

-v 把过程打出来,就三步:

creating TABLE "app_schema.t_config"
processing data for table "app_schema.t_config"
finish restoring contents of table "app_schema.t_config" 3 rows

建表、灌数据、3 行完成。命令用的是 -t t_config(不带 schema)就成功了。但盯着这三行看——建了表、进了数据,然后就结束了,没有一句 creating CONSTRAINT。对比刚才归档清单里那条单独的主键记录,这里没动它。先按下不表,去验证一下。

验证:范围对了,但……

到临时库查一遍。先看只恢复了哪张表:

select table_schema, table_name from information_schema.tables
where table_schema = 'app_schema' order by table_name;

select config_key, config_value, remark from app_schema.t_config order by config_key;

select count(*) as other_table_count from information_schema.tables
where table_schema = 'app_schema' and table_name in ('t_customer', 't_order');

临时库验证只恢复一张表

范围这块没问题:app_schema 里只有 t_config 一张表,三行配置数据原样在(中文备注也正常),对照的 t_customert_order 数量是 0,没被带进来。要是这篇到这儿就收尾,看着挺圆满——一张表干净利落地捞回来了。

但前面留了个疑点:主键呢?

捞回来的是张「没主键」的表

单独查一下 t_config 恢复后的约束:

select constraint_name, constraint_type, table_schema, table_name
from information_schema.table_constraints
where table_schema = 'app_schema' and table_name = 't_config'
order by constraint_name;

目标表约束检查

结果只有两条,都是 CHECK,名字是 17075_17076_1_not_null 这种系统自动生成的——它们是 config_keyconfig_value 两个 NOT NULL 列约束。主键 t_config_pkey 不见了。

回过头串一下就明白了。归档清单里,t_config 的表、数据、主键是三条独立条目;-t t_config 挑的是「名叫 t_config 的那个表」,正好命中 TABLETABLE DATA 两条,而主键 t_config_pkey 是一条单独的 CONSTRAINT 记录,-t 没把它算进来。所以第 5 步 -v 里才只有建表和灌数据、没有建约束。至于那两个 NOT NULL 为什么在——因为 NOT NULL 是写在 CREATE TABLE 语句里的,跟着表定义一起就进来了;而 PRIMARY KEY 是一条独立的 ALTER TABLE ADD CONSTRAINT,得单独恢复。

这就是单表恢复真正的坑:命令跑成功了、数据也对,但恢复出来的可能是张有数据、没主键的裸表。主键没了意味着唯一性不再保证、关联查询和很多依赖主键的操作性能垮掉,而这一切不报错——你要是不专门查一眼约束,根本发现不了。拿这种表直接顶回生产,是在埋雷。

什么时候能用 -t,什么时候不能只靠它

-t 适合的是「只想把某张表的数据捞出来」的场景:拉到临时库比对一下被改前的值、恢复一张纯数据的日志表、给验证环境喂一张表的样本。这些情况要的就是数据,表结构完不完整不那么要紧,-t 又快又省事。

但只要你的目标是把一张表完整恢复回去——带着它的主键、唯一约束、外键、索引——-t 表名 默认这一下是不够的,它只管表和数据。真要完整恢复,得换个做法:要么整库(或整 schema)恢复到临时库、再把这张表连同约束一起迁过去,要么恢复完手动把主键、索引这些补齐。

说到底还是第 2 篇那句话:恢复完别急着信,先在临时库查清楚捞回来的到底是不是你要的那张表。尤其是业务表,光看「有几行数据」远远不够,约束、索引这些也得一并盘一遍,确认没缺,再往原库上动。

下一篇换个维度,不再挑对象,而是分开备:只备结构、或只备数据,先想清楚要的是个空壳还是一包内容。