☰
openGauss物理备份实战:gs_probackup增量备份与PITR恢复指南
2026/10/7 22:07:24 网站建设 项目流程

干数据库运维的都知道,备份这事儿平时看不出价值,出事儿那天才知道它有多重要。openGauss这两年国产化落地不少,但它的物理备份方案一直挺折腾人——官方自带的gs_dump只能做逻辑备份,数据量大或者想做到能精确回放事务的恢复,逻辑备份就有点顶不住了。gs_probackup这个从pg_probackup移植适配过来的工具,算是把openGauss的物理备份、增量备份、基于时间点的恢复这些能力补全了。

这篇文章我把gs_probackup做增量备份恢复的完整链路写出来,包括方案选型、环境准备、参数配置、全量+增量备份实操、恢复实操,以及我在真实环境里踩过的坑和排错过程。适合正在用openGauss跑生产、想建立一套正经备份体系的DBA和运维同学。下面这些命令我都实际跑过,照着做基本能复现。

1. 备份方案怎么选:为什么是gs_probackup

1.1 openGauss备份的现状与痛点

openGauss开箱自带的备份手段主要是gs_dump和gs_dumpall,这两个都是逻辑备份,把数据导出成SQL文件或者COPY格式的数据文件。逻辑备份在库比较小、恢复精度要求不高的场景下够用,但生产库一旦到了几百GB甚至上TB,劣势就非常明显:导出慢、恢复慢,更重要的是它只能还原到“某个备份时刻”的数据快照,没办法做到基于时间点恢复(PITR),也没办法按事务ID精确回放。业务误删数据这种事故,逻辑备份基本救不回来。

另一个常见的土办法是直接冷拷贝数据文件。这方案的问题在于要停库才能保证一致性,对于7×24小时的业务来说基本不可接受。手工拷贝还容易漏文件、丢WAL,恢复的时候各种对不上。所以真正要在生产环境解决openGauss的备份问题,必须上物理备份工具。

1.2 gs_probackup的核心能力

gs_probackup是openGauss社区从PostgreSQL生态的pg_probackup移植适配过来的物理备份工具。它做的事本质上就是“把数据文件原样备份下来,配合WAL日志做一致性恢复”,但具体能力比一句话描述的要多得多:

  • 全量备份:把整个数据目录完整备份一份,作为后续增量的基础。
  • 页级增量备份:基于openGauss的PTRACK机制,只备份自上次备份以来被修改过的数据页。
  • WAL归档管理:把WAL日志统一归档,支持恢复到任意时间点和指定事务。
  • 备份集校验:可以检查备份链的完整性,确认备份集可恢复。
  • 并行备份恢复、压缩、保留策略清理等工程化能力。

这套能力和商业数据库的备份工具已经很接近了,而且它是开源、随openGauss发行版自带的,不需要额外采购商业组件。

1.3 与其他方案的对比

方案备份粒度PITR对业务影响适合场景
gs_dump / gs_dumpall逻辑不支持基本无影响小库、迁移、结构导出
冷拷贝数据目录物理不支持需要停库维护窗口、测试环境
gs_probackup全量物理支持几乎无感知各种规模
gs_probackup页级增量物理支持几乎无感知大库、高频备份

结论很直接:生产环境的openGauss,如果对恢复时间、恢复精度有要求,gs_probackup是目前开源方案里最靠谱的选择。我见过不少团队一开始用gs_dump顶着,等库涨到一定程度、备份时间压不住业务窗口的时候,最后还是回到gs_probackup这条路上。

2. 环境准备与初始化配置

2.1 确认工具与安装方式

openGauss的安装包默认会带上gs_probackup,通常在$GAUSSHOME/bin目录下。装完数据库后直接用which gs_probackup确认即可。如果确实没有,可以从openGauss社区的Gitee仓库拉源码自己编译,过程也不复杂:

git clone https://gitee.com/opengauss/gs_probackup.git cd gs_probackup mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j4 && make install

编译完把生成的二进制软链到$GAUSSHOME/bin下,或者加进PATH。然后确认版本:

gs_probackup --version

这里有个小提醒:不同openGauss版本自带的gs_probackup版本可能不一样,命令参数有些细微差异。动手之前先跑一遍gs_probackup --help,把-B、-i、-b这几个核心参数的写法确认清楚。

2.2 初始化备份目录并注册实例

