一、 简介
pg_rman 是一个 PostgreSQL 的在线备份和恢复工具,提供类似 pg_dump 的简单性来进行物理备份。系统为每个数据库集群维护一个备份目录,支持全量、增量和仅归档等多种备份模式。它与 PostgreSQL 内置的备份机制(pg_start_backup() 和 pg_stop_backup())集成,同时增加了压缩、增量备份和自动保留策略等功能。 README.md:3-8
主要功能包括:
- 整个数据库集群(包括表空间)的在线备份
- 时间点恢复(PITR)功能
- 增量备份支持以最小化存储需求
- 带版本控制的备份目录管理
- 与存储快照系统集成
- 备用服务器备份支持
备份目录结构
cpp
backup_path/
├── pg_rman.ini # 全局配置
├── system_identifier # 数据库集群标识符
└── YYYY-MM-DD/ # 基于日期的目录
└── HH-MM-SS/ # 基于时间的备份目录
├── backup.ini # 备份元数据
├── database/ # 数据库文件
├── arclog/ # 归档 WAL 文件
└── srvlog/ # 服务器日志文件
二、 学习路线
第一阶段:理解整体架构和入口
- 从主入口开始 -
pg_rman.c的main()函数- 理解命令行参数解析和配置加载流程
- 掌握命令分发机制 pg_rman.c:213-246
- 核心数据结构 -
pg_rman.h- 重点理解
pgBackup、pgFile、pgBackupOption结构体 - 熟悉各种枚举类型(BackupStatus、BackupMode等) pg_rman.h:146-182
- 重点理解
第二阶段:核心功能模块
- 备份功能 -
backup.c中的do_backup()函数- 理解全量备份、增量备份的实现差异
- 学习与PostgreSQL的
pg_start_backup()/pg_stop_backup()集成
- 恢复功能 -
restore.c中的do_restore()函数- 掌握时间点恢复的实现机制
- 理解recovery配置文件的生成逻辑
- 目录管理 -
catalog.c- 学习备份元数据的存储和检索
- 理解备份目录的层次结构
第三阶段:底层实现
- 文件系统操作 -
dir.c和data.c- 理解文件遍历、复制和校验机制
- 学习增量备份的文件变更检测
- WAL处理 -
xlog.c- 理解WAL文件的解析和处理
- 学习时间线和LSN的概念应用 xlog.c:36-72
- 实用工具 -
util.c和parray.c- 学习通用工具函数和动态数组实现
第四阶段:高级特性
- 压缩和存储快照
- 理解数据压缩的实现
- 学习外部存储快照脚本的集成
- 备用服务器备份
- 理解从备用服务器进行备份的特殊处理
- 学习复制环境下的备份策略
三、 整体架构

核心模块文件
| 文件 | 功能描述 | 主要函数 |
|---|---|---|
pg_rman.c |
主入口和命令分发 | main(), pgut_help() pg_rman.c:108-246 |
pg_rman.h |
核心数据结构和声明 | pgBackup, pgFile, pgBackupOption pg_rman.h:146-195 |
backup.c |
备份操作实现 | do_backup(), do_backup_database() backup.c:821-888 |
restore.c |
恢复操作实现 | do_restore(), restore_database() restore.c:26-29 |
catalog.c |
备份目录管理 | catalog_get_backup_list(), catalog_lock() catalog.c:727-759 |
init.c |
初始化备份目录 | do_init() init.c:32-63 |
工具模块文件
| 文件 | 功能描述 | 主要函数 |
|---|---|---|
dir.c |
文件系统操作 | dir_list_file(), dir_read_file_list() dir.c:547-617 |
data.c |
数据文件处理 | backup_data_file(), restore_data_file() |
xlog.c |
WAL文件处理 | xlog_is_complete_wal() pg_rman.h:331-332 |
util.c |
通用工具函数 | time2iso(), status2str() |
parray.c |
动态数组实现 | parray_new(), parray_append() |
模块功能详解
1. 命令处理模块 (pg_rman.c)
负责程序的入口点和命令分发:
- 解析命令行参数和配置文件
- 验证参数有效性
- 分发到具体的操作处理函数 pg_rman.c:64-103
2. 备份操作模块 (backup.c)
实现完整的备份流程:
- 数据库文件备份(
do_backup_database()) - 归档WAL备份(
do_backup_arclog()) - 服务器日志备份(
do_backup_srvlog()) backup.c:736-818 - 支持全量、增量和仅归档备份模式
3. 恢复操作模块 (restore.c)
处理数据库恢复操作:
- 基础备份恢复
- 增量备份应用
- 时间点恢复配置
- 恢复目标参数处理 restore.c:21-29
4. 目录管理模块 (catalog.c)
管理备份元数据和目录结构:
- 备份目录锁定机制
- 备份列表管理
- 备份元数据读写
- 系统标识符验证 catalog.c:727-759
5. 文件系统模块 (dir.c)
提供底层文件操作:
- 文件列表生成和解析
- 文件复制和校验
- 目录创建和管理
- 文件属性处理 dir.c:547-617
6. 初始化模块 (init.c)
处理备份目录初始化:
- 创建备份目录结构
- 解析PostgreSQL配置
- 生成系统标识符文件
- 创建配置文件 init.c:32-63
四、 主入口函数
pg_rman的入口点位于pg_rman.c的main()函数,采用典型的命令分发模式 pg_rman.c:108-246 。
-
配置初始化 :调用
catalog_init_config(¤t)初始化当前备份配置 pg_rman.c:121-122 -
选项解析 :使用
pgut_getopt()解析命令行参数,该函数依赖options数组定义的选项映射 pg_rman.c:64-103 -
必需参数验证 :确保
backup_path已指定,这是所有操作的必需参数 pg_rman.c:127-131 -
配置文件加载 :从
pg_rman.ini读取默认配置 pg_rman.c:166-181 -
路径验证:所有路径必须是绝对路径 pg_rman.c:183-203
-
命令分发:根据命令类型调用相应的处理函数 pg_rman.c:214-244

