---
title: openGauss数据库源码解析系列文章——备份恢复机制：openGauss增量备份技术（下）-官方技术文章-鲲鹏社区
description: 上篇图文，我们分享了安全管理源码解析—备份恢复机制：openGauss增量备份技术的部分内容，本篇将继续介绍备份恢复机制：openGauss增量备份技术（下）。
keywords: Gauss,数据库源码解,析系列文章,备份恢复机制,增量备份技术,官方技术文章,鲲鹏社区,主要文件
url: https://www.hikunpeng.com/developer/techArticles/20251201-4?envFlag=1
section: (其他)
---

# openGauss数据库源码解析系列文章——备份恢复机制：openGauss增量备份技术（下）-官方技术文章-鲲鹏社区

URL: https://www.hikunpeng.com/developer/techArticles/20251201-4?envFlag=1
描述: 上篇图文，我们分享了安全管理源码解析—备份恢复机制：openGauss增量备份技术的部分内容，本篇将继续介绍备份恢复机制：openGauss增量备份技术（下）。
关键词: Gauss,数据库源码解,析系列文章,备份恢复机制,增量备份技术,官方技术文章,鲲鹏社区,主要文件

官方技术文章 [了解详情](https://www.hikunpeng.com/zh/developer/techArticles)

openGauss数据库源码解析系列文章——备份恢复机制：openGauss增量备份技术（下）

openGauss数据库源码解析系列文章——备份恢复机制：openGauss增量备份技术（下）

openGauss

发表于 2025/12/01

0

### 10.2.2 gs_probackup主要文件

增量备份与全量备份相比，最重要的就是对备份数据和元数据的管理。备份数据主要通过目录来区分，元数据主要通过backup.control文件来管理。gs_probackup的主要目录文件如下。

（1） backup_path：备份根目录，所有实例的备份文件都存放在这个目录下。

（2） backup_path/backups/：数据根目录，所有实例的数据文件都存放在这个目录下。

（3） backup_path/wal/：日志根目录，所有实例的日志文件都存放在这个目录下。

（4） backup_path/backups/instance_name：实例的数据根目录，一个实例的所有数据都存放在这个目录下。实例备份的配置参数文件pg_probackup.conf存放在这个目录下。

（5） backup_path/wal/instance_name：实例的日志根目录，一个实例的所有WAL日志都存放在这个目录下。

（6） backup_path/backups/instance_name/backupID：一个具体备份的数据目录，一次备份的数据存放在这个backupID下，backupID是用这次备份的开始时间start_time进行36位编码生成的，即backupID等于base36enc(backup->start_time)，base36enc是一个36位编码的转换函数。备份元数据控制文件backup.control就存放在这个目录下。

gs_probackup备份元数据文件backup.control内容参照pgBackupWriteControl函数写的内容，也可以通过gs_probackup show -B backup-path查看备份元数据信息。

文件内容具体如下：

### （1） #Configuration 配置小节。

① backup-mode = "PAGE"，"PTRACK"，"DELTA"，"FULL"。当前只支持FULL和PTRACK。

② stream = true 或者 false，表示是否流复制备份模式。

③ compress-alg = none，zlib或者pglz。

④ compress-level = 0到9，级别越大，压缩率越高。

⑤ from-replica = true或者 false，true表示是从备机备份数据，false表示从主机备份数据。通过执行pg_is_in_recovery SQL函数来判断主备机。

### （2） #Compatibility 兼容性小节。

① block-size = 数据库数据文件数据页的大小。

② xlog-block-size = 数据库日志文件日志页的大小。

③ checksum-version = CRC校验算法的版本号，数值类型。global/pg_control文件中的data_checksum_version。

④ program-version = gs_probackup工具版本号，字符串类型。

⑤ server-version = 数据库服务器版本号，字符串类型。

### （3） #Result backup info。

① timelineid = 备份时数据库的时间线。

② start-lsn = 备份开始时的XLOG位置。

③ stop-lsn = 备份结束时的XLOG位置。

④ start-time = 备份开始时的时间（备份状态设置为BACKUP_STATUS_RUNNING的时间）。

⑤ merge-time = 备份合并的时间，如果没有合并，则为0。

⑥ end-time = 备份结束时的时间（或者是备份非正常终止的时间）。

⑦ recovery-xid = 这个备份能够恢复到的最早事务ID。

⑧ recovery-time = 这个备份能够恢复到的最早时间点。

⑨ expire-time = 备份过期的时间。

⑩ merge-dest-id = 备份能合并到的备份ID。

⑪ data-bytes = 备份的数据大小，这个是原始大小。

⑫ wal-bytes = 备份的WAL日志文件大小。

⑬ uncompressed-bytes = 备份的数据未压缩大小，不包括WAL文件。

⑭ pgdata-bytes = 备份时数据库的数据目录PGDATA的大小。

⑮ status = 备份状态 "UNKNOWN"，"OK"，"ERROR"，"RUNNING"，"MERGING"，"MERGED"，"DELETING"，"DELETED"，"DONE"，"ORPHAN"，"CORRUPT"。

⑯ parent-backup-id = 父备份ID，只有在增量备份的时候有效。

⑰ primary_conninfo = 连接数据库的信息。replication，dbname，fallback_application_name，password等连接信息。

⑱ external-dirs = 备份的外部地址列表。

⑲ note = 备份的注释信息。

⑳ content-crc = 整个备份数据的CRC校验值。backup_content.control文件的CRC值。backup_content.control文件存放了备份文件的信息。

### 10.2.3 gs_probackup备份恢复流程

gs_probackup工具在备份之前需要先进行备份目录初始化，然后进行数据库实例的全量备份，在全量备份的基础上才能进行增量备份。类似地，增量恢复也必须以某个全量备份为基础进行恢复。gs_probackup除了支持本地备份外，也支持通过SSH进行远程备份。下面是几个主要的步骤。

### （1） 初始化备份目录。在指定的目录下创建backups/和wal/子目录，分别用于存放备份文件和WAL文件，代码如下：

```sql
gs_probackup init -B backup_dir
```

### （2） 初始化一个数据库实例的备份，代码如下：

```sql
gs_probackup add-instance -B backup_dir -D data_dir --instance instance_name [remote_options]
```

### （3） 创建指定实例的备份。在进行增量备份之前，必须至少创建一次全量备份。全量还是增量由-b backup_mode参数控制，FULL表示创建全量备份，PTRACK表示创建PTRACK增量备份，代码如下：

```sql
gs_probackup backup -B backup_dir --instance instance_name -b backup_mode
```

### （4） 从指定实例的备份中恢复数据，代码如下：

```sql
gs_probackup restore -B backup_dir --instance instance_name -i backup_id
```

如果进行远程备份和恢复，需要初始化备份目录和初始化一个数据库实例的备份，第一步、第二步和本地备份恢复是相同的，执行上文中的（1）和（2）即可。但第三步和第四步需要使用SSH的远程连接信息进行备份和恢复，步骤如下所示。

### （1） 远程备份，代码如下：

```sql
gs_probackup backup -B backup_dir -b FULL --stream --instance=instance_name --remote-user=remote_user --remote-host=ip --remote-port=remote_port -d db -p port -U user
```

### （2） 远程恢复，代码如下：

```sql
gs_probackup restore -B backup_dir --instance=instance_name --remote-user=remote_user --remote-host=ip --remote-port=remote_port --incremental-mode=checksum
```

下面介绍每个处理函数的详细实现。

### （1） init命令的处理函数是do_init，在do_init函数中。

① 首先检查命令行输入的备份路径backup_dir是否为空目录，要求必须为空目录。如果backup_dir不存在，则创建。

② 在backup_dir下创建backups子目录，创建wal子目录。

### （2） add-instance的处理函数为do_add_instance，在do_add_instance处理函数中。

① 创建backup_dir/backups/instance_name子目录，创建backup_dir/wal/instance_name子目录。

② 获取实例备份参数信息，包括system_identifier，xlog_seg_size，remote.host，remote.proto，remote.port，remote.path，remote.user，remote.ssh_options，remote.ssh_config等，通过调用函数do_set_config把这些实例备份信息写到backup_path/backups/instance_name/pg_probackup.conf配置文件中。

### （3） backup的处理函数为do_backup，do_backup根据参数backup_mode是FULL还是PTRACK进行全量或者增量备份。全量备份和增量备份基本流程是一样的，唯一的区别是全量备份拷贝全部数据文件，增量备份只拷贝自上次备份以来的脏数据页。函数的处理流程如下。

① 调用pgNodeInit初始化备份数据库服务器节点的信息。

② 设置备份状态为BACKUP_STATUS_RUNNING和其他备份元数据，包括备份时间、当前版本、压缩算法、压缩级别和外部目录地址。

③ 调用pgBackupCreateDir创建备份路径，备份路径由pgBackupGetPath构造，路径为backup_dir/backups/instance_name/base36enc(backup->start_time)，同时创建外部目录的备份地址，地址为backup_dir/backups/instance_name/ extern_direc。

④ 备份元数据写入到backup.control控制文件中。

⑤ 调用pgdata_basic_setup创建到数据库服务器的连接，检查校验备份工具的block_size、wal_block_size，checksum_version等和数据库服务器的版本是兼容的。调用check_system_identifiers校验系统标识符system_identifier是一致的。检查数据库服务器的ptrack版本是兼容的，并且开关是打开的。

⑥ 调用add_note把备份描述信息添加到备份元数据中。

⑦ 调用do_backup_instance进行数据库实例数据备份。

⑧ 更新备份元数据中的备份结束时间，备份状态为BACKUP_STATUS_DONE。更新备份的留存策略ttl或者expire_time。

⑨ 如果需要校验备份，则调用pgBackupValidate对备份数据进行校验。

⑩ 最后如果需要删除过期的备份或者合并备份，则调用do_retention把过期的备份删除。

### （4） restore的处理函数为do_restore_or_validate，函数的处理流程如下。

① 检查如果data目录不为空，看是否为增量恢复，并且当前的增量和路径中存在的数据是否兼容。首先检查两者的system_identifier标识符是否一致，如果不一致，则恢复失败。然后检查目录中是否有备份标签文件，如果存在，则恢复失败。

② 调用catalog_get_backup_list获取实例的所有备份。在catalog_get_backup_list函数中，遍历实例所有的backup.control文件，获取所有backup_id，并且根据backup_id排序。所有增量备份和他们的祖先连接起来，备份元数据有一个parent_backup，指向的就是父备份ID。

```sql
/* Link incremental backups with their ancestors.*/
for (i = 0; i < parray_num(backups); i++)
{
pgBackup   *curr = parray_get(backups, i);
pgBackup  **ancestor;
pgBackup key;
if (curr->backup_mode == BACKUP_MODE_FULL)
continue;
key.start_time = curr->parent_backup;  
ancestor = (pgBackup **) parray_bsearch(backups, &key,
pgBackupCompareIdDesc); 
if (ancestor) 
curr->parent_backup_link = *ancestor;
}
```

③ 在备份列表中，查找满足恢复条件的备份。如果指定了target_backup_id则根据backup_id进行匹配。如果指定了pgRecoveryTarget，则根据pgRecoveryTarget进行匹配，判断函数为satisfy_recovery_target。

④ 如果找到的备份是全量备份，那么当前backup_id就是满足要求的。如果找到的备份是增量备份，需要遍历整个增量备份链表查找之前所有备份都是正常的。

⑤ 检查表空间映射是正常的。

⑥ 如果是INCR_LSN恢复，恢复链中的恢复位置。

⑦ 如果恢复前需要验证文件正确性，则调用pgBackupValidate和validate_wal验证数据文件和日志文件正确性。

⑧ 调用restore_chain根据备份链进行恢复。

⑨ 根据传入的恢复参数调用create_recovery_conf创建recovery.conf恢复文件。整个恢复结束。

其他的一些流程处理如下。

### （5） help的help_pg_probackup和help_command，这两个函数的处理都在help.cpp中。

① help_pg_probackup命令没有输入参数，就是打印整个工具的命令行使用帮助信息。

② help_command(char *command)有一个输入参数command，根据command参数指定的子命令分别调用相应子命令的帮助处理函数。

### （6） del-instance删除实例的处理函数为do_delete_instance，在do_delete_instance处理函数中。

① 调用catalog_get_backup_list获取实例。backup_dir/backups/instance_name子目录下的所有数据备份。遍历删除这些数据备份。

② 删除backup_dir/wal/instance_name子目录下的所有WAL日志文件。

③ 删除实例备份配置文件backup_dir/backups/instance_name/pg_probackup.conf。

④ 删除实例backup_dir/backups/instance_name子目录本身，删除backup_path/wal/instance_name子目录本身。

### （7） 设置实例备份配置文件backup_dir/backups/instance_name/pg_probackup.conf的处理函数为do_set_config，do_set_config的根据解析的命令行参数，以name = value的形式把新值设置到配置文件中。pg_probackup.conf是文本文件，为了避免文件写坏，先把内容写到一个pg_probackup.conf.tmp临时文件，最后再重命名为正式文件。

### （8） 显示实例备份配置文件backup_dir/backups/instance_name/pg_probackup.conf的处理函数为do_show_config，do_show_config函数根据命令行要求是json还是普通格式把参数以name=value的方式显示出来。

### 10.2.4 redo日志增量备份恢复流程

在gs_basebackup或者gs_probackup工具全量备份的基础上，再加上数据库的redo日志，就可以实现基于redo日志的增量备份和恢复。如果把所有redo日志都进行归档备份，那么数据库就可以实现基于时间点的恢复PITR，把数据库恢复到基于全量备份以来的任意时间点。当前openGauss没有提供工具进行redo日志的备份，应用可以通过配置归档命令的方式或者自己拷贝的方式把redo日志拷贝到备份目录进行备份。恢复时只需要一个全量备份加上redo日志就可以进行数据库的恢复。这个过程不涉及代码逻辑，所以不再进行详细描述。

### 10.3 小结

物理备份是通过拷贝文件方式进行的备份，备份文件主要分为数据文件和XLOG文件，为了保证备份可用，需要保证XLOG文件的范围覆盖了备份数据的整个过程。因为在拷贝数据的过程中，这些数据页可能被正在执行的在线事务进行修改，这些修改只能通过XLOG恢复保证数据的一致性。增量备份只拷贝上次备份以来的数据脏页，能减少备份的数据量，提高备份效率，但增量备份只能恢复到备份的某个时间点，无法恢复到任意时间点，任意时间点的恢复只能用全量备份和全量XLOG日志的方式进行实现。
