最近,我们与一位客户合作,他使用 pg_dump 手动备份了 800GB 的 PostgreSQL 数据库。该数据库规模迅速增长,备份与数据库本身存储在同一台服务器上。这种设置存在几个关键问题:
- 单点故障:如果服务器发生故障,数据库及其备份都会丢失。
- 没有时间点恢复:意外的数据删除无法撤消。
- 性能瓶颈:备份消耗本地存储,影响数据库性能。
为了解决这些风险,我们用 pgBackRest 替换了他们的设置,将备份转移到具有自动保留策略和支持时间点恢复 (PITR) 的专用备份服务器。
本指南将引导您在实际场景中安装、配置和测试 pgBackRest,其中备份将在专用备份服务器上配置,与数据节点本身分开。
PgBackRest 概述
pgBackRest 是由 Crunchy Data 开发的一款强大的开源 PostgreSQL 备份和恢复解决方案。它旨在满足大规模 PostgreSQL 环境的需求,注重可靠性、效率和自动化。
主要特点包括:
- 支持完整、差异和增量备份,以优化存储使用率并减少备份时间。
- 时间点恢复 (PITR) 用于在数据丢失或损坏时进行精确恢复。
- 并行处理可加快备份和恢复操作,特别是在大型数据库中。
- 集成压缩和加密,确保安全且节省空间的备份存储。
- 远程备份功能通过将备份与主数据库服务器分离来防止单点故障。
pgBackRest 备份类型
完整备份
完整备份会捕获整个 PostgreSQL 数据库集群,并包含恢复完整功能实例所需的所有文件。必须先进行完整备份,然后才能执行任何差异备份或增量备份。
差异备份
差异备份仅包含自上次完整备份以来更改的数据文件。这些备份是累积的,这意味着每个新的差异备份都存储自最近一次完整备份以来所做的所有更改。
增量备份
增量备份更细粒度,仅包含自上次备份以来发生变化的文件,无论该备份是完整备份、差异备份还是另一个增量备份。
备份策略注意事项
保留政策
保留策略决定了备份在自动清除之前存储的时间。pgBackRest 提供了灵活的保留选项:
- 基于计数的保留:保留固定数量的备份。
- 基于时间的保留:删除超过指定时间段的备份
压缩
pgBackRest 支持多种压缩算法,每种算法在速度和压缩率之间提供不同的权衡。您可以配置压缩类型和级别。较低的级别提供更快的压缩速度,但压缩体积较小;而较高的级别提供更好的压缩效果,但备份时间较长。您可以根据性能和存储需求选择压缩类型(lz4、zst 或 gz)和级别。
并行备份和恢复
pgBackRest 支持使用–process-max选项进行并行处理,以加快压缩和数据传输速度。最好将备份进程限制在可用 CPU 的 25% 左右,以避免影响数据库性能。但是,由于 PostgreSQL 集群在操作期间处于离线状态,因此恢复操作可以安全地使用所有可用 CPU。如果主机包含多个集群,则在设置恢复并行度时应考虑到这一点。适当调整process-max可以显著缩短大型数据库的备份和恢复时间。
设置
对于本指南,我们使用包含一台数据服务器和一台备份服务器的设置:
主节点(数据库服务器):
- 操作系统:RHEL 9
- PostgreSQL 版本:15
- pgBackRest 版本:2.55.1
备份节点(备份服务器):
- 操作系统:RHEL 9
- pgBackRest 版本:2.55.1
在这种配置中,备份服务器负责使用 pgBackRest 远程存储所有备份,而主节点运行 PostgreSQL 数据库。
安装 pgBackRest
在备份节点上
要设置 pgBackRest,我们首先需要添加官方 PostgreSQL 存储库,安装必要的依赖项,然后安装 pgBackRest 本身。
RHEL 的默认存储库不包含最新的 PostgreSQL 工具,因此我们首先添加官方 PostgreSQL 存储库:
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporrpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
需要 libssh2 来启用对安全加密的远程备份的支持:
sudo dnf 安装 libssh2
现在安装 pgBackRest。如果您需要其他版本,请根据需要替换版本号:
sudo dnf install -y pgbackrest-2.55.1
在数据库节点上
与备份节点上的步骤相同:
sudo dnf 安装 libssh2 sudo dnf 安装 -y pgbackrest-2.55.1
创建用户并设置 SSH 无密码访问
要使用 pgBackRest 实现远程、安全和自动备份,我们需要在备份和数据库服务器之间进行无密码 SSH 访问。
在备份节点上
我们需要一个专门的备份用户,因为以 root 身份运行备份是有风险的,不建议这样做。
sudo adduser pgbackrest
为 pgbackrest 生成 SSH 密钥。此密钥对将作为服务器之间的身份验证机制:
sudo -u pgbackrest ssh-keygen -t rsa -b 4096 -N "" -f /home/pgbackrest/.ssh/id_rsa
设置正确的 SSH 访问所有权和权限
sudo chmod 700 /home/pgbackrest /home/pgbackrest/.ssh sudo chmod 600 /home/pgbackrest/.ssh/id_rsa sudo chmod 644 /home/pgbackrest/.ssh/id_rsa.pub sudo chmod 600 /home/pgbackrest/.ssh/authorized_keys sudo chown -R pgbackrest:pgbackrest /home/pgbackrest
如果您使用 SELinux(在 RHEL 上很常见),请确保它能够识别新的 SSH 设置/
sudo restorecon -Rv /home/pgbackrest/.ssh
在数据库节点上
在数据库服务器上,切换到 postgres 用户并设置 SSH:
sudo su - postgres mkdir -p ~/.ssh && chmod 700 ~/.ssh ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
设置正确的文件权限
chmod 600 ~/.ssh/id_rsa chmod 644 /home/postgres/.ssh/id_rsa.pub chmod 600 ~/.ssh/authorized_keys chown -R postgres:postgres ~/.ssh
如果启用了 SELinux,也请在此处应用适当的上下文:
须藤restorecon -Rv /var/lib/pgsql 须藤restorecon -Rv /var/lib/pgsql/.ssh
交换 SSH 密钥并测试连接
现在,让我们确保两台服务器相互信任。
在备份节点上:
- 将 pgbackrest 公钥 (id_rsa.pub) 复制到 DB 节点的~postgres/.ssh/authorized_keys。
在数据库节点上:
- 将 postgres 公钥(id_rsa.pub)复制到备份节点的 ~pgbackrest/.ssh/authorized_keys。
现在测试:
sudo -u pgbackrest ssh postgres@<数据库节点 IP> sudo -u postgres ssh pgbackrest@<备份节点 IP>
如果成功了,那就给自己点个赞吧!你刚刚启用了安全无密码的访问。
配置pgbackrest.conf
在备份节点上
首先,创建一个用于存储备份的备份目录。我们将使用 /home/pgbackrest/backups 作为此目录。为了避免权限问题,pgbackrest 用户必须是该目录的所有者。
sudo mkdir -p /home/pgbackrest/backups sudo chown -R pgbackrest:pgbackrest /home/pgbackrest/backups
接下来,编辑 /etc/pgbackrest.conf。此文件控制备份行为、保留策略和性能设置。
[global]
repo1-path=/home/pgbackrest/backups # 本地备份路径
repo1-retention-full=7 # 保留 7 个完整备份
repo1-retention-full-type=time # 使用基于时间的过期
repo1-host-user=pgbackrest # 此主机上的 SSH 用户
log-level-console=info
log-path=/home/pgbackrest/backups
log-level-file=debug
start-fast=y # 启动更快备份
delta=y # 对更改的块使用增量逻辑
[db]
pg1-host=<DB_NODE_IP> # 远程 DB 节点 IP
pg1-host-user=postgres
pg1-port=5432
pg1-path=/var/lib/pgsql/15/data # PostgreSQL 数据目录
这里 :
- repo1-path指定存储所有备份的备份存储库位置。
- retention-full=7表示将保留最近 7 个完整备份的滚动快照。超过此限制的旧备份将被自动删除。您可以根据备份保留策略调整此设置。
- delta=y启用增量备份,这意味着只复制自上次备份以来的更改,而不是复制整个数据集。
- start-fast=y 确保备份过程立即启动,不会出现不必要的延迟。
- pg1-host 是 PostgreSQL 服务器的 IP 地址或主机名。
- pg1-path 指的是数据库服务器上的实际 PostgreSQL 数据目录。
- pg1-host-user 是数据库服务器上具有 SSH 访问权限的用户,用于远程运行备份。
备份会占用大量空间,因此压缩至关重要。pgBackRest 支持多种压缩类型。我建议使用压缩级别 3 的 ZST,以便在速度和压缩率之间取得良好的平衡。要启用此功能,请在 pgbackrest.conf 中的 [global] 部分下添加以下设置:
压缩类型=zst 压缩级别=3
pgBackRest 将在恢复期间自动解压缩数据。
在数据库节点上
在 PostgreSQL 节点上,你需要告诉 pgBackRest 如何连接到备份服务器以及本地 PostgreSQL 数据的存储位置。打开 /etc/pgbackrest.conf 并进行如下编辑:
[global]
repo1-host=<BACKUP_NODE_IP> # 远程 repo 主机
repo1-host-user=pgbackrest
log-level-console=info
[db]
pg1-path=/var/lib/pgsql/15/data # 本地 PostgreSQL 数据路径
这会告诉 pgBackRest 在需要时联系远程备份主机,并定义本地数据库文件所在的位置。
接下来,您需要指示 PostgreSQL 开始归档其 WAL 文件,并定义在恢复期间如何还原它们。打开 postgresql.conf 并设置以下内容:
archive_mode = on
archive_command = 'pgbackrest --stanza=db archive-push %p'
restore_command = 'pgbackrest --stanza=db archive-get %f "%p"'
- archive_mode = on 告诉 PostgreSQL 开始存档 WAL。
- archive_command 定义如何将 WAL 推送到备份系统。
- restore_command 在恢复期间用于从档案中获取 WAL。
最后,重新启动以应用配置更改:
sudo systemctl 重启 postgresql-15
初始化pgBackRest
在备份节点上
为了避免必须在每个命令前加上 sudo -u pgbackrest,您可以使用以下命令切换到 pgbackrest 用户:
sudo -i -u pgbackrest
但是,为了保持一致性和清晰度,本指南对每个命令都使用 sudo -u pgbackrest。
创建节
stanza 是 pgBackRest 用于对特定 PostgreSQL 实例的配置进行分组的逻辑名称。创建 stanza 是设置备份环境的第一步。
sudo -u pgbackrest pgbackrest --stanza=db --log-level-console=info
stanza-create
这将验证您的配置并初始化存储库中的节元数据。在继续操作之前,请运行快速检查以验证数据库节点与备份系统之间的连接:
sudo -u pgbackrest pgbackrest --stanza=db 检查
如果一切连接正确,pgBackRest 将确认数据库和存储库可访问。
进行第一次完整备份:
您的初始备份必须是完整备份,它将成为所有未来增量或差异备份的基础。
sudo -u pgbackrest pgbackrest --stanza=db --type=full --log-level-console=info 备份
这会将所有相关数据从 PostgreSQL 数据目录复制到配置的备份存储库。完整备份完成后,您可以创建更小、更高效的备份,仅包含更改部分。
增量备份包括自上次任何类型的备份以来的更改:
sudo -u pgbackrest pgbackrest --stanza=db --type=incr --log-level-console=info 备份
差异备份包括自上次完整备份以来的更改:
sudo -u pgbackrest pgbackrest --stanza=db --type=diff --log-level-console=info 备份
使用 Cron 自动备份
为了确保备份按计划运行,请为 pgbackrest 用户配置一个 cron 作业:
sudo crontab -e -u pgbackrest
添加以下条目以自动执行每日备份:
# 周日凌晨 2 点 — 完整备份
0 2 * * 0 /usr/bin/pgbackrest --stanza=db --type=full 备份
# 周一至周六凌晨 2 点 — 增量备份
0 2 * * 1-6 /usr/bin/pgbackrest --stanza=db --type=incr 备份
查看备份内容
在备份节点上
查看所有备份集的摘要,包括大小、时间戳和存档信息等详细信息
sudo -u pgbackrest pgbackrest 信息
要探索特定备份:
sudo -u pgbackrest ls /home/pgbackrest/backups/backup/db/<BACKUP_ID>/pg_data
PITR 恢复
时间点恢复 (PITR) 是 PostgreSQL 的一项强大功能,它允许数据库恢复到意外数据丢失、损坏或部署不当之前的特定时刻。借助 pgBackRest,PITR 将成为简化且可靠的流程。
以下是使用 pgBackRest 执行完整恢复以及时间点恢复的完整演练。
pgBackRest 如何处理恢复:
当您启动恢复时,pgBackRest 会自动组装所需的一切:
- 最新完整备份
- 任何相关的差异或增量备份
- 重放所需的所有 WAL(预写日志)文件
这可确保恢复的数据库一致且最新,无论是最新点还是您选择的特定时间。
在数据库节点上
停止 PostgreSQL
sudo systemctl 停止 postgresql-15
如果要恢复到同一个数据目录,则该目录必须为空:
sudo rm -rf /var/lib/pgsql/15/data/*
要将所有内容恢复到最近的一致状态:
sudo -u pgbackrest pgbackrest --stanza=db
要恢复到特定时间点,请指定目标时间并输入:
sudo -u pgbackrest pgbackrest --stanza=db --type=time --target="2025-05-23 14:30:00" 恢复
如果您想在意外 DROP 或错误更新之前恢复,这将很有用。
sudo systemctl 启动 postgresql-15
PostgreSQL 现在将开始使用恢复的数据。
测试备份还原
您应该定期测试备份,但不要触及生产环境。为了验证备份是否可恢复,您可以在同一备份服务器上执行测试恢复。此过程有助于验证,并且不会影响主数据库。
步骤
- 选择一个安全的空目录来恢复数据库。
- 运行以下命令执行完整恢复:使用您想要的目标恢复位置更新 –pg1-path。
sudo -u pgbackrest pgbackrest --stanza=db --pg1-path=/var/lib/postgresql/15/test 恢复
要恢复到特定时间点,
sudo -u pgbackrest pgbackrest --stanza=db
--pg1-path=/var/lib/postgresql/15/test --log-level-console=info --type=time
--target="2025-06-13 15:37:00" 恢复
恢复完成后,检查恢复的数据目录中是否有预期的内容:
PG_VERSION 基础/ 全局 /postgresql.conf
(可选):使用恢复的目录启动 PostgreSQL:
pg_ctl -D /var/lib/postgresql/15/测试启动
使用 psql 连接并验证数据库结构和内容:
psql -U postgres -c“从 pg_database 中选择数据名称;
结论
即使您的备份运行顺利,还原测试对于验证端到端恢复也至关重要。我们强烈建议您安排定期测试还原,以便:
- 确保备份不会被悄无声息地破坏
- 确认 WAL 归档功能正常
- 验证您的恢复过程
在实际紧急情况下,您不希望第一次恢复尝试成为您的第一次练习。
原文地址:https://stormatics.tech/blogs/disaster-recovery-guide-with-pgbackrest
原文作者:Warda Bibi




