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

本文将深入解析金仓数据库(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_ci 为 on)下,建表时不加双引号,表名会被统一转为小写存储在数据字典中。
复制代码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_ci 为 off)下,小写表、大写表、混合表可以同时存在,互不冲突。而不敏感环境下,无论输入 ag、Ag 还是 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 替换不同步的问题。只有将这些坑一一填平,您的备份恢复流程才能真正做到可靠。
最终建议始终如一:生产环境务必定期进行恢复演练。备份文件躺在硬盘上并不算真正的备份,只有在需要时能够完整、正确地恢复出来,那才叫真正的容灾能力。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
金仓数据库逻辑备份实战:全库导出与模式替换全流程
在长期的运维实践中,我越来越体会到,备份就像一份保险——平时看似无用,但关键时刻却是唯一的救命稻草。逻辑备份看似简单,可真正执行恢复时,各种陷阱接连浮现:表名大小写不一致、Schema 未正确切换、Owner 属性未同步修改……任何一个环节处理不当,最终恢复出的数据库就会与预期相去甚远。 本文将深入
金仓数据库sys_rman物理备份全流程演练与误覆盖恢复
干运维这行,逻辑备份和物理备份我都接触过,但说句实在话,真正能在生产环境里扛住事儿的,还得是物理备份。逻辑备份导出的是 SQL 语句,数据量一大,那速度慢得让人抓狂,而且最关键的是,它没法做时间点恢复。物理备份不一样,它直接拷贝数据文件,再配上 WAL 归档日志,想恢复到过去哪一秒都行,这是它最硬核
Windows下将MySQL注册为系统自启服务教程
先说一个关键前提:务必以管理员身份运行终端,否则 mysqld --install 这条命令几乎不可能成功。问题不在于命令写错,而是 Windows 系统的用户账户控制(UAC)机制会在中途拦截——在普通 CMD 或 PowerShell 窗口执行这条命令,要么直接提示 Access is deni
Mac版Navicat中快速对比两个数据库的表结构异同
直接说结论:Mac 版 Navicat 和 Windows 版在表结构比对逻辑上完全一致。但默认配置下,它确实无法承受“全库一键比对上万张表”的压力。要想避免卡死、内存溢出、进度条永远停在 0%,你必须手动将表分批处理,或者利用前缀过滤来控制扫描范围。 为什么 Mac 上点击「结构同步」后界面会卡住
MySQL中UNION操作推荐用UNION ALL的原因
MySQL中UNION与UNION ALL性能对比:别再被“保险”迷惑,差距远超预期 先给出核心结论:UNION ALL 的性能通常比 UNION 高出不止一个数量级。原因在于,UNION 在合并结果集后会自动触发去重操作,这往往伴随着隐式排序,进而产生临时表和文件排序。而 UNION ALL 则直
- 日榜
- 周榜
- 月榜
相关攻略
2026-07-03 07:07
2026-07-03 07:07
2026-07-03 07:07
2026-07-03 07:07
2026-07-03 07:07
2026-07-03 07:07
2026-07-03 07:06
2026-07-03 07:06
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