五、 核心数据结构
1. pgBackup结构
表示单个备份条目的核心结构 pg_rman.h:146-182 :
cpp
typedef struct pgBackup
{
BackupMode backup_mode; // 备份模式
BackupStatus status; // 备份状态
TimeLineID tli; // 时间线ID
XLogRecPtr start_lsn; // 起始LSN
XLogRecPtr stop_lsn; // 结束LSN
time_t start_time; // 开始时间
time_t end_time; // 结束时间
// ... 其他字段
} pgBackup;
2. pgFile结构
表示备份中的单个文件 pg_rman.h:69-83 :
cpp
typedef struct pgFile
{
time_t mtime; // 最后修改时间
mode_t mode; // 文件权限
size_t size; // 文件大小
size_t read_size; // 读取大小
size_t write_size; // 写入大小
pg_crc32c crc; // CRC校验值
char *linked; // 链接文件路径
bool is_datafile; // 是否为数据文件
char path[1]; // 文件路径
} pgFile;
3. pgBackupOption结构
备份配置选项结构 pg_rman.h:184-195 :
cpp
typedef struct pgBackupOption
{
bool smooth_checkpoint; // 平滑检查点
int keep_arclog_files; // 保留归档文件数量
int keep_arclog_days; // 保留归档天数
int keep_srvlog_files; // 保留服务日志数量
int keep_srvlog_days; // 保留服务日志天数
int keep_data_generations; // 保留数据备份代数
int keep_data_days; // 保留数据天数
char *standby_host; // 备用主机
char *standby_port; // 备用端口
} pgBackupOption;
4. 枚举类型
BackupStatus枚举跟踪备份生命周期 pg_rman.h:121-131 :
BACKUP_STATUS_INVALID- 无效状态BACKUP_STATUS_OK- 备份成功BACKUP_STATUS_RUNNING- 正在运行BACKUP_STATUS_ERROR- 发生错误BACKUP_STATUS_DELETING- 正在删除BACKUP_STATUS_DELETED- 已删除BACKUP_STATUS_DONE- 完成BACKUP_STATUS_CORRUPT- 损坏
BackupMode枚举定义备份类型 pg_rman.h:133-139 :
BACKUP_MODE_INVALID- 无效模式BACKUP_MODE_ARCHIVE- 仅归档备份BACKUP_MODE_INCREMENTAL- 增量备份BACKUP_MODE_FULL- 全量备份
5. 全局配置变量
系统使用多个全局变量存储配置 pg_rman.c:22-56 :
- 路径配置 :
backup_path、pgdata、arclog_path、srvlog_path、pgconf_path - 通用配置 :
verbose、progress、check - 当前备份 :
current(pgBackup结构)
6. 选项定义数组
options数组定义了命令行参数到配置变量的映射 pg_rman.c:64-103 ,包括:
- 目录选项 :
-D、-A、-B、-S、-G - 通用选项 :
-v、-P、-c - 备份选项 :
-b、-s、-Z、-C、-F - 保留策略选项 :
--keep-*系列 - 恢复选项 :
--recovery-target-*系列