游乐游手机版
首页/数据库/文章详情

金仓数据库逻辑备份实战:全库导出与模式替换全流程

时间:2026-07-03 07:08
在长期的运维实践中,我越来越体会到,备份就像一份保险——平时看似无用,但关键时刻却是唯一的救命稻草。逻辑备份看似简单,可真正执行恢复时,各种陷阱接连浮现:表名大小写不一致、Schema 未正确切换、Owner 属性未同步修改……任何一个环节处理不当,最终恢复出的数据库就会与预期相去甚远。 本文将深入

在长期的运维实践中,我越来越体会到,备份就像一份保险——平时看似无用,但关键时刻却是唯一的救命稻草。逻辑备份看似简单,可真正执行恢复时,各种陷阱接连浮现:表名大小写不一致、Schema 未正确切换、Owner 属性未同步修改……任何一个环节处理不当,最终恢复出的数据库就会与预期相去甚远。

金仓数据库逻辑备份实战:从全库导出到 Schema 替换的完整闭环

本文将深入解析金仓数据库(KingbaseES)逻辑层面的备份与恢复操作,从全库导出到恢复过程中如何干净地将旧 Schema 替换为新 Schema,内容均源自实际踩坑与验证后的经验总结,希望能助您避开常见误区。

一、逻辑备份的三种导出格式

金仓数据库逻辑备份的核心工具是 sys_dump,它支持三种导出格式,分别适用于不同场景。请先了解格式差异,因为后续恢复时使用的命令完全取决于最初选择的导出格式。

第一种是纯文本格式,参数 -Fp,导出为普通的 .sql 文件,内容均为可读的 SQL 语句。此格式最大的优势在于透明性——您可以直接打开查看,甚至用文本编辑器进行修改。示例如下:

 复制代码# su - kingbase
$ mkdir -p /home/kingbase/backup/sys_dump_$(date +%Y%m%d%H)
$ sys_dump -h 127.0.0.1 -p 54321 -U system -d dbtest -f /home/kingbase/backup/sys_dump_$(date +%Y%m%d%H)/dbtest.sql

第二种是自定义二进制格式,参数 -Fc,导出为 .dmp 文件。此格式经过压缩,体积更小,并且恢复时灵活性高,可选择性地仅恢复部分对象。

 复制代码# su - kingbase
$ mkdir -p /home/kingbase/backup/sys_dump_$(date +%Y%m%d%H)
$ sys_dump -h 127.0.0.1 -p 54321 -U system -d dbtest -Fc -f /home/kingbase/backup/sys_dump_$(date +%Y%m%d%H)/dbtest.dmp

第三种是目录格式,参数 -Fd,将备份内容拆分为一个目录中的多个文件。这是唯一支持并行备份的格式,通过 -j 参数指定并行度,可显著加快大库备份速度。

 复制代码# su - kingbase
$ sys_dump -h 127.0.0.1 -p 54321 -U system -d dbtest -Fd -j 4 -f /home/kingbase/backup/sys_dump_$(date +%Y%m%d%H)

注意目录格式存在一个细节:如果目标目录已存在,则需先删除再执行备份,否则会引发错误。

二、不只是全库,还能精细到 Schema 和单表

在实际工作中,我们往往不需要整库备份,可能只需保护某个 Schema 或关键表。sys_dump 可使用 -n 指定 Schema,用 -t 指定表。

仅备份某个 Schema:

 复制代码$ sys_dump -h 127.0.0.1 -p 54321 -U system -d dbtest -n public -f /home/kingbase/backup/sys_dump_$(date +%Y%m%d%H)/public.sql

仅备份某张表:

 复制代码$ sys_dump -h 127.0.0.1 -p 54321 -U system -d dbtest -t test -f /home/kingbase/backup/sys_dump_$(date +%Y%m%d%H)/test.sql

需要提醒新人注意几个参数:-a 表示仅备份数据(不包括结构),-s 则相反,仅备份结构(不包括数据)。此外,还有一个关键特性容易被忽视:sys_dump 仅转储备份开始时刻的快照,备份过程中的数据变更不会被包含。此机制保证了备份的一致性,但您必须清楚这条边界。

三、那个最容易让人栽跟头的坑:表名大小写

说到 -t 指定表名,这里必须单独强调一个极易踩坑的典型问题。当表名为大小写混合时,sys_dump 经常报错 no matching tables were found,可表明明就在那里,它却找不到。

