PostgreSQL 备份到底是怎么工作的:从逻辑导出到物理恢复

2026-07-24 22 预计阅读时间: 1 分钟
来源: planetscale.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

备份的价值不只在于“生成一个文件”,更在于关键数据损坏、误删或服务故障后,能否按预期恢复。理解 PostgreSQL 备份的工作方式,有助于选择合适的工具,也能避免只备份、不验证的假安全感。

备份实际上保存了什么

PostgreSQL 备份大致可以分成两类:逻辑备份和物理备份。

逻辑备份保存的是数据库对象和数据的逻辑表示,例如表结构、数据行、索引定义、权限以及其他对象。pg_dump 生成的备份通常可以恢复到另一个数据库,甚至可以用于不同版本之间的迁移,但恢复过程需要重新执行 SQL 或导入归档内容。

物理备份保存的是数据库集群在磁盘上的物理状态。pg_basebackup 可以复制一个可用于恢复的基础备份;配合预写式日志(WAL),还可以把数据库恢复到基础备份之后的某个时间点。物理备份更适合灾难恢复和较大数据库,但对 PostgreSQL 版本、目录结构及运行环境有更严格的要求。

可以把两者理解为:逻辑备份记录“数据库应该由哪些对象和数据组成”,物理备份记录“数据库文件在某个时刻是什么状态”。

pg_dump:方便迁移的逻辑备份

逻辑备份适合以下场景:

  • 备份单个数据库或部分对象
  • 将数据迁移到另一套 PostgreSQL 环境
  • 需要查看、筛选或编辑导出的 SQL
  • 数据量尚未大到恢复时间不可接受

一个可直接改造的示例:

#!/usr/bin/env bash
set -euo pipefail

DB_NAME="app"
DB_HOST="127.0.0.1"
DB_PORT="5432"
DB_USER="backup_user"
BACKUP_DIR="./backups"
STAMP="$(date +%Y%m%d_%H%M%S)"

mkdir -p "$BACKUP_DIR"

PGPASSWORD="$PGPASSWORD" pg_dump \
  --host "$DB_HOST" \
  --port "$DB_PORT" \
  --username "$DB_USER" \
  --format custom \
  --file "$BACKUP_DIR/${DB_NAME}_${STAMP}.dump" \
  "$DB_NAME"

printf 'Backup written to %s\n' "$BACKUP_DIR/${DB_NAME}_${STAMP}.dump"

运行前需要准备连接所需的 PGPASSWORD,或者更推荐使用 PostgreSQL 的 .pgpass 文件,避免把密码直接写进脚本。custom 格式不是纯文本 SQL,但可以通过 pg_restore 选择性恢复表、schema 或数据。

恢复到一个新数据库可以这样做:

createdb --host 127.0.0.1 --username postgres app_restore

pg_restore \
  --host 127.0.0.1 \
  --username postgres \
  --dbname app_restore \
  --clean \
  --if-exists \
  ./backups/app_20250101_120000.dump

这里的时间戳只是示例,实际使用时应替换为真实备份文件。恢复验证应在隔离数据库中进行,不要直接对生产库执行未经验证的恢复命令。

pg_basebackup 和 WAL:恢复到某个时间点

逻辑备份通常回答的是“如何重新创建数据”。物理备份则更接近“如何把数据库恢复到某个时间状态”。基础备份保存一份数据库集群的物理副本,而 WAL 记录数据库发生过的变更。恢复时,PostgreSQL 先从基础备份开始,再重放后续 WAL。

这种机制可以支持时间点恢复(PITR)。例如,操作人员误删数据后,可以选择恢复到误操作发生之前的时间点,而不必只回到最近一次完整备份的时间。

基础备份命令可以参考下面的形式:

pg_basebackup \
  --host 127.0.0.1 \
  --port 5432 \
  --username replication_user \
  --pgdata ./basebackup \
  --format tar \
  --gzip \
  --progress \
  --wal-method stream

这条命令的具体可用性取决于数据库用户权限、复制配置、WAL 归档设置和 PostgreSQL 版本。生产环境中还需要明确备份目录的存储位置、保留周期、加密方式以及传输到异地存储的策略。

逻辑备份和物理备份并不是互相替代的关系。逻辑备份便于迁移和对象级恢复,物理备份加 WAL 更适合快速恢复整套数据库和应对较大的数据量。

真正可靠的备份需要测试恢复

备份任务显示“成功”并不代表灾难发生时一定能恢复。至少应定期检查以下内容:

  1. 备份文件是否存在,大小是否异常。
  2. 备份是否能在独立环境中恢复。
  3. 恢复后的关键表、行数和业务查询是否符合预期。
  4. 从故障发生到服务恢复需要多长时间,即实际恢复时间是否满足目标。
  5. 备份文件是否受到访问控制和加密保护。
  6. WAL 或增量恢复所需的日志是否完整,保留时间是否覆盖业务要求。

一个简单的逻辑备份校验流程可以是:创建临时数据库、执行 pg_restore、运行若干关键查询,然后删除临时数据库。不要只检查文件名和文件大小,因为一个格式正确但内容不完整的备份仍然可能无法满足恢复目标。

如何选择方案

小型应用通常可以从定期 pg_dump 开始,并把备份复制到与数据库不同的存储位置。随着数据量增长或恢复时间要求提高,应考虑基础备份、WAL 归档以及自动化的时间点恢复流程。

采用前先明确三个问题:允许丢失多少数据,允许停机多久,以及是否需要恢复单张表而不是整套集群。前两个问题决定备份频率和恢复架构,第三个问题决定是否必须保留逻辑备份。

最后,把恢复演练纳入日常运维。备份系统的完成标准不是“每天产生文件”,而是团队能够在压力下找到正确的备份、知道恢复步骤,并证明恢复结果可用。


相关推荐