DBAtlas · 数据库运维图谱

使用 pgBackRest 进行备份与 PITR

PostgreSQL难度: 中级耗时: 45–90 分钟

使用 pgBackRest 进行全量 / 差异 / 增量备份、持续 WAL 归档和基于时间点的恢复 (PITR)。适用于单服务器、流复制 (primary + standby) 或 Patroni 集群;仓库 (repo) 可以位于同一服务器、单独的备份服务器 (SSH) 或 S3 兼容的对象存储。包括加密、压缩、保留策略、cron/systemd 调度以及恢复到单独目录的测试 restore;同一指南还会生成灾难发生时的原地 restore 操作手册(包括在 Patroni 中从备份重建集群)。与同类指南的区别:这是生产环境推荐的物理备份工具;如不想安装额外工具而做物理备份和 PITR,请使用 pg_basebackup + WAL 归档指南;逻辑备份(表/数据库转储、跨大版本迁移)请使用 pg_dump / pg_restore 指南。

架构: 1 台服务器、primary + standby 或 Patroni 集群;可选备份服务器

场景

  • 安装 pgBackRest + 首次备份 + 测试 restore — 尚未部署 pgBackRest:软件、仓库、WAL 归档、首次备份、调度和一次测试 restore。
  • 灾难时刻:原地 restore(恢复到最新状态或某个时间点) — 将数据库原地恢复到备份和归档所覆盖的某一时刻:最新时刻、某个时间、xid、LSN 或 restore point。集群会被关闭;目标之后的更改将丢失。
  • 数据目录中有损坏或被删除的文件(用 delta restore 修复) — 服务器完好,但部分数据文件无法读取或已被删除:--delta 只从备份写回有差异的文件,并重放到归档的最后时刻。集群会被关闭。
  • 只恢复单个数据库 (--db-include) — 集群保持运行:单个数据库被恢复到一个临时实例(单独的目录和端口),用 pg_dump 导出后以新名称加载到生产服务器。单张表被删除时也用这张卡片(从临时实例执行 pg_dump -t)。
  • 将备份恢复到另一台服务器(克隆 / 测试 / 报表) — 不触碰生产服务器。备份在新服务器上打开;WAL 归档被关闭,这样克隆不会写入生产仓库。加密仓库需要提供密钥。
  • 服务器完全丢失:在新服务器上打开备份并接替原服务器 — 磁盘或服务器丢失:新服务器从备份打开并成为新的 primary;WAL 归档和备份在同一个 stanza 中继续。旧服务器必须保持关闭。
  • 从备份搭建新的 standby (--type=standby) — 搭建新 standby 而不给 primary 增加复制负载:文件来自备份,缺少的 WAL 从归档和流复制补齐。Primary 保持运行。
  • 备份真的可用吗?(info / check / verify 与 restore 演练) — 只读检查,以及不触碰生产服务器、恢复到单独目录的 restore 演练。同时配置每月一次的验证任务 (cron)。
  • 修改保留期限并清理旧备份 (expire) — 修改 repo1-retention-full/diff 设置,先用 --dry-run 显示将删除哪些内容,然后执行 expire。被删除的备份无法找回。

开始之前

  • PostgreSQL … 已安装并运行(pg-install 指南)…;本服务器为 primary…。数据目录 …。
  • Patroni 集群 … 正在运行(Patroni 安装):一个 Leader,其余为流复制 replica。所有节点的数据目录为 …,Patroni 配置为 …,REST API 密码在 /etc/patroni/patroni.env 文件中。
  • 未配置其他归档/备份工具(Barman、WAL-G、手写的 archive_command);如有请先移除。两个工具把同一 WAL 搬到不同位置时,两边都会不完整。… Patroni 中当前值见 patronictl show-config 的输出。…
  • 已知数据库大小。仓库大约需要 (full 数量 + 1) × 压缩后大小 + WAL 归档 的空间(使用 zst 时大多数数据库可压缩到 1/3–1/5)。
  • 仓库目录 … 位于与数据库分开的磁盘/NFS 共享上,并已持久挂载 (fstab)。
  • 备份服务器上已为 … 挂载空间充足的单独磁盘。备份服务器与数据库使用同一操作系统系列。
  • 各服务器能互相解析名称(…、…),且彼此之间 22/tcp (SSH) 已放通。
  • Standby(………, ……)是从 primary 接收 WAL 的流复制 standby,并使用与 primary 相同的 PGDATA 路径 (…)。
  • Bucket … 已创建;已准备好仅对该 bucket 具有读/写/删除权限的访问密钥 (access key + secret key)。Bucket 上没有删除对象的 lifecycle 规则(保留由 pgBackRest 管理)。服务器可以访问 endpoint。
  • 时钟已同步 (NTP)。PITR 目标时间和 S3 签名都依赖正确的时间。
  • 服务器可以访问 PGDG 和 EPEL 仓库(或内部镜像);pgBackRest 的依赖 libssh2 来自 EPEL。
  • 已准备好存放加密密钥的位置(密码保险库 / vault)。密钥如果不在服务器之外保存,服务器丢失后备份将无法打开。