gs_probackup需要一个独立的“备份目录”,它所有的备份集、WAL归档都统一放在这里管理。建议把这个目录放在单独的挂载盘上,和数据库数据目录物理隔离,避免互相挤占磁盘。

mkdir -p /data/gauss_backup chown -R omm:dbgrp /data/gauss_backup su - omm gs_probackup init -B /data/gauss_backup

init命令会生成备份目录的基础结构。接下来把要备份的数据库实例注册进去:

gs_probackup add-instance -B /data/gauss_backup -D /data/omm/data -i gauss1

参数逐一说清楚:

  • -B:备份目录,就是刚才建的那个路径。
  • -D:openGauss的数据目录。不确定的话,用show data_directory;在数据库里查一下。
  • -i:实例名,自己起一个,建议和业务或环境对应,比如gauss_prod、gauss_test,后面所有命令都要用这个实例名。

注册完成后,备份目录下会生成backup.control和实例级别的配置文件。可以用gs_probackup show-config -B /data/gauss_backup -i gauss1查看实例当前的配置项。

2.3 数据库侧参数配置

这是最容易踩坑的环节。gs_probackup的物理备份强依赖几个数据库参数,不配好,后面所有备份命令都会报错。打开postgresql.conf(openGauss里通常是postgresql.conf加上postgresql.conf.helper的组合),确认以下参数:

wal_level = hot_standby archive_mode = on archive_command = 'cp %p /data/wal_archive/%f' ptrack_enable = on session_timeout = 0

逐个说明:

  • wal_level:至少要archive级别,openGauss默认通常是hot_standby,一般不用动。
  • archive_mode:必须开on,关了备份直接失败。
  • archive_command:WAL归档命令。上面示例是归档到本地目录,需要先建好/data/wal_archive目录并chown。另一种方式是让gs_probackup自己接管归档,把WAL直接归档进备份目录里,命令形如:
archive_command = 'gs_probackup archive-archive -B /data/gauss_backup -i gauss1 --wal-file-name %f'

两种方式各有适用场景。我常用本地目录方式,简单直观,PITR的时候手动把WAL拷到恢复实例即可。如果图省事,推荐用gs_probackup自管理方式,恢复时它会自动从备份目录里找WAL。

  • ptrack_enable:PTRACK开关,页级增量备份必须开。这个参数openGauss支持reload生效,但我建议和前面几个一起改完重启,统一生效。
  • session_timeout:openGauss的空闲会话超时参数,默认值在不同版本里差异很大。备份期间如果有长事务或者交互操作,很容易被它杀掉,建议直接置0关闭,这个问题下面排错章节还会细讲。

改完参数重启数据库:

gs_ctl restart -D /data/omm/data

注意:archive_mode和wal_level修改后必须重启数据库才生效,reload没用。很多人就是改了参数不重启,然后备份一直报“WAL archiving is not enabled”,排查半天才发现是这回事。

3. 增量备份的运行机制

3.1 两种备份模式的区别

gs_probackup支持两种备份模式,由-b参数指定:

  • full:全量备份,整个数据目录完整拷贝。后续所有增量都以它为基础。
  • page:页级增量备份,基于PTRACK,只备份自上次备份以来被修改过的数据页。

这里的“增量”和很多数据库工具里的差异增量、累计增量不太一样。page增量是一条链式结构:

全量备份(base) → page增量1(备份自base以来变化的数据页) → page增量2(备份自page增量1以来变化的数据页) → ...

恢复的时候,工具从全量开始,依次应用page增量备份,最后回放WAL日志,得到完整的恢复点。只要链条上任何一个环节损坏或丢失,整条链就废了。

3.2 PTRACK是怎么工作的

PTRACK(Page Tracking)是openGauss提供的数据页跟踪机制。当ptrack_enable=on时,数据库会在内存里记录哪些数据页被修改,周期性地把这份“脏页位图”刷到磁盘上,一般落在数据目录下的ptrack相关目录里。

page增量备份时,gs_probackup读取PTRACK位图文件,找出变化的数据页,只备份这些页。相比全量备份,page增量的数据量通常只有全量的百分之几到十几,备份窗口大幅缩短。我实测一个700GB的库,全量要跑一个多小时(开了压缩),page增量平均只要3到5分钟。

使用PTRACK有三个前提缺一不可:

  • 必须有至少一个全量备份作为基础。
  • ptrack_enable=on。
  • 系统时钟稳定,别乱跳,时区也别随意改动,PTRACK位图依赖时间戳和LSN的对应关系。

3.3 关键参数与配置项