问题的根源不在数据库,而在于 Linux Shell 的语法解析。先理解金仓数据库中表名的存储方式。在大小写不敏感环境(enable_cion)下,建表时不加双引号,表名会被统一转为小写存储在数据字典中。

 复制代码TEST=# create table dD (id int );
CREATE TABLE
TEST=# select relname from pg_class where relname='dd';
 relname
---------
 dd
(1 row)

但如果在建表时为表名添加了双引号,则会原样保留大小写混合的形态:

 复制代码create table "gD" (id int );
TEST=# select relname from pg_class where relname='gD';
 relname
---------
 gD
(1 row)

此时问题便出现了。在 sys_dump 命令中写 -t "hGF",本意是保留大小写,但双引号在 Shell 中会先被解析,实际传给 sys_dump 的只剩下 hGF,而数据字典中存储的是带引号语义的标识符,两者无法匹配,于是报错。

 复制代码[kingbase2@localhost V8]$ sys_dump -U system -d test -p 2920 -FC -t "hGF" -f /opt/Kingbase/ES/V8/dd1.dmp
sys_dump: error: no matching tables were found

正确的写法有两种,核心思路都是让双引号能够真正传递到 sys_dump 层级。第一种使用转义符:

 复制代码sys_dump -U system -d test -p 2920 -FC -t ""hGF"" -f /opt/Kingbase/ES/V8/db1.dmp

第二种用单引号包裹双引号,因为 Shell 中单引号内的内容被视为纯字符串,不会进行任何解析:

 复制代码sys_dump -U system -d test -p 2920 -FC -t '"hGF"' -f /opt/Kingbase/ES/V8/db2.dmp

请牢记这个区别:Shell 中单引号表示字面字符串,双引号则会触发变量解析。因此,当涉及大小写混合的表名时,要么使用转义,要么用单引号包裹。

顺带提一下大小写敏感与不敏感环境的差异。敏感环境(enable_cioff)下,小写表、大写表、混合表可以同时存在,互不冲突。而不敏感环境下,无论输入 agAg 还是 AG,系统只会识别为其中一种形态,后续再尝试创建另一种形态的同名表时,会直接报错 relation already exists。这一特性在数据库迁移和恢复时尤其需要留意。

四、恢复:导出格式决定了你用什么命令

介绍完备份,接下来是恢复操作。这里有一条铁律:恢复时使用的命令完全取决于你当初选择的导出格式。

纯文本的 .sql 文件只能用 ksql 恢复,这一点没有商量余地。恢复前需先创建好目标数据库。

 复制代码# su - kingbase
$ createdb -h 127.0.0.1 -p 54321 -U system dbtest
$ ksql -h 127.0.0.1 -p 54321 -U system -d dbtest -f /home/kingbase/backup/sys_dump_2023060615/dbtest.sql

自定义格式和目录格式则使用 sys_restore

 复制代码# 自定义格式
$ sys_restore -h 127.0.0.1 -p 54321 -U system -d dbtest /home/kingbase/backup/sys_dump_2023060615/dbtest.dmp# 目录格式,同样支持并行
$ sys_restore -h 127.0.0.1 -p 54321 -U system -d dbtest -Fd -j 4 /home/kingbase/backup/sys_dump_2023060615

使用 sys_restore 时有一个参数细节需提醒:-d-f 不能同时使用,只需用 -d 指定目标库,无需再用 -f 单独指定文件路径。这一点常有人混淆。

恢复 Schema 或单表的逻辑类似:如果当初导出的是 .sql 文件,则仍使用 ksql 配合 -f

 复制代码$ ksql -h 127.0.0.1 -p 54321 -U system -d dbtest -f /home/kingbase/backup/sys_dump_2023060615/public.sql

五、进阶玩法:恢复时把旧 Schema 换成新的

最后讨论一个稍显高级但实战中非常实用的需求:在恢复时,不想使用原有的 Schema,而是替换成一个新的。例如,源库中的数据都在 abc 这个 Schema 下,我们希望导入目标库时将其落到 u2 下面。

sys_restore 提供了 -g-G 参数来实现此目的。但这里有一个极易被忽略的陷阱:仅添加 -g -G 参数后,表确实会落到新的 Schema,但表的 Owner 仍然是旧的!如果连 Owner 也想一并更换,必须额外加 -O 参数。

用一个完整的测试来说明。先准备环境:新建一个 abc 用户、abc 库、abc Schema,其中存放一张 t1 表,Owner 和 Schema 均为 abc。再新建一个超级用户 u2 及其对应的 u2 Schema。

