备份策略设计
前面几页分别讲了单点工具:pg_dump 做逻辑备份、pg_basebackup 做物理备份、archive_command 做 WAL 归档、pg_verifybackup 做备份校验。这一页要把它们组装成一套体系:多长时间备份一次、保留多久、放几份、放在哪里、出故障时能退回多远。
备份策略设计的核心是回答两个问题:
- RPO(Recovery Point Objective):能容忍丢失多少数据?换句话说,最坏情况下允许退回到多久之前。RPO 决定备份与归档的频率。
- RTO(Recovery Time Objective):能容忍停多久?从故障发生到业务恢复,允许的时长上限。RTO 决定恢复方案的技术选型(是切备用节点,还是原地恢复,还是重建)。
这两个指标是业务给的,不是技术定的。技术要做的是把业务指标翻译成具体参数:备份周期、归档方式、保留份数、存储布局、演练频次。本页按这个顺序展开。
需要强调一点:不存在“普适最优的备份策略”。一份每天全量、保留 7 天、单机存放的策略,对小型内部系统可能绰绰有余,对金融核心系统则远远不够。策略必须与业务等级匹配,并且必须被验证过——没演练过的策略等于没有策略。
前置知识
建议先阅读:pg_verifybackup
基础概念
RPO 与 RTO
| 指标 | 含义 | 由什么决定 |
|---|---|---|
| RPO | 允许丢失的数据时间跨度 | 备份频率 + WAL 归档频率(archive_timeout) |
| RTO | 允许的恢复耗时 | 备份大小、恢复方式、人员响应速度、验证流程 |
举例说明 RPO 的作用:如果 archive_timeout = 300(5 分钟),理论上最坏会丢失最多 5 分钟的 WAL(因为最后一次切换后未满 5 分钟的事务还没归档)。若业务只能容忍丢 1 分钟,那这个配置不达标,要么调小 archive_timeout,要么上同步复制。
RTO 的作用类似:如果一份基础备份有 2 TB,恢复到可用状态需要 6 小时,那么任何声称“1 小时恢复”的方案都是不成立的——除非有热备节点可以立即接管。
备份的三种粒度
| 粒度 | 手段 | RPO 能力 | 典型用途 |
|---|---|---|---|
| 逻辑备份 | pg_dump / pg_dumpall | 取决于频率(小时/天级) | 单库迁移、单表恢复、跨版本升级 |
| 物理全量备份 | pg_basebackup、文件系统快照 | 配合归档可达分钟级 | 整实例恢复的基础 |
| 连续归档 | WAL 归档 | 分钟级(受 archive_timeout 限制) | PITR,任一时间点回放 |
| 流复制 | 物理备库 | 秒级至零(同步复制) | 故障切换,快速接管 |
这些手段不是互斥的,而是互补的。一套成熟的策略通常同时包含:每日物理全量 + 连续 WAL 归档 + 一个流复制备库 + 定期的逻辑备份(用于单表恢复和跨版本迁移)。
全量、增量、差异
| 类型 | 含义 | 优点 | 缺点 |
|---|---|---|---|
| 全量(full) | 每次都完整复制所有数据 | 恢复最简单,单份自包含 | 耗时长、占空间大 |
| 差异(differential) | 只包含相对上次全量的变化 | 恢复需要两份 | 差异量随时间增长 |
| 增量(incremental) | 只包含相对上次任意备份的变化 | 单份最小、最快 | 恢复需要整条链,链条越长风险越高 |
PostgreSQL 自身提供的 pg_basebackup 做的是全量物理备份。增量能力通常来自第三方备份工具或存储层快照(例如 ZFS、LVM 快照)。因此在纯原生方案下,常见做法是“周期性全量 + 连续 WAL 归档”——WAL 归档在某种程度上承担了“增量”的角色。
保留策略:GFS
GFS 是 Grandfather-Father-Son 的缩写,是经典的轮转保留策略:
- Son(子):近期保留密集,例如每天一份,保留 7 天。
- Father(父):中期保留稀疏,例如每周一份,保留 8 周。
- Grandfather(祖父):长期保留,例如每月一份,保留 12 个月。
这种结构能在“存储成本”与“可回溯深度”之间取得较好平衡:近期恢复需求最频繁,所以保留密集;长期恢复需求罕见,所以保留稀疏但覆盖久远。
3-2-1 原则
备份领域流传最广的一条经验法则是 3-2-1:
- 3 份数据副本(1 份生产 + 2 份备份)。
- 2 种不同介质(例如本地磁盘 + 对象存储/磁带)。
- 1 份异地(与生产机房物理隔离)。
它应对的是不同级别的失效:单盘损坏(本地副本覆盖)、机房整体故障(异地副本覆盖)、以及勒索软件/误删(离线或不可变副本覆盖)。
恢复目标的分级
并非所有恢复都是“把整个实例退回去”。常见的目标级别:
| 级别 | 目标 | 常用手段 |
|---|---|---|
| 单行/单表 | 找回误删的少量数据 | 逻辑备份、逻辑复制、从副本抽取 |
| 单库 | 恢复某个数据库 | pg_dump 单库备份、PITR 到新实例后抽取 |
| 整实例 | 恢复到某个时刻 | 基础备份 + WAL 归档 + PITR |
| 整机房 | 业务不中断 | 异地副本、异地备份、DNS/流量切换 |
策略设计时应当明确:每一级目标分别用什么手段达成、对应 RTO 是多少。很多团队只覆盖了“整实例”一级,遇到“误删一行”这种最常发生的场景反而束手无策。
备份窗口
备份窗口指的是“允许执行备份而不影响业务”的时间段。物理全量备份会产生大量 I/O,pg_dump 会长时间持有长事务(进而影响 VACUUM 与 WAL 保留),因此都需要安排在窗口内。
备份窗口与备份耗时是一对矛盾:
- 数据量增长 → 备份耗时增长。
- 业务增长 → 窗口可能缩小。
当两者交叉时,策略必须升级(改成增量、用快照、上备库做备份等),而不是简单地“延后结束时间”。
备份媒介与成本
| 介质 | 特点 | 适用场景 |
|---|---|---|
| 本地磁盘 | 快、便宜、但同机房 | 快速恢复的第一层 |
| 网络存储(NAS/SAN) | 容量大、可共享 | 集中备份存储 |
| 对象存储 | 便宜、可跨区、支持不可变策略 | 长期保留与异地 |
| 磁带 | 极便宜、离线、恢复慢 | 合规归档 |
成本主要来自容量与保留时长。GFS + 3-2-1 的组合就是在这两个维度上做优化。
不可变备份与防勒索
传统备份的一个致命弱点是:如果攻击者拿到了备份存储的写权限,备份也会被加密或删除。因此现代策略中会引入:
- 不可变(immutable)/WORM 存储:写入后在保留期内无法修改或删除。
- 对象锁(object lock):对象存储提供的保留策略。
- 单向写入通道:备份从生产推送到存储,存储侧不提供删除接口给生产。
这些机制属于“备份安全”范畴,与备份策略同等重要。策略里如果只写“每天备份”,而不写“备份存储的写权限如何隔离”,在真实攻击面前可能是无效的。
备份元数据
一份备份不仅仅是数据文件,还包含一堆必须一起保存的元数据:
- 备份类型与格式(逻辑/物理、plain/tar)。
- 备份起止时间与对应的 LSN。
- 对应的 PostgreSQL 版本与
pg_control信息。 - 清单文件
backup_manifest(物理备份)。 - 校验记录(何时校验、结果)。
- 恢复所需的配置片段(
restore_command等)。
缺少元数据的备份,在真正恢复时往往需要反复试错,直接拉长 RTO。
语法与用法
每日物理全量备份脚本骨架
#!/usr/bin/env bash
set -euo pipefail
BACKUP_ROOT="/var/lib/pgsql/backup"
STAMP="$(date +%Y%m%d_%H%M%S)"
TARGET="${BACKUP_ROOT}/${STAMP}"
pg_basebackup \
-h /var/run/postgresql \
-U repl \
-D "$TARGET" \
-F plain \
-X stream \
-P -v
pg_verifybackup -e "$TARGET"
echo "backup ok: $TARGET"要点:备份后立即校验,避免“备份不可用”被拖到恢复时才发现。
逻辑备份(单库)脚本骨架
#!/usr/bin/env bash
set -euo pipefail
STAMP="$(date +%Y%m%d)"
pg_dump -Fc -d appdb -f "/var/lib/pgsql/dump/appdb_${STAMP}.dump"-Fc(custom 格式)便于用 pg_restore 做选择性恢复(例如只恢复某张表),这在“单表恢复”场景里非常关键。
查看归档状态
SELECT archived_count,
failed_count,
last_archived_wal,
last_archived_time,
last_failed_wal,
last_failed_time
FROM pg_stat_archiver;failed_count 持续增长说明归档链路有问题,会直接威胁 RPO。
查看当前 WAL 位置
SELECT pg_current_wal_lsn() AS current_lsn,
pg_walfile_name(pg_current_wal_lsn()) AS current_wal;用于人工核对“当前数据对应的 WAL 段是否已归档”。
手动触发 WAL 切换(用于收尾)
SELECT pg_switch_wal();在低写入量实例上,当前 WAL 段可能长时间不满,导致归档迟迟不发生。在做重要操作前手动切换一次,可以缩短 RPO 窗口。
查看数据目录大小(估算备份量)
du -sh /var/lib/pgsql/data结合增长率可以预估备份耗时与存储需求。
详细说明
从 RPO 推导备份频率
RPO 是策略的起点。把 RPO 拆成两段:
实际可恢复点间隔 ≈ max(全量备份周期, WAL 归档间隔)更精确地说,恢复到任意时间点依赖“基础备份 + 之后的全部 WAL”。因此:
- 若只用每日全量备份、没有 WAL 归档 → RPO 是 24 小时。
- 若有每日全量 + 连续归档(
archive_timeout = 300)→ RPO 变成 5 分钟。
这也是为什么 PITR 体系必须搭配归档:它把 RPO 从“备份周期”压到“归档粒度”。
从 RTO 推导恢复方式
RTO 决定了恢复的技术路线:
| RTO 要求 | 可行方案 |
|---|---|
| 分钟级 | 必须依赖现成副本(流复制 + 提升),几乎没有“从头恢复”的空间 |
| 小时级 | 从最近的全量 + WAL 恢复,要求备份大小与恢复速度匹配 |
| 天级 | 常规备份恢复,可接受较长的搬运与验证时间 |
关键公式是:
恢复耗时 ≈ 数据搬运时间 + 基础备份重放 + WAL 重放 + 验证时间把这个估算值与 RTO 对比,就能判断当前方案是否达标。很多团队从未算过这个账,于是“RTO 4 小时”在纸面上成立,在演练中变成 12 小时。
保留份数如何计算
保留份数 = 保留时长 ÷ 备份周期。例如每天一份、保留 30 天,则保留 30 份。但要注意容量:
所需容量 ≈ 单份备份大小 × 份数 × (1 + 冗余系数)WAL 归档的容量需要单独计算:
WAL 归档容量 ≈ 每日 WAL 生成量 × 保留天数这往往是被低估的一项:高频写入系统的每日 WAL 量可能远大于基础备份的增量部分。
备份链的完整性
无论全量还是增量,都要意识到“备份是一串依赖关系”。对“全量 + 归档”体系而言:
- 要恢复到时刻 T,需要:T 之前最近的那份全量备份 + 从该全量的结束 LSN 到 T 之间的全部 WAL。
因此链条上的任何一环缺失,都会导致恢复目标无法达成。策略中必须显式保障:
- 全量备份与它之后产生的 WAL 归档不分开清理。
- 清理策略以“可恢复区间”为单位,而不是以“单个文件的时间”为单位。
归档与备份的保留必须联动
一个常见事故是:备份保留了 30 天,WAL 归档只保留了 7 天。结果是——只有最近 7 天的备份能真正用于 PITR,更早的备份虽有数据文件却缺 WAL,属于“看起来有备份、实际不可用”。
因此保留策略的表述应当是:“可恢复到过去 N 天内的任意时刻”,而不是分别规定“备份保留 30 天、WAL 保留 7 天”。前者是目标,后者只有在满足依赖关系时才成立。
备份窗口与增量策略的权衡
随着数据量增长,每日全量的窗口压力会持续增大。可选的缓解手段:
- 改用快照:文件系统或存储快照几乎瞬间完成,代价是需要
pg_backup_start/pg_backup_stop配合保证一致性。 - 在备库上做备份:把备份 I/O 从主库移到备库,避免影响主库。
- 降低全量频率、依赖 WAL 归档:例如每周全量 + 连续归档,中间靠 WAL 恢复。代价是恢复时需要重放更长时间的 WAL,RTO 变长。
这三者在 RTO 与业务影响之间各有取舍,没有免费选项。
逻辑备份不可替代的两个场景
物理备份很强,但有两件事它做不好:
- 单表/单行恢复。物理备份只能整实例回放,要找回一张误删的表,得先恢复出一个新实例再从里面抽取——代价高。
- 跨大版本迁移。物理备份与实例版本强绑定,跨版本升级通常走逻辑导出导入(或用
pg_upgrade)。
因此成熟的策略通常同时保留物理备份与逻辑备份,各司其职。只做其中一种,会在这两类场景里付出高昂代价。
备份存储的权限与隔离
备份存储的权限设计要点:
- 备份写入使用专用的操作系统账号,不使用数据库超级用户。
- 备份目录对数据库实例账号应当是只读或不可见的,防止实例上的漏洞导致备份被破坏。
- 若支持,启用不可变保留策略。
- 备份的读取权限也应受控,因为备份里包含全部数据。
这些属于“备份安全”的基础要求,与制度层面的访问审计共同构成防线。
备份期间的性能影响
不同的备份方式对生产的影响差别很大:
| 方式 | 主要影响 |
|---|---|
pg_basebackup(流式) | 主库需要发送全部数据,网络与 I/O 有负载;会触发 checkpoint |
pg_basebackup(-Ft + 压缩) | 网络占用下降,CPU 占用上升 |
| 文件系统快照 | 极低,但需要存储与文件系统支持 |
pg_dump | 长事务,影响 VACUUM 与 WAL 保留;CPU 有负载 |
策略设计时要明确每一项备份对生产的影响,并据此安排时段。pg_dump 的长事务影响尤其容易被忽略——它可能让回收无法进行,间接导致膨胀。
备份与复制槽的联动
如果用 pg_basebackup 且使用复制槽,需要确保备份结束后槽不会遗留。较稳妥的做法是让 pg_basebackup 使用临时槽,并在脚本中对异常路径做清理。
遗留槽会持续拽住 WAL 占磁盘,这属于“备份引起的生产问题”,在策略评审时应作为风险点列出。
备份与归档的失败模式对比
备份与归档虽然都属于“复制数据到别处”,但失败模式不同,处理方式也应不同:
| 维度 | 基础备份 | WAL 归档 |
|---|---|---|
| 频率 | 低(每天/每周) | 高(分钟级) |
| 单次产物 | 一个大目录 | 一个 16MB 的 WAL 段 |
| 失败影响 | 少一份历史基线 | RPO 立刻变差 |
| 重试成本 | 高(要重跑整份) | 低(重传一个段) |
| 典型失败原因 | 网络中断、空间不足 | 归档目录满、权限、目标不可达 |
结论:归档需要更灵敏的监控、更积极的重试,因为它失败时 RPO 立刻变坏;而备份失败通常还有时间在上限内重跑一次。
备份的幂等与重入
设计备份脚本时,要考虑“脚本被杀掉后重新执行”会怎样:
- 目标目录已存在怎么办?应当使用带时间戳的目录名,天然避免冲突。
- 半成品目录要不要保留?应当先写入临时目录,成功后再改名,避免半成品被误认为有效备份。
- 校验失败的备份要不要保留?建议保留一段时间用于事后分析,但必须打上明显标记,防止被当成可用备份。
这三点在自动化流水线里是稳定性的关键。
单实例多数据库的策略差异
一个实例上可能有多个数据库,它们的重要性与数据量差别很大:
- 核心库:需要最短 RPO、最长保留、最频繁演练。
- 日志库:可以接受更长 RPO,但数据量大,全量成本高。
- 临时库:可能只需要每周一份逻辑备份。
如果对整实例统一使用一套策略,往往出现“核心库保护不足、临时库过度保护”的错配。可行做法是在实例级物理备份之外,对核心库单独增加逻辑备份与更细的校验。
策略中的时间基准
备份体系里所有时间都必须明确时区,否则在排障时会出现“日志显示 10:30、备份元数据记录 02:30”这类混乱。建议:
- 所有脚本与元数据统一使用带时区的时间戳。
- 数据库侧记录时间统一用
timestamptz。 - 跨机房场景明确以哪一方时间为准。
时间基准混乱会直接拖长 RTO,因为恢复决策依赖“恢复到哪一刻”。
备份存储的容量规划
容量规划要覆盖三块,不能只算备份本体:
总需求 ≈ 备份占用 + WAL 归档占用 + 临时空间- 备份占用:由保留份数与单份大小决定。
- WAL 归档占用:由 WAL 生成速率与保留时长决定,常被低估。
- 临时空间:恢复时需要同时容纳“备份内容”与“恢复中的实例”,因此至少要留出一份完整数据目录大小的空间。
很多恢复事故不是缺备份,而是缺“恢复时落地的空间”。策略中应明确恢复环境的容量要求,并预留。
只做备份不做恢复准备的问题
备份与恢复是两件事,但在资源规划上常被混为一谈。常见的缺失项:
- 没有预留恢复用的数据目录空间。
- 没有准备恢复用的主机(或在故障时无法立即获得)。
- 没有恢复所需的配置片段与归档地址记录。
- 没有人明确在事故中负责执行恢复。
结果就是“备份齐全、但恢复不起来”。策略评审时应当把“恢复准备”作为独立章节,逐项检查。
从备份恢复与新实例并行
在生产环境原地恢复会带来明显停机。实践中常采用“并行恢复”降低风险:
- 在另一台主机上用同一份备份启动新实例。
- 恢复到目标时刻。
- 验证数据正确性。
- 再把流量切过去(或从新实例抽取需要的数据)。
这种方式把“恢复”与“切换”解耦,RTO 更容易控制,也更适合“单表恢复”这类场景。
备份策略与安全事件
在勒索软件或入侵场景下,备份策略的核心是保证至少有一份副本不可被攻击者触达:
- 备份推送使用单向通道,存储侧不暴露删除接口。
- 启用不可变保留期,期内无法修改。
- 保留至少一份离线副本(磁带或断网存储)。
- 定期验证离线副本可恢复。
只依赖“在线可写备份”的体系,在勒索场景下可能全军覆没。这一点在近年的安全事件中反复被验证。
备份策略的常见误区
| 误区 | 问题 |
|---|---|
| 有备份就等于能恢复 | 缺少 WAL、缺少恢复环境、缺少操作者 |
| 备份在别的目录就是异地 | 同机房、同存储、同权限域都不算 |
| 备份保留 30 天 = 可恢复 30 天 | 若 WAL 只留 7 天,实际只有 7 天可用 |
| 校验通过 = 备份可用 | 校验有边界,仍需试恢复 |
| 只做物理备份就够了 | 单表恢复与跨版本迁移需要逻辑备份 |
| 备份脚本跑成功 = 备份完成 | 需要检查退出码、校验结果与元数据 |
把这些误区写成评审清单,能显著降低“纸面合规、实际不可用”的概率。
策略文档应包含的内容
一份可执行的备份策略文档至少应包含:
- 业务系统的 RPO / RTO 要求(以及来源,例如业务方书面确认)。
- 备份类型与频率(物理全量、逻辑备份、归档)。
- 保留策略(GFS 具体参数、可恢复区间)。
- 存储布局与介质(本地/异地/不可变)。
- 校验与演练的频次、责任人。
- 恢复流程与联系人。
- 监控与告警项。
其中“恢复流程”最容易被省略,却是在事故中真正被使用的部分。
备份策略的评审与迭代
备份策略不是一次性写好后就不动的文档。它应当随以下变化而复审:
- 数据量显著增长(影响备份窗口与恢复耗时)。
- 业务 RPO/RTO 要求变化。
- 架构变化(例如新增了异地机房、引入了分片)。
- 安全事件或行业监管要求变化。
- 演练发现的问题。
建议至少每半年复审一次,并在重大架构变更时立即复审。
监控项清单
备份策略要落地,必须靠监控兜底。核心监控项:
| 监控项 | 说明 |
|---|---|
| 最近一次成功备份时间 | 超过周期未成功即告警 |
归档 failed_count | 持续增长即告警 |
archive_command 滞后 | 用 last_archived_time 与当前时间对比 |
| 备份校验结果 | 失败即告警 |
| 备份存储容量 | 接近阈值告警 |
| 恢复演练上次执行时间 | 超期未演练告警 |
这些指标共同回答一个问题:“如果现在出事,我能不能恢复,能恢复到什么时候?”
备份策略与经济性
备份要花钱(存储、带宽、人力),因此策略设计包含经济权衡:
- 更长的保留期 = 更多存储成本。
- 更高的备份频率 = 更多带宽与 I/O 成本。
- 更低的 RTO = 更多硬件(热备)与更高复杂度。
合理的做法是按业务等级分层:核心系统享受最短 RPO、最低 RTO、最长保留;非核心系统采用更经济的配置。对所有系统套用同一套最严标准,通常既浪费预算,又因为复杂度过高而难以维护。
备份与合规
受监管行业通常对备份有明确要求,例如:
- 数据保留期限(数年)。
- 备份的完整性校验记录。
- 恢复演练的记录与报告。
- 备份介质的访问审计。
这类要求会直接影响保留策略与介质选择(离线磁带、不可变存储)。合规要求应当在策略设计开始时纳入,而不是事后补救。
实战示例
示例一:估算 RPO 与 RTO
假设:
- 数据总量 1 TB,每日增量 20 GB。
- 每日 WAL 生成量 100 GB。
archive_timeout = 300。- 全量备份耗时约 2 小时,恢复耗时约 3 小时。
推导:
- RPO ≈ 5 分钟(受
archive_timeout限制)。 - RTO ≈ 3 小时(恢复)+ 验证时间(约 1 小时)= 约 4 小时。
若业务要求 RTO ≤ 1 小时,当前方案不达标,需要引入热备节点。
示例二:GFS 保留参数
每日备份:保留 7 份
每周备份:保留 8 份
每月备份:保留 12 份
WAL 归档:与上述备份的最长保留时长对齐(12 个月)关键点是最后一行的联动:WAL 归档的保留时长不应短于备份的保留时长,否则早期备份无法用于 PITR。
示例三:核对归档是否跟上
SELECT last_archived_wal,
last_archived_time,
now() - last_archived_time AS lag,
failed_count
FROM pg_stat_archiver; last_archived_wal | last_archived_time | lag | failed_count
-----------------------+------------------------+----------+--------------
000000010000000000000C | 2026-09-20 10:35:12+08 | 00:02:41 | 0lag 在 5 分钟以内属于正常(与 archive_timeout 匹配);若 lag 持续增大或 failed_count 增长,需要立即排查。
示例四:备份目录结构约定
/var/lib/pgsql/backup/
├── daily/
│ ├── 20260918/
│ ├── 20260919/
│ └── 20260920/
├── weekly/
│ └── 2026W38/
└── monthly/
└── 202609/按保留层级分目录,清理脚本按目录层级执行,能显著降低“误删不该删的备份”的风险。
示例五:备份元数据记录
cat > "$TARGET/backup.info" <<EOF
backup_time=$(date -Iseconds)
pg_version=$(psql -Atc 'SHOW server_version')
start_lsn=$(psql -Atc 'SELECT pg_current_wal_lsn()')
database_size=$(psql -Atc 'SELECT pg_size_pretty(pg_database_size(current_database()))')
EOF这份元数据在恢复时能快速回答“这份备份是什么、能不能用”。
示例六:清理脚本(按可恢复区间清理)
#!/usr/bin/env bash
set -euo pipefail
# 只删除超过保留期的旧备份;WAL 归档单独按最长保留期清理
find /var/lib/pgsql/backup/daily -maxdepth 1 -type d -mtime +7 -exec rm -rf {} +注意清理脚本必须与 WAL 归档的保留策略配套,不能让“可恢复区间”出现断档。
示例七:用逻辑备份覆盖单表恢复
# 每天做一份自定义格式的逻辑备份
pg_dump -Fc -d appdb -f /var/lib/pgsql/dump/appdb_20260920.dump
# 恢复时只取需要的表
pg_restore -d appdb_restore -t orders /var/lib/pgsql/dump/appdb_20260920.dump这个能力是物理备份给不了的,也是“为什么不能只做物理备份”的直接答案。
注意事项
- RPO/RTO 必须由业务确认,不能由技术单方面假设;否则策略再完备也可能不达标。
- 备份保留与 WAL 归档保留必须联动。只保留备份不保留 WAL,早期备份无法用于 PITR。
pg_dump会持有长事务,影响 VACUUM 与 WAL 保留,需安排在低峰时段并监控。- 备份没验证等于没备份。至少做快速校验,定期做完整校验。
- 只做物理备份是不够的。单表恢复与跨版本迁移需要逻辑备份。
- 同一机房的多份副本不算异地。3-2-1 中的“1”要求物理隔离。
- 备份存储的写权限必须与数据库实例隔离,否则勒索软件可连备份一起破坏。
- 恢复耗时必须实测,而不是估算;估算与实测的差距往往很大。
- 备份窗口不会自动适应数据增长,需要定期复核并升级方案。
- 不要用
archive_mode = off来临时停止归档;临时停止应设archive_command = ''。 - 遗留复制槽会撑爆磁盘,备份脚本要处理异常路径。
- 策略文档必须包含恢复流程,否则事故现场无人能按图执行。
最佳实践
- 从业务方取得书面的 RPO / RTO 指标,作为整套策略的输入与验收标准。
- 用“可恢复到过去 N 天内的任意时刻”来描述保留策略,而不是分开描述备份与 WAL 的保留天数。
- 采用“物理全量 + 连续 WAL 归档 + 流复制备库 + 逻辑备份”的组合,覆盖不同级别的恢复目标。
- 每次备份后立即执行快速校验,定期执行完整校验,并把结果落库留痕。
- 按 GFS 组织保留层级,并用目录结构而非命名约定来表达层级,降低误删风险。
- 落实 3-2-1:本地一份用于快速恢复,异地一份用于机房级故障,不可变一份用于防勒索。
- 每季度至少完成一次端到端恢复演练,覆盖“整实例”与“单表”两类场景。
- 对备份与归档建立监控:最近成功时间、失败次数、滞后时长、存储容量、校验结果。
- 把备份元数据(LSN、时间、版本、校验记录)与备份一起保存,缩短恢复时的信息查询时间。
- 定期实测恢复耗时并与 RTO 对比;不达标就升级方案(引入热备或快照)。
- 对备份存储实施最小权限与不可变策略,并审计访问记录。
- 至少每半年复审一次策略文档,重大架构变更时立即复审,并保存历次版本的变更记录。
下一节
继续学习:灾难恢复流程
参考链接
- PostgreSQL 官方文档:Backup and Restore
- PostgreSQL 官方文档:Continuous Archiving and Point-in-Time Recovery
- PostgreSQL 官方文档:pg_basebackup
- PostgreSQL 官方文档:pg_dump
- PostgreSQL 官方文档:pg_dumpall
- PostgreSQL 官方文档:pg_verifybackup
- PostgreSQL 官方文档:Write Ahead Log Configuration
- PostgreSQL 官方文档:High Availability, Load Balancing, and Replication
- PostgreSQL 官方文档:Monitoring Database Activity