备份命令里常用的核心参数先列出来:

-B /data/gauss_backup # 备份目录,所有命令都要带 -i gauss1 # 实例名 -b full|page # 备份模式 -p 5432 # openGauss数据库端口 --archive # 备份期间归档WAL --threads N # 并行线程数,建议和CPU核数相关 --compress # 压缩备份数据 --log-level-console # 控制台日志级别

实例级的默认配置用set-config统一管理,这样执行备份时不用每次敲一堆重复参数:

gs_probackup set-config -B /data/gauss_backup -i gauss1 \ --compress-algorithm=zlib \ --compress-level=6 \ --archive-timeout=300 \ --retention-redundancy=2 \ --retention-window=14
  • --compress-algorithm/--compress-level:压缩算法和级别,zlib的6级在压缩率和速度之间比较均衡。
  • --archive-timeout:WAL归档超时时间,单位秒,默认就是300。
  • --retention-redundancy:最少保留多少个备份集。
  • --retention-window:保留多少天以内的备份。

这些配置会在执行备份时自动生效,不用每次手动拼参数。

4. 备份实操:从全量到增量

4.1 全量备份实操

第一次做备份必须先跑全量。全量备份的产物是后续所有增量的基础,所以完成后一定要做校验。命令如下:

su - omm gs_probackup backup -B /data/gauss_backup -i gauss1 -b full -p 5432 --archive --threads 4 --compress

我一般固定加--compress,生产库普遍比较大,压缩能省不少磁盘空间。--threads根据机器核数来,4线程在大多数环境已经够用,SSD盘可以放到8,机械盘建议别超过4,否则备份期间IO抢占业务。

备份过程会输出进度日志,结束之后用show命令看备份集列表:

gs_probackup show -B /data/gauss_backup -i gauss1

输出大概长这样:

Instance: gauss1 BACKUP INFO: ID | Mode | Status | Time | WAL | 大小 ----------|------|--------|----------------------|----------------|---------- ABC123456 | full | OK | 2024-05-20 14:00:00 | 000000010000... | 23 GB

看到Status是OK,并且有一行Mode为full的记录,说明全量备份建立成功。

4.2 增量备份实操

全量完成后,日常的增量命令很简单,把模式换成page就行:

gs_probackup backup -B /data/gauss_backup -i gauss1 -b page -p 5432 --archive --threads 4 --compress

这个命令会基于最近的全量+page链,把自上次备份以来变化的数据页备份一遍。对大多数业务场景,快的话几秒钟,慢的话几分钟就跑完了。增量备份的价值就在这里——可以做到每小时甚至每半小时备份一次,对生产几乎无感。

有一点要特别注意:page增量备份依赖上一次备份成功完成。如果上一次page增量跑到一半失败了,下一次备份会把这次的失败点当作基准,恢复时就会出问题。所以每次备份完,养成看一眼退出码的习惯,或者把备份日志接到监控告警里。

4.3 备份校验与查看

备份做了不等于一定能恢复。我强烈建议每次备份完成后跑一遍校验:

gs_probackup validate -B /data/gauss_backup -i gauss1

这条命令会检查备份链的完整性,包括数据文件块是否有缺失、WAL是否齐全。输出里没有ERROR,才说明这个备份链是可用的。

日常巡检用带-R参数的show查看整个恢复链状态:

gs_probackup show -B /data/gauss_backup -i gauss1 -R

-R会展示每个备份和WAL的对应关系,以及当前能恢复到什么位置。这条命令我每次巡检都会跑,一眼就能看出链条有没有断。

4.4 备份调度与保留策略

生产环境的备份不能靠手工点命令。用crontab做定时任务,建议的策略是:

  • 数据量不大(几百GB以内):每天凌晨1点全量,每小时page增量。
  • 数据量大(TB级):每周日全量,每天凌晨plus每小时page增量。

crontab里这么写:

0 1 * * * /home/omm/scripts/full_backup.sh >> /home/omm/scripts/backup.log 2>&1 0 * * * * /home/omm/scripts/page_backup.sh >> /home/omm/scripts/backup.log 2>&1

脚本内容核心就是前面那两条gs_probackup命令,加上日志时间戳。脚本记得用su - omm -c方式执行,别用root跑。

保留策略由set-config里配的retention参数控制,执行备份时会自动清理过期备份。手动清理用:

gs_probackup delete -B /data/gauss_backup -i gauss1 --delete-expired

