增量备份与基于时间点的恢复(PITR)是数据库高可用架构中的关键能力。在 PostgreSQL 生态中,虽然pg_probackup等工具久负盛名,但其对新版本的支持可能滞后。从PostgreSQL 17开始,官方也提供了内置的增量备份功能,但许多用户仍青睐功能更为全面的第三方工具。
经过对比测试,pgBackRest 在功能支持上更为完善,它支持PostgreSQL当前五个主版本以及最近的五个EOL版本,并完美支持增量备份与时间点恢复的结合使用。本文将详细介绍pgBackRest的配置与实战操作。
一、pgBackRest简介
pgBackRest是一款功能强大的开源备份与恢复工具,其主要特性包括:
- 多进程并行备份及恢复(支持lz4/zstd并行压缩)
- 支持本地或远程操作(通过SSH)
- 支持完整(Full)、差异(Differential)和增量(Incremental)备份
- 备份集完整性验证与数据checksum校验
- 支持基于时间点(PITR)的恢复
- 兼容S3、Azure、GCS等对象存储
- 支持表空间重映射、仓库加密等高级功能
官方项目地址:https://github.com/pgbackrest/pgbackrest
二、pgBackRest源码编译安装
注意:从v2.54版本开始,pgBackRest需要使用meson进行编译,不再支持make。
- 安装依赖包:
yum install meson make cmake gcc openssl-devel libxml2-devel lz4-devel libzstd-devel bzip2-devel libyaml-devel libssh2-devel
- 编译pgBackRest:
# su - postgres
$ mkdir -p build
$ tar zxf pgbackrest-release-2.57.0.tar.gz -C build
$ export PKG_CONFIG_PATH=/opt/pg/18/lib/pkgconfig:$PKG_CONFIG_PATH
$ meson setup build/pgbackrest build/pgbackrest-release-2.57.0
$ ninja -C build/pgbackrest
$ cp build/pgbackrest/src/pgbackrest /opt/pg/18/bin
$ chmod 755 /opt/pg/18/bin/pgbackrest
编译完成后,生成的单一二进制文件可以复制到同架构的其他生产环境中直接使用。
三、pgBackRest基本配置与使用
-
创建配置和日志目录
mkdir -p -m 770 /database1/pgbackrest/log
mkdir -p /database1/pgbackrest/conf
touch /database1/pgbackrest/conf/pgbackrest.conf
chmod 640 /database1/pgbackrest/conf/pgbackrest.conf
-
配置Stanza
Stanza定义了PostgreSQL数据库集群的备份配置。编辑配置文件/database1/pgbackrest/conf/pgbackrest.conf:
[pg18stanza]
pg1-path=/database1/data_1800
pg1-port=1800
pg1-user=backup
[global]
repo1-path=/database1/pgbackrest/repo
repo1-retention-full=2
log-path=/database1/pgbackrest/log
log-subprocess=y
-
创建备份用户并授权
在PostgreSQL中创建一个专用用户:
create user backup password ‘pgbackrest’;
grant pg_read_all_settings to backup;
grant execute on function pg_catalog.pg_create_restore_point to backup;
grant execute on function pg_catalog.pg_switch_wal to backup;
grant execute on function pg_catalog.pg_backup_start to backup;
grant execute on function pg_catalog.pg_backup_stop(boolean) to backup;
-
配置归档
修改PostgreSQL的postgresql.conf文件:
archive_mode = on
archive_command = ‘pgbackrest --config=/database1/pgbackrest/conf/pgbackrest.conf --stanza=pg18stanza archive-push %p’
可选优化:在pgBackRest配置中为归档推送指定更低的压缩级别以节省CPU。
[global:archive-push]
compress-level=3
-
创建与检查Stanza
初始化Stanza并检查配置是否正确:
$ pgbackrest --stanza=pg18stanza \
--config=/database1/pgbackrest/conf/pgbackrest.conf \
--log-level-console=info stanza-create
$ pgbackrest check \
--archive-check --archive-mode-check --archive-timeout=1m \
--stanza=pg18stanza --config=/database1/pgbackrest/conf/pgbackrest.conf \
--log-level-console=info
-
执行备份
执行一次全量备份:
$ pgbackrest backup --type=full --start-fast=y \
--stanza=pg18stanza --config=/database1/pgbackrest/conf/pgbackrest.conf \
--log-level-console=info --no-resume --annotation=source=“Sunday backup”
定期备份策略示例(Crontab):
30 06 * * 0 pgbackrest --type=full --stanza=pg18stanza backup
30 06 * * 1-6 pgbackrest --type=diff --stanza=pg18stanza backup
此策略每周日进行全备,周一至周六进行差异备份。
-
查看备份信息
$ pgbackrest info \
--stanza=pg18stanza --config=/database1/pgbackrest/conf/pgbackrest.conf \
--output=text
四、增量备份与时间点恢复实战
以下通过一个完整示例演示如何使用增量备份恢复到特定时间点。
-
准备测试数据
create table tab_pitr_recover (id int, remark varchar, up_time timestamp without time zone);
insert into tab_pitr_recover select 1, ‘test backup’, now();
-
执行全量备份
$ pgbackrest backup --type=full --start-fast=y \
--stanza=pg18stanza --config=/database1/pgbackrest/conf/pgbackrest.conf \
--log-level-console=info --no-resume
-
写入更多数据并执行增量备份
-- 写入铺底数据
insert into tab_pitr_recover select n, ‘test backup’ from generate_series(2, 10000) n;
-- 执行增量备份
$ pgbackrest backup --type=incr \
--stanza=pg18stanza --config=/database1/pgbackrest/conf/pgbackrest.conf \
--log-level-console=info
-
模拟后续数据写入并记录时间点
-- 插入ID为10001的数据,并记录其提交时间戳
insert into tab_pitr_recover select 10001, ‘test backup’, now() returning xmin, up_time;
SELECT pg_xact_commit_timestamp(‘1222539’::xid); -- 假设返回:2025-10-27 17:01:18.842333+08
-- 等待一分钟后,再插入ID为10002的数据
select pg_sleep(60);
insert into tab_pitr_recover select 10002, ‘test backup’, now();
此时表中应有10002条记录。
-
模拟故障并执行时间点恢复
假设发生数据故障,我们需要恢复到ID为10001的记录刚提交的时刻(即不包含ID为10002的记录)。
关闭数据库,清空或移走数据目录后,执行恢复命令:
$ pgbackrest restore \
--config=/database1/pgbackrest/conf/pgbackrest.conf \
--stanza=pg18stanza --repo=1 --set=20251027-165020F_20251027-165850I \
--type=time --target=“2025-10-27 17:01:18.842333” --target-action=promote \
--process-max=2 --log-level-console=info
命令说明:
--set:指定用于恢复的增量备份集。
--type=time --target:指定要恢复到的目标时间点。
--target-action=promote:达到恢复目标后,将备机提升为主机。
-
验证恢复结果
启动恢复后的数据库,检查数据:
select count(*) from tab_pitr_recover;
预期结果应为10001条,验证恢复成功。
五、高级恢复技巧:排除特定数据库
pgBackRest支持在恢复时排除特定的数据库,这在只想恢复部分业务库时非常有用。
$ pgbackrest restore \
--config=/database1/pgbackrest/conf/pgbackrest.conf \
--stanza=pg18stanza --repo=1 --set=20251027-151800F \
--type=time --target=“2025-10-27 15:25:11.472 CST” --target-action=promote \
--db-exclude=testdb --db-exclude=tempdb \
--process-max=2 --log-level-console=info
请注意:使用--db-exclude排除的数据库,在恢复完成后会在数据目录中留下空文件夹或零字节文件,需要手动连接到数据库执行DROP DATABASE命令将其彻底清理。
总结与建议
- 工具选型:对于追求功能全面、支持广泛PostgreSQL版本的 数据库备份与恢复 需求,pgBackRest是一个优秀的选择,其增量备份与PITR功能的结合非常稳健。
- 版本适配:PostgreSQL 17用户可评估其原生增量备份功能,但对于生产环境,经过广泛验证的第三方工具如pgBackRest可能提供更成熟的管理特性和更低的运维风险。
- 定期验证:无论采用何种工具,都必须定期演练备份恢复流程,确保备份的有效性和恢复流程的可靠性。
|