指南阶段

  • 安装 pgBackRest 软件 — 添加 PGDG 仓库(备份服务器) · 添加 PGDG 仓库(备份服务器) · 启用 EPEL 仓库 · 安装 pgBackRest · 创建 pgbackrest 用户 · 移除旧的配置文件
  • 仓库准备 — 创建仓库目录 · 创建仓库目录 · 生成 SSH 密钥(备份服务器) · 生成 SSH 密钥(数据库服务器) · 授权备份服务器的密钥 · 授权数据库服务器的密钥 …
  • pgBackRest 配置 — 写入配置文件 · 写入配置文件(备份服务器) · 写入配置文件(数据库服务器) · 输入 S3 访问密钥 · 生成加密密钥 · 在服务器 … 上写入加密密钥 …
  • Stanza 与首次备份 — 创建 stanza · 创建 stanza · 验证配置 (check) · 执行首次 full 备份 · 执行首次 full 备份 · 查看仓库状态 (info) …
  • 备份调度 — 验证 pgbackrest 命令的路径 · 编写备份脚本 · 设置脚本的属主和权限 · 创建 systemd service 和 timer · 测试调度(手动触发) · 准备 cron 服务 …
  • 验证与恢复测试 — 检查 WAL 归档是否正常工作 · 写入测试数据并记录目标时间 · 准备测试 restore 目录 · 恢复到单独目录、直到目标时间 · 在单独端口上启动测试集群 · 验证恢复的数据 …
  • 监控与维护 — 验证仓库完整性 (verify) · 验证仓库完整性 (verify) · 监控最近一次备份的时间 · 监控最近一次备份的时间 · 第二份副本与密钥保管
  • 诊断:文件损坏还是缺失? — 在日志中找出错误和受影响的文件 · 确定损坏的对象 · 确认存在完好的备份和归档
  • Restore 前检查 — 列出备份 · 检查应用连接 · 停止 standby · 停止 PostgreSQL · 复制当前数据目录(如有空间)
  • 原地 restore — 执行 restore (--delta) · 启动 PostgreSQL 并等待 recovery 完成 · 检查目标处的数据 (pause) · 结束 recovery 并 promote
  • 验证 — 清理 restore 设置 · 检查集群状态 · 检查应用数据 · 验证损坏已消除 (amcheck) · 确认归档仍在继续 · 执行新的 full 备份 …
  • Restore 前:停止 Patroni 集群 — 列出备份 · 保存集群状态和动态配置 · 停止应用 · 停止 replica 上的 Patroni · 停止 leader 上的 Patroni · 复制当前数据目录(如有空间)
  • 验证与清理 (Patroni) — 确认归档仍在继续 · 执行新的 full 备份 · 检查集群和应用访问 · 删除移到一边的数据目录
  • Patroni:重建损坏的节点 (reinit) — 找出哪个节点存在损坏 · 如果损坏的节点是 leader,先移交 leader 角色 · 重建损坏的 replica (reinit)
  • 备份验证与 restore 演练 — 备份状态和最近一次备份的时间 (info) · 确认归档当前正常工作 (check) · 验证仓库完整性 (verify) · 准备演练目录 · 将最新备份恢复到演练目录 · 启动演练实例并等待 recovery …
  • 每月验证调度 — 编写每月验证脚本 · 设置脚本权限并在 cron 环境下试运行 · 编写每月 cron 任务 · 设置 cron 文件的权限
  • 修改保留策略 — 当前保留设置与备份 · 修改保留设置 · 显示将删除哪些内容 (dry-run) · 删除旧备份 (expire) · 检查仓库使用量和调度
按您的环境打开分步计划 →