尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

人大金仓KingbaseES逻辑备份工具sys_dump实战:从备份到恢复

人大金仓KingbaseES逻辑备份工具sys_dump实战:从备份到恢复 半夜两点被电话叫起来不是出了大事故而是开发兄弟误删了一张业务表。好在我们的作业里一直用 sys_dump 做定时备份二十分钟内就把那张表捞了回来。干国产数据库这块儿人大金仓 KingbaseES 的备份工具不算冷门但真正把 sys_dump 用顺手的团队还真不多。这篇文章不打算照着手册念就按我这几年的实际使用经验把 sys_dump 怎么选型、怎么用、怎么避坑从零到落地一次讲清楚。新人可以照着抄老手也能看看有没有漏掉的细节。1. 认识sys_dump先弄清楚它是哪把刀1.1 它是谁能干什么sys_dump 是人大金仓 KingbaseES 自带的逻辑备份工具位置一般在数据库安装目录的 bin 下面。按功能来说它和 MySQL 的 mysqldump、PostgreSQL 的 pg_dump 是同一类东西把数据库里的对象定义、表数据、索引、约束、函数、存储过程等内容按照逻辑结构导出成文件。导出的文件既可以是纯 SQL 文本也可以是一种带格式的归档文件后续用 ksql 或 sys_restore 再导回数据库。很多新手容易把 sys_dump 当成一个“全库备份”命令这个理解对了一半。它能备份的粒度非常灵活可以备份整个实例中的多个数据库也可以只备份某一个数据库可以在数据库内部再按照 schema模式筛选还可以精确到表。换句话说你可以在一条命令里决定“我导出哪些库、哪些模式、哪些表、只要结构还是只要数据”。这种灵活性在数据迁移、测试环境搭建、误删恢复这些场景里特别重要。另外要强调一点sys_dump 不是人大金仓的唯一备份工具。物理备份通常走 sys_backup对应的是数据库底层数据文件和重做日志的整体拷贝。但 sys_dump 这种逻辑备份的价值在于“细腻”某天有人误删了一张表你不需要把整个数据目录拖回来只要把那张表的逻辑数据恢复进去就行。实际工作中我习惯把逻辑备份和物理备份配合使用物理备份兜底逻辑备份做细粒度恢复。1.2 和物理备份放一起逻辑备份到底图什么既然有了物理备份为什么还要用 sys_dump我遇到过不少同事这样问。这里就要分清逻辑备份和物理备份的使用场景差异。物理备份直接复制数据库的物理文件速度最快恢复也是把文件放回去整库恢复非常稳但它的缺点是跨版本、跨平台能力弱想从旧版本恢复到新版本或者从一台异构服务器恢复到另一台往往很麻烦。物理备份的粒度也比较粗想单独捞一张表出来需要先整库恢复再导出费时费力。sys_dump 这类逻辑备份恰好补上这些短板。它导出的是数据库对象定义和数据的“逻辑表达”不依赖特定的文件系统布局所以在硬件更换、版本升级、跨平台迁移、测试数据脱敏后重建等场景里逻辑备份几乎是唯一方便的选择。它还能对一张表加 WHERE 条件只导出符合条件的数据这在做增量抽取、数据归档时非常好用。拿我常用的场景举例子业务上线前把生产库的表结构同步到测试库只需要-s参数导出结构。月度归档只导出半年前的历史订单数据可以通过-t限定表再配合--where过滤数据。误删单表恢复用sys_restore -t指定表名从整库备份中把那张表挑出来。跨版本升级先用 sys_dump 导出所有对象和数据新环境初始化后再导入。物理备份解决的是“最坏情况下的整库可用性”sys_dump 解决的是“日常操作中的灵活恢复”。这两个不是一个替代关系而是互补关系。下面这张表可以快速对比对比项sys_dump 逻辑备份sys_backup 物理备份备份粒度库、模式、表、条件数据整个实例或数据目录输出内容SQL语句 / 归档文件数据文件拷贝和日志恢复速度慢逐条执行SQL快文件级拷贝跨版本迁移支持较灵活限制较多单独恢复一张表方便需要整库恢复后再导出典型场景迁移、演练、误删恢复容灾、全量兜底2. sys_dump核心参数与用法拆解2.1 先跑通一条最简单的备份命令安装好人大金仓 KingbaseES 之后sys_dump 就在 bin 目录下。为了使用方便我一般会先设置环境变量export KINGBASE_HOME/opt/Kingbase/ES/V8 export PATH$KINGBASE_HOME/bin:$PATH设置好之后一条最基础的备份命令是这样sys_dump -U system -d testdb -f /backup/testdb.sql这条命令的意思是以 system 用户连接本机默认端口的 testdb 数据库把整库结构和数据导出到/backup/testdb.sql文件里格式是纯 SQL 文本。实际生产环境里我不建议直接使用超级用户跑备份。最好单独建一个专门用于备份的账号只赋予必要的连接和查询权限避免把数据库超级权限暴露在脚本或定时任务里。建一个sysbackup用户并授权的方式在官方文档里都有核心思路是备份账号需要 CONNECT 权限以及读取表数据的 SELECT 权限。如果还要备份所有对象定义比如函数、存储过程的所有者属性那通常还是得用较高权限账号这一点要在安全性和便利性之间做个取舍。另外提醒一下sys_dump 默认连接端口是 54321如果你的 KingbaseES 实例改过端口记得加-p参数。如果数据库和应用不在同一台机器还需要加-h指定主机地址。密码验证方面我习惯用环境变量或者密码文件不在命令行里直接暴露明文密码因为/proc里的进程命令行是可以被同机其他用户看到的。2.2 粒度控制整库、模式、表怎么选sys_dump 最大的魅力在于可以精细控制备份范围。下面这些参数我几乎天天用参数作用示例-d指定要备份的数据库名-d testdb-n只备份指定模式可重复使用-n public -n sales-t只备份指定表或视图可重复使用-t sales.orders-T排除指定表-T log.*-a只导出数据不导出结构-a-s只导出结构不导出数据-s-F指定输出格式p/c/d/t-F c-j并行导出线程数-j 4-Z压缩级别0-9-Z 9举几个比较典型的用法。备份指定模式sys_dump -U sysbackup -d testdb -n public -n sales -f /backup/sales_mode.dump某些大日志表不想每次备份可以用-T排除sys_dump -U sysbackup -d testdb -T log.access_log -T log.error_log -f /backup/without_log.dump只导出结构给测试库同步表结构sys_dump -U sysbackup -d testdb -s -f /backup/schema_only.sql只导出数据用于把老数据导入到已经建好表结构的新库sys_dump -U sysbackup -d testdb -a -f /backup/data_only.sql这些参数可以混着用但注意别冲突。比如-s和-a同时用sys_dump 就会忽略其中一个或者直接报错因为系统没法又导出结构又只导出数据。2.3 备份格式四选一p/c/d/t 这件事很关键sys_dump 的输出格式有四种很多人一开始不重视后面恢复时就踩坑。这里我详细说一下。第一种是plain也就是纯 SQL 文本参数是-F p。这种格式好处是可直接查看、可编辑恢复时直接用 ksql 执行即可。缺点是数据量大时文件特别大恢复也慢而且无法做选择性恢复。我一般只在小库、结构脚本场景使用它。第二种是custom对应-F c这是我最推荐的格式。它会把数据库对象和数据以自定义格式写入一个文件支持压缩支持在恢复时按表选择还支持在导出时用-Z指定压缩级别。误删表需要单表恢复时custom 格式配合 sys_restore 的-t参数非常好使。生产环境的日常备份我基本都用 custom。第三种是directory对应-F d输出的是一个目录内部会有一个文件描述整体信息每个表的备份独立成一个文件。这种格式最大的优势是天然支持并行恢复也支持并行导出只要配合-j参数。超大数据库场景我更倾向于用它。缺点是不能像单文件一样直接拷贝完事备份目录要整体保留。第四种是tar对应-F t。它其实是一个 tar 打包格式看起来友好但恢复时的灵活程度不如 custom 和 directory。它同样需要 sys_restore 来恢复。老实说这个格式我用的比较少因为 custom 已经覆盖了绝大多数需求。对应关系整理如下格式参数压缩选择性恢复并行恢复工具plain-F p不支持不支持不支持ksqlcustom-F c支持支持不支持sys_restoredirectory-F d支持支持支持sys_restoretar-F t支持支持不支持sys_restore提一个性能相关的小经验如果只是小库plain 格式足够但生产环境哪怕库只有几十 GB我也建议用 custom 或 directory。原因很简单后续恢复时可以选择只恢复一张表不用把整个 100GB 的 SQL 全部执行一遍。3. 完整实操从策略设计到定时备份落地3.1 备份前先想清楚全量还是增量多久做一次很多新手拿到 sys_dump 就直接写脚本跑跑完就以为万事大吉。实际上备份策略才是整个备份体系里最需要花时间设计的部分。我一般会问自己三个问题备份窗口有多长数据要保留多久一旦出事故能接受丢多少数据sys_dump 本身没有类似“增量备份”的完整功能它每次跑基本都是全量导出。但我们可以通过表级、模式级和 WHERE 条件组合出近似“差异备份”的方案。比如每天凌晨全量备份核心表每周末再做一次整体全量备份或者对超大历史表只备份最近七天的数据更早的数据靠归档表留存。这里要特别说下--where参数。sys_dump 允许对表导出时加过滤条件比如只导出近一天的数据sys_dump -U sysbackup -d testdb -t sales.orders -a \ --whereorder_date CURRENT_DATE - 1 \ -f /backup/orders_daily.dump但注意这种用法只导出数据而且要配合-a如果结构也跟着导出恢复时容易造成表结构缺失。具体使用时一定要先想清楚恢复路径不然导出的数据文件根本没法直接用。备份频率怎么定核心看业务对丢失数据的容忍度。如果业务允许丢一天的订单那每天全量够了如果只能丢十分钟那 sys_dump 全量备份就撑不起来得配合物理备份、归档日志或者同步工具。作为逻辑备份sys_dump 更多是兜底和数据迁移工具别把它当成「零丢失容灾」的万能方案。3.2 写一个生产可用的备份脚本我写备份脚本的套路比较固定核心就几句话设置环境变量、生成带日期的文件名、执行 sys_dump、保留最近 N 份、清理过期日志。下面是一个可以直接抄作业的版本#!/bin/bash set -euo pipefail export KINGBASE_HOME/opt/Kingbase/ES/V8 export PATH$KINGBASE_HOME/bin:$PATH export PGPASSWORD这里是密码 DB_NAMEtestdb BACKUP_BASE/data/backup BACKUP_DIR${BACKUP_BASE}/${DB_NAME} DATE$(date %Y%m%d_%H%M%S) LOG_FILE${BACKUP_BASE}/backup_${DB_NAME}.log mkdir -p ${BACKUP_DIR} echo [$(date %F %T)] start sys_dump ${LOG_FILE} sys_dump -U sysbackup -h 127.0.0.1 -p 54321 -d ${DB_NAME} \ -F c -Z 9 \ -f ${BACKUP_DIR}/${DB_NAME}_${DATE}.dump ${LOG_FILE} 21 echo [$(date %F %T)] end sys_dump ${LOG_FILE} # 保留最近7份备份 find ${BACKUP_DIR} -name *.dump -mtime 7 -delete # 清理30天前的日志 find ${BACKUP_BASE} -name backup_*.log -mtime 30 -delete这里有几个细节值得展开。第一为什么用-F c -Z 9custom 格式支持压缩-Z 9是最高压缩级别能省不少磁盘空间。代价是导出时 CPU 开销略高但通常影响不大。如果服务器 CPU 很紧张可以降成-Z 5。第二为什么用set -euo pipefail因为一旦 sys_dump 报错脚本必须立刻退出不能继续执行后面的清理动作避免“备份失败但老备份全被清了”的惨剧。这个坑我踩过所以现在所有备份脚本都加这个开关。第三为什么用find ... -mtime 7 -delete而不是简单数文件个数因为有些项目备份文件可能较大保留策略按时间更直观如果想保留最近 7 份而不是最近 7 天也可以用ls -t配合tail -n 8来删这个看个人习惯。第四PGPASSWORD直接用明文写在脚本里仅适合内网环境。生产环境我更推荐用密码文件或者通过配置中心把密码注入到环境变量里不要把明文密码写进代码仓库。3.3 用 crontab 定时跑起来脚本写好后定时调度是另一个容易翻车的地方。最常见的问题是手动执行脚本一切正常放到 crontab 里就不行多半是环境变量缺失。因为 cron 默认不加载用户的环境变量连 PATH 都可能是精简版本所以脚本内部必须用绝对路径或者自己 export 环境变量。一个标准 crontab 配置如下30 2 * * * /data/scripts/backup_kingbase.sh /data/backup/cron.log 21这表示每天凌晨 2 点 30 分执行一次备份。选这个时间点通常是为了避开业务高峰同时给批处理任务留出空间。如果同步任务、报表任务都挤在同一时刻建议错峰。djob 提交后记得先手动执行一次脚本确认没有密码提示、没有路径问题。然后再观察连续几天的备份日志确认文件大小和生成时间都稳定才算真正落地。4. 恢复实操、常见报错与排查实录4.1 恢复两条路ksql 和 sys_restore有备份就必须有恢复恢复才是最终目的。不同备份格式恢复方式不一样。如果是 plain 格式的 SQL 文件直接用 ksql 执行ksql -U system -d testdb -f /backup/testdb.sql如果是 custom 或 directory 格式需要用 sys_restoresys_restore -U system -d testdb -C /backup/testdb.dump-C参数表示在恢复前创建数据库。如果目标库已经存在可以去掉-C直接恢复到现有库中。除此之外还有两个参数很常用--clean表示在创建对象前先删除已存在的同名对象--if-exists表示删除时加上 IF EXISTS 条件避免因为对象不存在而中断。最实用的场景是单表恢复。比如凌晨误删了sales.orders表我从最近一次 custom 备份中只恢复这一张表sys_restore -U system -d testdb -t sales.orders /backup/testdb_20250101.dump这样 sys_restore 会从备份文件里找到这张表只执行与它相关的恢复操作其他对象全部跳过。恢复速度很快也不影响库里的其他表。恢复操作之前最好先确认目标数据库没有活跃的写入事务。如果线上业务正在写入同一张表恢复过程中会遇到锁等待甚至死锁。实际操作中我倾向于把恢复窗口安排在业务低谷必要时先断开应用连接。4.2 高频踩坑速查表下面这些报错和问题是我在 sys_dump 使用过程中遇到最多的情况整理成表方便查问题现象可能原因排查方向too many clients already实例连接数满了查max_connections释放空闲连接permission denied for table xxx备份账号没有表权限给账号授权或改用有权限的账号lock timeout表上有长事务持锁设置--lock-wait-timeout错峰备份恢复时提示表已存在目标库已有同名对象加--clean或先手工清理备份文件快速打满磁盘备份文件太多或太大检查df -h调整保留策略中文乱码客户端字符集和服务端不一致设置PGCLIENTENCODINGsys_dump: error: query failed备份过程中表结构被修改核对 DDL 变更尽量在维护窗口备份这里值得展开的是锁等待问题。sys_dump 导出一张表时通常会对表请求 ACCESS SHARE 级别的锁这个锁和写入操作的 ROW EXCLUSIVE 锁会冲突。如果某个长事务一直占着表sys_dump 就会一直等。为了不让备份任务被锁拖死我习惯在备份命令里加上sys_dump ... --lock-wait-timeout5这样超过 5 秒拿不到锁就放弃宁可这次备份失败也不能让备份进程把整个库拖到锁风暴里。备份失败可以通过告警发现再人工处理数据库锁死造成的业务影响可比备份失败大得多。字符集问题也经常让人头大。如果备出来的文件在恢复时出现乱码先检查两个库的字符集是否一致。KingbaseES 的默认字符集通常跟随初始化参数如果源库是 UTF8目标库是 GBK恢复时就会出问题。解决方案是让两边字符集保持一致或者在导出时通过PGCLIENTENCODING环境变量指定客户端编码。4.3 备份成功不等于备份可用每次看到有人只检查备份脚本退出码是 0 就觉得万事大吉我都想多说两句。备份成功只是开始备份可恢复才是目的。我见过太多案例备份文件一直在生成但某天真的要恢复时才发现文件损坏、不完整或者权限不对等于白备份。所以我推荐的验证流程是第一备份完成后检查日志。sys_dump 在运行过程中如果遇到某些非致命错误可能会继续执行但日志里会有 WARNING。脚本里可以加一步 grep 检查grep -E WARNING|ERROR ${LOG_FILE} exit 1第二定期做恢复演练。至少每个季度在测试环境执行一次完整恢复。恢复后可以抽几张核心表做 count 对比确认数据行数和源库一致。这一步不能省恢复一次胜过检查十次备份日志。第三对于 custom 格式的文件可以用下面命令查看归档内容sys_restore -l /backup/testdb.dump它会列出备份文件里包含的所有数据库对象一眼能看出哪些表导进去了、哪些没有。这个命令非常轻量适合快速确认备份完整性。5. Docker环境备份与KWR联动监控5.1 容器里装的人大金仓备份照样跑现在不少人喜欢用 Docker 部署人大金仓 KingbaseES本地开发、测试环境尤其常见。容器部署和传统部署的备份逻辑其实是一样的只是要额外处理“容器内外文件交换”的问题。如果容器已经启动最简单的做法是直接进入容器执行 sys_dumpdocker exec -it kingbase-container bash sys_dump -U system -d testdb -F c -f /tmp/testdb.dump退出容器后再把备份文件拷贝到宿主机docker cp kingbase-container:/tmp/testdb.dump /data/backup/但这种方式有个问题如果容器被重建容器内的文件会丢。更推荐的方式是在启动容器时就把备份目录挂载到宿主机。类似这样docker run -d \ --name kingbase-container \ -v /data/backup:/backup \ image-name之后备份命令直接写到挂载目录docker exec kingbase-container bash -c \ sys_dump -U system -d testdb -F c -f /backup/testdb.dump挂载的好处是可以直接保存到宿主机磁盘容器销毁也不影响备份文件。如果宿主机已经做了磁盘阵列或异地备份那就更踏实了。还有一个坑需要提醒容器内的 cron 通常不是默认开启的而且容器重启后 cron 服务可能不会自动拉起。所以在容器场景下我建议不要在容器内部配 crontab而是在宿主机上用 cron 调用docker exec来触发备份30 2 * * * docker exec kingbase-container bash -c sys_dump -U system -d testdb -F c -f /backup/testdb.dump /data/backup/cron.log 21这样每台宿主机只要负责自己上面的容器备份任务管理起来也清晰。5.2 用KWR盯住备份期间的性能波动备份虽然是运维操作但它同样消耗 CPU、IO 和网络资源。某些业务高峰期跑 sys_dump会把磁盘 IO 拉满导致业务查询变慢。要定位这种性能问题人大金仓的 KWRKingbaseES Workload Report是个顺手工具和 Oracle 的 AWR 报告思路类似可以自动或手动采集实例在一段时间内的运行指标然后输出一份工作负载报告。我的用法是在备份任务开始前打一个快照备份结束后再打一个快照然后生成这段时间的 KWR 报告对比看备份期间数据库的等待事件、IO 延迟、CPU 使用率是否异常。如果发现某类等待事件占比特别高就针对性地调整备份策略比如错峰、降并行度、或者把备份流复制到独立存储。实际经验里最影响业务的往往是 sys_dump 导出大表时的顺序读放大。如果服务器磁盘本来就慢备份期间 IO 等待会明显上升。这种情况下可以结合 KWR 报告里的 IO 数据判断是否需要降低-Z压缩级别或者改用-j并行策略让 IO 更平滑。压缩级别越高CPU 消耗越大并行数越高IO 波动越大。这两者都需要结合数据库实际负载来调不能盲目拉满。如果你在 Docker 环境里跑金仓同样可以在容器内开启 KWR 采集。不过容器实例的资源隔离特性决定了宿主机上的其他容器可能也会争抢 CPU 和磁盘所以 KWR 报告只能反映数据库内部视角宿主机层面的监控还是需要配合docker stats或者系统监控工具一起看。5.3 备份容灾规划的小建议结合上面的内容最后聊几个备份规划建议。第一遵循 3-2-1 原则。至少保留 3 份备份副本放在 2 种不同的存储介质上其中 1 份在异地。对很多中小团队来说本地磁盘一份、另一台服务器一份再加对象存储一份基本就能满足。第二备份文件不能只躺在备份服务器上定期要做恢复测试。没有经过恢复验证的备份本质上只是“一堆数据”。第三给备份文件做完整性校验。custom 格式可以直接用sys_restore -l检查内容但文件是否在上传过程中损坏最好再算一下校验和。脚本里可以用 md5sum 生成校验文件后续验证时就拿校验值对比。6. 写在最后备份这件事功夫在平时说实话最靠谱的备份不是写在文档里的漂亮方案而是在一次次真实恢复演练里练出来的熟练度。我见过太多因为没做过恢复演练等到真出事故时连备份文件都打不开的例子。sys_dump 真的是一个好用又灵活的工具参数就那么多多试几次就不会踩坑。我个人还有一个习惯每次备份脚本上线后先连续观察一周确认每天备份文件大小、耗时都稳定然后至少每个月做一次单表恢复演练每季度做一次整库恢复演练。演练的时候顺手把恢复步骤写成操作手册标记每一步的预估时间。这样等哪天真出了误删、误更新、迁移失败的问题整个团队都能稳住而不是临时翻文档抓瞎。最后分享一个小技巧备份脚本里别忘了给文件名加上日期但恢复时不要只看文件名就信先sys_restore -l看一下内容。文件名只能说明“这个时间点有备份文件”内容正确才是真的安全。
返回列表