导出 abc 库:

 复制代码sys_dump -Uabc -Fc -f abc.dmp abc -p 2920

加上 -O-g-G 三个参数进行恢复,目标 Schema 指定为 u2

 复制代码sys_restore -Uu2 -dabc -Fc -p 2920 -gabc -Gu2 -O abc.dmp

恢复完成后,检查发现 t1 表的 Schema 和 Owner 都变成了 u2,这正是我们所期望的结果:

 复制代码abc-# c abc u2
abc-# d
               List of relations
 Schema |        Name         | Type  | Owner
--------+---------------------+-------+--------
 public | sys_stat_statements | view  | system
 u2     | t1                  | table | u2
(2 rows)

作为对比,如果不加 -O,您会看到 Schema 虽然换成了 u2,但 Owner 仍然顽固地保持为 abc

 复制代码sys_restore -Uu2 -dabc -Fc -p 2920 -gabc -Gu2 abc.dmp
-- 结果里 t1 的 Owner 仍然是 abc

除了使用参数外,还有一种更直接的方法:导出为 .sql 文本,然后通过 sed 命令将文件中的 Schema 名称全部替换。

 复制代码sys_dump -Usystem -Fp -f abc.sql abc -p 2920
sed -i 's/abc/u2/g' abc.sql
sed -i 's/public/u2/g' abc.sql
ksql abc -Usystem -f abc.sql

这种方式直观易懂,但存在明显短板:对于数据量大的库,文本替换速度较慢,且全局替换容易误伤(例如表名中恰好也包含 abc 字样)。因此,小库可以尝试此方法,大库则建议老老实实使用 sys_restore 的参数。

写在最后

逻辑备份这套体系,真正的难点从来不在于命令本身,而在于那些隐藏在细节中的边界条件:三种格式各自的恢复方式、大小写混合表名在 Shell 中的转义处理、sys_restore 的参数互斥规则,以及 Owner 与 Schema 替换不同步的问题。只有将这些坑一一填平,您的备份恢复流程才能真正做到可靠。

最终建议始终如一:生产环境务必定期进行恢复演练。备份文件躺在硬盘上并不算真正的备份,只有在需要时能够完整、正确地恢复出来,那才叫真正的容灾能力。

来源:https://juejin.cn/post/7655565829648597026
上一篇金仓数据库sys_rman物理备份全流程演练与误覆盖恢复
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
金仓数据库sys_rman物理备份全流程演练与误覆盖恢复
数据库 · 2026-07-03

金仓数据库sys_rman物理备份全流程演练与误覆盖恢复

干运维这行,逻辑备份和物理备份我都接触过,但说句实在话,真正能在生产环境里扛住事儿的,还得是物理备份。逻辑备份导出的是 SQL 语句,数据量一大,那速度慢得让人抓狂,而且最关键的是,它没法做时间点恢复。物理备份不一样,它直接拷贝数据文件,再配上 WAL 归档日志,想恢复到过去哪一秒都行,这是它最硬核

Windows下将MySQL注册为系统自启服务教程
数据库 · 2026-07-03

Windows下将MySQL注册为系统自启服务教程

先说一个关键前提:务必以管理员身份运行终端,否则 mysqld --install 这条命令几乎不可能成功。问题不在于命令写错,而是 Windows 系统的用户账户控制(UAC)机制会在中途拦截——在普通 CMD 或 PowerShell 窗口执行这条命令,要么直接提示 Access is deni

Mac版Navicat中快速对比两个数据库的表结构异同
数据库 · 2026-07-03

Mac版Navicat中快速对比两个数据库的表结构异同

直接说结论:Mac 版 Navicat 和 Windows 版在表结构比对逻辑上完全一致。但默认配置下,它确实无法承受“全库一键比对上万张表”的压力。要想避免卡死、内存溢出、进度条永远停在 0%,你必须手动将表分批处理,或者利用前缀过滤来控制扫描范围。 为什么 Mac 上点击「结构同步」后界面会卡住

MySQL中UNION操作推荐用UNION ALL的原因
数据库 · 2026-07-03

MySQL中UNION操作推荐用UNION ALL的原因

MySQL中UNION与UNION ALL性能对比:别再被“保险”迷惑,差距远超预期 先给出核心结论:UNION ALL 的性能通常比 UNION 高出不止一个数量级。原因在于,UNION 在合并结果集后会自动触发去重操作,这往往伴随着隐式排序,进而产生临时表和文件排序。而 UNION ALL 则直