备份的价值不只在于“生成一个文件”,更在于关键数据损坏、误删或服务故障后,能否按预期恢复。理解 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 更适合快速恢复整套数据库和应对较大的数据量。
真正可靠的备份需要测试恢复
备份任务显示“成功”并不代表灾难发生时一定能恢复。至少应定期检查以下内容:
- 备份文件是否存在,大小是否异常。
- 备份是否能在独立环境中恢复。
- 恢复后的关键表、行数和业务查询是否符合预期。
- 从故障发生到服务恢复需要多长时间,即实际恢复时间是否满足目标。
- 备份文件是否受到访问控制和加密保护。
- WAL 或增量恢复所需的日志是否完整,保留时间是否覆盖业务要求。
一个简单的逻辑备份校验流程可以是:创建临时数据库、执行 pg_restore、运行若干关键查询,然后删除临时数据库。不要只检查文件名和文件大小,因为一个格式正确但内容不完整的备份仍然可能无法满足恢复目标。
如何选择方案
小型应用通常可以从定期 pg_dump 开始,并把备份复制到与数据库不同的存储位置。随着数据量增长或恢复时间要求提高,应考虑基础备份、WAL 归档以及自动化的时间点恢复流程。
采用前先明确三个问题:允许丢失多少数据,允许停机多久,以及是否需要恢复单张表而不是整套集群。前两个问题决定备份频率和恢复架构,第三个问题决定是否必须保留逻辑备份。
最后,把恢复演练纳入日常运维。备份系统的完成标准不是“每天产生文件”,而是团队能够在压力下找到正确的备份、知道恢复步骤,并证明恢复结果可用。