PostgreSQL 备份与高可用
PostgreSQL 的备份恢复和高可用围绕 WAL 展开。WAL 既能做崩溃恢复,也能做流复制和时间点恢复。
学习目标
学完本页,你要能回答:
| 问题 | 要掌握的原理 |
|---|---|
pg_dump 和 pg_basebackup 有什么区别 | 逻辑备份导出对象和数据,物理备份复制数据库文件 |
| 为什么 PITR 需要基础备份加 WAL | 基础备份提供起点,WAL 把数据库推进到目标时间点 |
| 为什么流复制会有延迟 | 从库要接收 WAL、写入 WAL、重放 WAL,每一步都可能慢 |
| 同步复制是不是绝对不丢数据 | 要看同步级别、确认位置、网络和故障场景 |
| 备份和高可用有什么区别 | 高可用解决故障切换,备份解决误删、误更新和灾难恢复 |
| 生产怎么设计 RPO/RTO | 根据业务能丢多久数据、能停多久服务倒推备份和复制策略 |
零基础先理解 WAL
WAL 是 Write-Ahead Logging,意思是“数据页真正刷盘前,先把修改日志写到 WAL”。这样即使数据库宕机,只要 WAL 已经落盘,就能在重启时把已提交事务重放回来。
flowchart TD
A["业务执行 insert/update/delete"] --> B["生成 WAL 记录"]
B --> C["WAL 先刷盘"]
C --> D["事务可以提交"]
D --> E["数据页稍后刷盘"]
E --> F{"宕机后重启"}
F --> G["根据 WAL 重放已提交修改"]备份、高可用、PITR 都围绕 WAL 展开:
| 能力 | WAL 的作用 |
|---|---|
| 崩溃恢复 | 重放宕机前已提交但未刷入数据文件的修改 |
| 流复制 | 主库把 WAL 发给从库,从库重放 WAL |
| 时间点恢复 | 恢复基础备份后,回放 WAL 到指定时间 |
| 审计排查 | 通过时间线和 LSN 判断恢复位置和复制延迟 |
备份类型
| 类型 | 工具 | 适合 |
|---|---|---|
| 逻辑备份 | pg_dump | 单库、单表、迁移 |
| 物理基础备份 | pg_basebackup | 整实例恢复、主从搭建 |
| WAL 归档 | archive_mode | 时间点恢复 |
逻辑备份和物理备份区别
| 对比 | 逻辑备份 pg_dump | 物理备份 pg_basebackup |
|---|---|---|
| 备份内容 | SQL/对象定义/数据逻辑内容 | 数据目录里的物理文件 |
| 恢复粒度 | 库、schema、表更灵活 | 通常恢复整个实例或集群 |
| 跨版本迁移 | 更适合 | 受版本和平台限制更多 |
| 大库速度 | 通常较慢 | 通常更适合大库 |
| PITR | 单独不支持完整 PITR | 配合 WAL 支持 PITR |
| 典型用途 | 迁移、导出单表、测试数据 | 容灾、搭建从库、整库恢复 |
选择原则:
- 小库迁移、单表导出、跨版本升级,优先
pg_dump。 - 大库整实例备份、主从搭建、时间点恢复,优先物理基础备份加 WAL。
- 核心生产库不要只做
pg_dump,因为恢复窗口和恢复完整性可能不满足要求。
pg_dump
备份单库:
pg_dump -h 127.0.0.1 -U app -d app_db -Fc -f app_db.dump恢复:
pg_restore -h 127.0.0.1 -U app -d app_db app_db.dump-Fc 是自定义格式,恢复时更灵活。
常见参数:
| 参数 | 作用 |
|---|---|
-Fc | 自定义格式,支持 pg_restore 灵活恢复 |
-j | 并行备份或恢复,适合较大库 |
--schema | 只备份某个 schema |
--table | 只备份某张表 |
--data-only | 只导数据 |
--schema-only | 只导结构 |
商业场景:如果误删的是一张配置表,可以从昨天的逻辑备份中恢复到临时库,再导出目标表数据回灌;但如果要恢复 10:23:15 前的全库状态,pg_dump 单独不够,需要 PITR。
物理基础备份
pg_basebackup 会复制主库的数据目录,并记录备份开始和结束所需的 WAL 位置。
示例:
pg_basebackup \
-h 10.0.0.10 \
-U repl \
-D /data/pg_basebackup \
-Fp \
-Xs \
-P参数含义:
| 参数 | 说明 |
|---|---|
-D | 备份输出目录 |
-Fp | plain 格式,直接输出数据目录结构 |
-Xs | 通过流方式包含备份期间需要的 WAL |
-P | 显示进度 |
为什么备份过程中还要处理 WAL?因为备份复制数据文件需要时间,复制期间业务还在写。不同数据文件可能来自不同时间点,需要 WAL 把它们恢复到一致状态。
flowchart TD
A["开始基础备份"] --> B["记录起始 LSN"]
B --> C["复制数据文件"]
C --> D["业务仍在写入并产生 WAL"]
D --> E["记录结束 LSN"]
E --> F["保存备份期间 WAL"]
F --> G["恢复时回放 WAL 到一致点"]时间点恢复 PITR
PITR 依赖基础备份 + WAL。
flowchart TD
A["基础备份"] --> B["持续归档 WAL"]
B --> C["发生误删"]
C --> D["恢复基础备份到临时实例"]
D --> E["回放 WAL 到误删前"]
E --> F["校验并导出数据"]更完整的 PITR 思路:
- 先有一个可用的物理基础备份。
- 从基础备份开始之后,WAL 持续归档。
- 发生误删、误更新或数据损坏时,准备一台临时恢复实例。
- 还原基础备份。
- 配置
restore_command,让 PostgreSQL 能拿到归档 WAL。 - 设置
recovery_target_time或recovery_target_lsn。 - 启动实例,让它回放 WAL 到目标点。
- 校验数据,导出需要回补的记录。
示例配置片段:
restore_command = 'cp /backup/wal_archive/%f %p'
recovery_target_time = '2026-07-06 10:24:00+08'
recovery_target_action = 'pause'recovery_target_action = 'pause' 的好处是:数据库恢复到目标时间后先暂停,方便 DBA 校验是否就是误操作前的位置,而不是直接打开后继续推进。
商业误删恢复流程:
flowchart TD
A["确认误删时间和影响范围"] --> B["选择误删前最近基础备份"]
B --> C["恢复到临时实例"]
C --> D["回放 WAL 到误删前"]
D --> E["业务和 DBA 校验数据"]
E --> F["导出误删数据"]
F --> G["主库执行补偿回灌"]
G --> H["校验业务状态和审计记录"]不要轻易把生产主库整体回退到误删前。因为误删之后可能还有正常订单、支付、采集任务状态更新,整体回退会丢掉这些正常业务。更常见做法是恢复到临时库,再把被误删的数据补回主库。
流复制
sequenceDiagram
participant P as Primary
participant W as WAL
participant S as Standby
P->>W: 写 WAL
S->>P: 接收 WAL
S->>S: 重放 WAL流复制可以用于读扩展和高可用,但默认仍可能有复制延迟。
流复制的核心链路:
flowchart TD
A["主库事务提交产生 WAL"] --> B["WAL sender 发送 WAL"]
B --> C["网络传输"]
C --> D["从库 WAL receiver 接收"]
D --> E["写入从库 WAL"]
E --> F["Startup 进程重放 WAL"]
F --> G["从库数据追上主库"]复制延迟可能发生在:
| 阶段 | 延迟原因 |
|---|---|
| 主库发送 | 主库压力大,WAL 产生太快 |
| 网络传输 | 跨机房网络抖动或带宽不足 |
| 从库写 WAL | 从库磁盘慢 |
| 从库重放 | 大事务、DDL、索引维护、从库查询冲突 |
| 应用读从库 | 读到旧数据,表现为刚写完查不到 |
查看复制状态:
select application_name,
state,
sync_state,
sent_lsn,
write_lsn,
flush_lsn,
replay_lsn,
write_lag,
flush_lag,
replay_lag
from pg_stat_replication;LSN 可以理解为 WAL 位置。sent_lsn、write_lsn、flush_lsn、replay_lsn 分别表示发送、写入、刷盘、重放到哪里。差距越大,延迟越大。
同步复制和异步复制
| 模式 | 特点 |
|---|---|
| 异步复制 | 主库提交不等从库,性能好,可能丢少量数据 |
| 同步复制 | 主库提交等待从库确认,一致性更强,延迟更高 |
同步复制也要分清“等到哪一步”:
| 级别 | 大致含义 | 影响 |
|---|---|---|
| remote write | 从库已写入操作系统缓存 | 延迟较低,但还没保证刷盘 |
| remote flush | 从库 WAL 已刷盘 | 持久性更强,提交延迟更高 |
| remote apply | 从库已重放可查询 | 一致性更强,但最慢 |
不要简单说“同步复制一定不丢数据”。如果同步从库也故障、配置不当、确认级别较弱,或者故障切换流程错误,仍然可能出现数据风险。生产要结合业务 RPO、网络质量和故障演练来设计。
复制槽是什么
复制槽 replication slot 用来告诉主库:某个订阅者或从库还需要哪些 WAL,主库不要过早清理。
优点:
- 从库短暂断开后,主库保留它还没收到的 WAL。
- 逻辑复制消费者可以可靠消费变更。
风险:
- 从库或消费者长期不消费,主库会持续保留 WAL。
- WAL 占满磁盘,主库可能故障。
查看复制槽:
select slot_name,
slot_type,
active,
restart_lsn,
confirmed_flush_lsn
from pg_replication_slots;商业项目里,复制槽必须监控 WAL 保留量,不能只创建不管。
备份和高可用不是一回事
| 能力 | 解决什么 | 不能解决什么 |
|---|---|---|
| 备份 | 误删、误更新、灾难后恢复历史数据 | 自动秒级切换 |
| 流复制 | 读扩展、主库故障后切换 | 误删会同步到从库 |
| 同步复制 | 降低主库故障丢数据风险 | 增加提交延迟,不能替代备份 |
| PITR | 恢复到具体时间点 | 恢复需要时间 |
| Patroni/repmgr 等 HA 工具 | 自动选主和故障转移 | 不能保证业务无感,也不能代替数据校验 |
一句话:高可用让系统尽快恢复服务,备份让数据能回到过去。两者都要有。
商业场景
| 场景 | 建议 |
|---|---|
| 核心交易库 | 基础备份 + WAL 归档 + 流复制 + 定期恢复演练 |
| 报表查询 | 使用只读从库,避免影响主库 |
| 误删恢复 | 临时实例恢复到误删前,再回补 |
| 强一致读 | 不要盲目读从库,要考虑复制延迟 |
RPO 和 RTO 怎么倒推方案
| 指标 | 含义 | 举例 |
|---|---|---|
| RPO | 最多允许丢多少数据 | 核心订单最多丢 0 到 1 分钟 |
| RTO | 最多允许停多久 | 核心服务 10 分钟恢复,报表 2 小时恢复 |
方案设计示例:
| 系统 | 可接受 RPO/RTO | 建议 |
|---|---|---|
| 支付/订单 | RPO 接近 0,RTO 分钟级 | 同步或准同步复制、自动 HA、频繁 WAL 归档、强演练 |
| 医疗采集任务 | RPO 数分钟,RTO 30 分钟内 | 异步流复制、WAL 归档、任务幂等补偿 |
| 报表库 | RPO 1 小时,RTO 数小时 | 定期备份、异步复制或离线重建 |
| 测试库 | 可丢数据 | 逻辑备份或快照即可 |
备份策略不是“每天凌晨备一下”,而是业务要求倒推出来的。
生产备份策略示例
| 项目 | 策略 |
|---|---|
| 物理基础备份 | 每天或每周,按库大小和恢复窗口决定 |
| WAL 归档 | 持续归档到独立存储 |
| 逻辑备份 | 关键配置表每日导出,方便单表恢复 |
| 从库 | 至少一个只读或热备从库 |
| 异地副本 | 核心库至少一份异地 |
| 恢复演练 | 每月至少恢复到临时环境 |
| 监控 | WAL 归档失败、复制延迟、备份时长、备份大小、磁盘空间 |
常见坑
| 坑 | 后果 | 正确做法 |
|---|---|---|
| 只做备份不演练恢复 | 真事故时发现备份不可用 | 定期恢复到临时环境 |
| 把从库当备份 | 误删会同步到从库 | 从库和备份都要有 |
| WAL 归档失败没人知道 | PITR 链断裂 | 监控归档失败和 WAL 缺口 |
| 复制槽长期 inactive | WAL 堆积撑爆磁盘 | 监控 slot 和 WAL 保留量 |
| 所有读都走从库 | 刚写完查不到 | 核心读写一致走主库或做延迟感知 |
| 大事务导致复制延迟 | 从库长时间追不上 | 拆批、限速、监控 replay lag |
面试标准回答
PostgreSQL 备份恢复的核心是 WAL。pg_dump 是逻辑备份,适合迁移、单表恢复和中小库导出;pg_basebackup 是物理基础备份,适合整实例恢复和搭建从库。PITR 依赖基础备份加持续归档 WAL,恢复时先还原基础备份,再回放 WAL 到目标时间点。流复制通过主库发送 WAL、从库接收并重放 WAL 实现,只读扩展和高可用都依赖它。异步复制性能好但可能延迟和丢少量数据;同步复制一致性更强但会增加提交延迟。备份和高可用不是一回事,从库不能替代备份,生产必须按 RPO/RTO 设计策略并定期恢复演练。