只备份一个 schema,别把整库都搬走
一个库里塞好几个 schema 是常事:业务表在一个 schema,审计日志在另一个,可能还有给报表、给别的团队用的独立 schema。真要搬东西的时候,往往只想动其中一块------把销售相关的表迁到新库、或者单独打包一份给某个团队,审计日志、别人的业务表都不该跟着走。
这时候整库 sys_dump 就有点大了:不光备了用不上的东西,还可能把不该外传的数据一并带出去。sys_dump 有个 -n,能把备份范围锁死在指定的 schema 上。这篇就用它,把一个 schema 单独备出来,并且一步步确认别的 schema 确实没被顺手捎上。建库删库还是 DBA 的活,用 system 连。
先确认这版 sys_dump 认不认 -n
参数别凭印象写,先翻一眼当前版本的帮助:
bash
sys_dump --help | grep -E "schema|-n|--schema"

这一行是要找的:
ini
-n, --schema=PATTERN dump the specified schema(s) only
-n 收一个 PATTERN,只导匹配到的 schema。顺带下面还有个 -N, --exclude-schema=PATTERN,是反过来的------排除某几个 schema、其余都要。这篇用 -n 做「只要这一个」,-N 留着知道有这么回事就行。确认参数在,后面的命令才有依据。
现场:一个库里两个 schema
要看出「只备一个」的效果,库里至少得有两个 schema,一个当主角、一个当参照。这里 sales_schema 放订单和订单明细两张表(还有它们之间的外键),是这次要备的业务;audit_schema 放一张审计日志表,它不是重点,唯一的作用是当对照物------最后用它来证明备份范围没有越界。
两个 schema 建好、灌完数据后,查一下现状:
sql
select table_schema, table_name
from information_schema.tables
where table_schema in ('sales_schema', 'audit_schema')
order by table_schema, table_name;
select 'sales_order' as item, count(*) from sales_schema.t_order
union all
select 'sales_item' as item, count(*) from sales_schema.t_order_item
union all
select 'audit_log' as item, count(*) from audit_schema.t_audit_log;

audit_schema.t_audit_log、sales_schema.t_order、sales_schema.t_order_item 三张表都在,行数分别是审计日志 2 行、订单 3 行、明细 3 行。两个 schema 都有真实内容------接下来只备 sales_schema,audit_schema 就该原地不动。
(顺一句:information_schema.tables 是标准写法,KES 里也可以用 sys_tables 查,两条查出来一样,看你顺手用哪个。)
备份时用 -n 锁定 sales_schema
关键就一条命令,-n sales_schema 把范围框住,格式还是上一篇的 custom:
bash
sys_dump -h 127.0.0.1 -p 54321 -U system \
-F c \
-n sales_schema \
-f /acowbo/kingbase/backups/schema_20260630/sales_schema.dump \
schema_src_db
ls -lh /acowbo/kingbase/backups/schema_20260630

备出来一个 3.9K 的 sales_schema.dump。命令里有两点容易看漏:-n sales_schema 是范围控制的核心,-n 后面跟的是 PATTERN,写精确名字就是只要这一个,也能用 -n 'sales*' 这种通配一次匹配多个;命令最末尾那个 schema_src_db 是源库名,别把它跟 -n 的值搞混。
别急着还原,先看归档清单里有什么
上一篇讲过,custom 备份能先用 sys_restore -l 把归档目录列出来,恢复前先验一遍范围对不对。这次就靠它来抓「有没有捎带别的 schema」:
bash
sys_restore -l /acowbo/kingbase/backups/schema_20260630/sales_schema.dump \
> /acowbo/kingbase/backups/schema_20260630/sales_schema.list
grep "sales_schema" /acowbo/kingbase/backups/schema_20260630/sales_schema.list
grep "audit_schema" /acowbo/kingbase/backups/schema_20260630/sales_schema.list

grep sales_schema 抓出来一串:schema 本身、两张表、两段表数据、两个主键约束、还有明细表指向订单表的外键------sales_schema 里该有的全在。而 grep audit_schema 这条,一行输出都没有。
这个「没输出」不是命令出错,正是这一步要的结果:归档里压根没有 audit_schema 的影子。恢复动作还没做,就已经能确定这份备份的范围没有超出 sales_schema。
还原到临时库
范围确认过了,还原到一个临时库看看,不去碰源库:
bash
sys_restore -h 127.0.0.1 -p 54321 -U system \
-d schema_restore_db \
-v \
/acowbo/kingbase/backups/schema_20260630/sales_schema.dump

-v 把过程打出来:建 sales_schema、建 t_order 和 t_order_item、灌数据各 3 行、建主键、建外键。从头到尾只跟 sales_schema 打交道,没有一句提到 audit_schema------归档里没有的东西,还原自然也变不出来。
验收:临时库里只有 sales_schema
最后到临时库里正面查一遍,把范围坐实:
csharp
select table_schema, table_name
from information_schema.tables
where table_schema in ('sales_schema', 'audit_schema')
order by table_schema, table_name;
select count(*) as order_count from sales_schema.t_order;
select count(*) as item_count from sales_schema.t_order_item;
select count(*) as audit_table_count
from information_schema.tables
where table_schema = 'audit_schema';

临时库里查两个 schema,只列出 sales_schema 的 t_order 和 t_order_item两张表;订单 3 行、明细 3 行,跟源库对得上。最后专门数一下 audit_schema 的表数量,是 0------一张都没进来。
到这儿,三道关是一致的:备份命令用 -n 框了范围,归档清单里 grep audit_schema 没输出,还原后的库里 audit_schema 表数为零。范围控制不是靠「命令跑成功了」这一句话,而是从备份包到恢复结果都对得上。
什么时候用,什么时候别硬套
-n 适合的场景很明确:库里分了多个 schema,这次只想动其中一块------迁一块业务到新库、单独给某个团队一份数据、或者只想验证某个 schema 的备份能不能用。范围小,备份快、文件小,也不会把不相干的数据裹出去。
但它只是「范围更小的一种备份」,不是所有场景的默认选择。整库有整库的用处,真要迁移一个完整的库,老老实实整库备更省心,没必要拆成一个个 schema。
还有一个坑得记在心里:-n 只管一个库内部的 schema,也只保证把这个 schema 的对象打包进去。如果 sales_schema 里的对象引用了别的 schema------比如外键指向 audit_schema 的表、或者视图 join 了别处的表------单独备 sales_schema 就可能把这些跨 schema 的依赖漏在外面,还原到干净的库时会因为找不到被引用的对象而报错。这篇的 sales_schema 内部自洽(外键都在自己 schema 内),所以干净;真实业务里备单个 schema 前,先摸清楚它有没有伸到别的 schema 去的手。
下一篇范围再缩一档:不是一个 schema,而是只把一张表从备份里单独捞回来。