注意:删除备份时要格外小心,别把当前增量链的base全量删掉。如果--retention-redundancy配得太小,可能出现所有page增量都依赖的全量被清理,整条链失效的惨案。我的经验是redundancy至少配2,也就是保留最近两个全量周期,宁可多占点磁盘,也别让自己无备份可用。

5. 恢复实操:把数据还原出来

5.1 恢复前的准备工作

恢复这件事我只想说一句:先演练,再实战。真要出事了再翻文档,大概率手忙脚乱。下面的过程建议在测试环境完整跑一遍,把命令和步骤刻进肌肉记忆。

恢复前确认几件事:

  • 备份目录可访问,show能看到所有备份集且状态正常。
  • WAL归档文件齐全,尤其做PITR的时候。
  • 目标数据目录已停止旧实例,或者是个全新空目录。
  • 磁盘空间足够,恢复出来的数据加上WAL,通常需要原库1.5倍以上的空间。

恢复的目标目录不要和旧数据目录混用。建议用独立路径,比如/data/omm/data_restore。

5.2 恢复到当前一致点

最简单的场景:把数据恢复到最近一次备份的一致性状态,也就是最近一次成功的page增量备份加上WAL回放到该点。

gs_probackup restore -B /data/gauss_backup -i gauss1 -D /data/omm/data_restore

这个命令默认会找最近有效的备份链,把全量加所有page增量还原到目标目录。恢复完成后,检查目标目录文件权限:

chown -R omm:dbgrp /data/omm/data_restore

然后用临时端口启动实例,验证数据:

gs_ctl start -D /data/omm/data_restore -p 15432 gsql -d postgres -p 15432 -r

正常的话直接查表、查数据、查对象元数据,确认没问题再切业务。注意:恢复出来的实例和原实例在同一个环境里,端口、IP都冲突,启动前先把postgresql.conf里的端口改掉,或者干脆先只做验证,不接入任何应用。

5.3 PITR恢复到指定时间点

这是gs_probackup最值钱的功能。业务误删数据、跑了错误的UPDATE、DROP了表,都可以利用WAL回放到事故之前。

gs_probackup restore -B /data/gauss_backup -i gauss1 -D /data/omm/data_restore \ --recovery-target-time '2024-05-21 03:15:00+08' \ --recovery-target-inclusive=true

参数说明:

  • --recovery-target-time:恢复到哪个时间点,格式带时区。openGauss对+08这种写法兼容比较好,直接用'2024-05-21 03:15:00'多数情况也能识别。
  • --recovery-target-inclusive:是否包含目标时间点那一刻的数据,默认true。

恢复完成后,目标数据目录里会生成recovery.conf或recovery.signal之类的恢复标志文件,数据库启动时自动进入恢复状态,回放WAL到指定目标,然后转为可读写。

openGauss这里有个细节:PITR回放依赖从备份点到目标时间点之间的WAL。如果之前配置的是本地cp归档方式,需要把这些WAL手动拷到恢复实例的pg_xlog(新版本也可能是pg_wal,按实际目录名为准)目录下:

mkdir -p /data/omm/data_restore/pg_xlog cp /data/wal_archive/* /data/omm/data_restore/pg_xlog/

如果不拷贝,实例启动后回放到备份点就会停住,恢复的目标时间点根本达不到,而且日志里会一直报找不到WAL文件的错误。

5.4 恢复后的完整性验证

恢复完成后别急着切业务,先做一轮验证:

  1. 用gs_ctl start把实例拉起来,观察pg_log下的启动日志,确认没有ERROR。
  2. 检查关键表的数据量,和业务侧对一下行数。
  3. 抽样验证最近的数据,比如今天凌晨产生的订单、日志是否都在。
  4. 检查存储过程和函数是否存在、能否正常执行。PITR恢复会回到历史时间点,之后建立的存储过程、函数自然也不存在,应用接入前要和开发确认一遍。
  5. 如果恢复了用户和角色,用gsql逐一验证登录权限。

经验之谈:PITR有个很容易被忽略的坑——业务一直在建索引、加字段、改存储过程的话,恢复到老时间点之后,这些结构变更也不存在。这不是备份工具的缺陷,是PITR本身的语义。所以恢复之后通常还要配合一份逻辑导出的元数据来补做结构迁移,这就是为什么我建议生产环境同时保留gs_dump的逻辑备份做补充。

6. 常见问题与排错实录

6.1 WAL归档不生效导致备份失败

报错场景:执行backup --archive时报ERROR: WAL archiving is not enabled。

先确认archive_mode确实是on,注意不是reload,要重启数据库。再确认archive_command有没有语法错误,路径目录是否已创建、属主是否正确。openGauss有些场景下postgresql.conf和postgresql.conf.helper都会参与配置加载,改错位置会被覆盖。修改之后用数据库命令复核:

show archive_mode; show archive_command;

看到实际生效的值和你预期一致,再重新跑备份。

6.2 PTRACK报错与处理

page增量备份时报ptrack is not enabled或者找不到ptrack文件,多半是两个原因:一是ptrack_enable没开,二是刚开启后还没来得及生成PTRACK位图文件。

解决办法:开启ptrack_enable后先跑一次全量备份,再跑page增量。第一次page增量会基于全量生成位图,之后才能正常做增量。如果ptrack目录下文件异常,比如磁盘故障导致位图损坏,gs_probackup会报读取失败。不要想着修复位图,重新做一次全量重建基础更省事。

6.3 session unused timeout导致连接中断

如果你用gsql连上去执行\l或跑耗时比较久的操作,终端突然打出这样一串:

WARNING: session unused timeout. FATAL: terminating connection due to session unused timeout

说明openGauss的session_timeout参数把空闲会话杀掉了。这个问题在备份和运维场景里尤其讨厌——gs_probackup备份时会在数据库内建立短连接,正常情况下没问题;但如果你在一个交互会话里手动触发备份,或者某些工具连接保持时间太长,就可能被杀掉,备份任务莫名其妙中断。

解决方法:

gs_guc set -D /data/omm/data -c "session_timeout = 0"

改完reload或者重启生效。生产环境如果不想全局关掉,也可以只在备份工具的连接层面做配置,但最简单可靠的就是调成0。这个参数直接影响备份和运维操作的稳定性,我建议一律置0。

6.4 恢复后实例无法启动

恢复完了,gs_ctl start报错,常见就几个原因:

  1. 权限不对,恢复目录属主不是omm。用chown -R omm:dbgrp解决。
  2. 目标目录里有旧的postmaster.pid文件残留,或者端口被占用。删除pid文件,换个端口启动。
  3. recovery.conf配置了不合理的恢复目标,或者恢复目标不可达(WAL缺失),实例会一直处于恢复状态。看日志,缺哪个WAL就去归档目录找。
  4. postgresql.conf、pg_hba.conf等配置文件和恢复实例不匹配。比如原库配置了很大的shared_buffers,恢复目标机器内存不够,起不来。

排查方法就一句话:看日志。openGauss的日志在数据目录下的pg_log里,启动失败的具体原因都会记在最新的日志文件里,照着解决就完事了。

6.5 磁盘空间与性能问题

备份目录被写满是最容易出事故的。全量加增量加WAL归档,数据膨胀速度可能超预期。我建议:

  • 备份目录和数据库目录分开挂载。
  • 定期清理过期备份,保留策略配好之后别频繁改。
  • 开启压缩,zlib压缩率一般能到2到5倍。
  • 监控备份目录使用率,超过80%触发告警。

性能方面,--threads开太高会导致备份期间IO抢占业务。经验值:数据盘是SSD可以开4到8,机械盘建议2到4。备份尽量安排在业务低峰期,定时任务已经是凌晨跑了,就别再叠个全量备份到白天高峰。

问题常见原因处理动作
WAL archiving is not enabledarchive_mode未生效重启数据库,复核参数
ptrack is not enabledptrack_enable关闭开启后先做全量
session unused timeoutsession_timeout过小置0并reload
恢复后起不来权限/端口/WAL缺失看pg_log逐项排查
备份目录写满保留策略未配置压缩+定时清理+告警

最后说点我自己的体会。

备份这条链路,工具选型只占一小半,真正决定生死的是日常的验证和演练。gs_probackup用起来并不难,难的是给它配一套可持续运行的体系:定时、监控、保留策略、定期恢复演练,一个都不能少。我见过太多环境装了工具、跑了备份、但从没真正恢复过,等出事了才发现备份集是坏的、WAL不齐、权限不对。

我的建议很简单:每次备份结束自动validate,每个季度在测试环境做一次完整的全量+增量恢复演练,把恢复步骤写成文档、标好责任人。真到了灾难那天,这套动作能让你从容地把数据救回来。另外,恢复演练时多试试PITR,别只恢复最近一致点——真正容易出问题的,恰恰是那个你不太敢碰的时间点回放。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询