PostgreSQL实战指南:多领域数据库应用与实践


第六部分:PostgreSQL高级管理与优化

本部分聚焦于 PostgreSQL 的高级运维和管理,内容涵盖高可用架构、备份恢复、安全加固、性能诊断与调优,以及通过扩展开发来增强数据库功能。旨在帮助数据库管理员(DBA)和开发人员精通 PostgreSQL 的管理与维护,确保数据库系统的稳定、安全与高效。


第25章:备份与恢复策略

数据是企业最宝贵的资产,而可靠的备份与恢复策略是数据安全的最后一道防线。无论是由于硬件故障、软件 Bug、人为误操作还是恶意攻击导致数据丢失或损坏,一个经过良好测试的恢复计划都能让你化险为夷。本章将深入探讨 PostgreSQL 的各种备份方法,特别是强大的时间点恢复(PITR)技术。

25.1 备份类型

PostgreSQL 主要有两种备份方式:逻辑备份和物理备份。

  • 逻辑备份 (Logical Backup):
    • 工具: pg_dump, pg_dumpall
    • 原理: 重新生成用于创建数据库对象(表、索引等)的 SQL 语句和用于填充数据的 COPY 命令。
    • 优点: 格式为人类可读的文本或归档文件,非常灵活。可以跨 PostgreSQL 版本、跨操作系统、跨硬件架构进行恢复。可以只备份单个数据库、单个 schema 或单个表。
    • 缺点: 对于非常大的数据库,备份和恢复过程可能非常缓慢。恢复时需要重建索引,这会消耗大量时间。
  • 物理备份 (Physical Backup):
    • 工具: pg_basebackup, pgBackRest, Barman
    • 原理: 直接复制构成数据库集群的数据文件(二进制文件)。
    • 优点: 备份和恢复速度通常比逻辑备份快得多,特别是对于大型数据库。
    • 缺点: 不如逻辑备份灵活,通常只能在完全相同的 PostgreSQL 主版本、操作系统和硬件架构上进行恢复。
25.2 pg_dumppg_restore

pg_dump 是进行逻辑备份的标准工具。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 备份单个数据库为纯文本 SQL 文件
pg_dump my_database > my_database.sql

# 使用自定义格式 (-Fc) 进行备份,这是推荐的方式,因为它更灵活,支持并行恢复
pg_dump -Fc -f my_database.dump my_database

# 恢复纯文本 SQL 文件
psql -d new_database -f my_database.sql

# 从自定义格式的备份中恢复
# -d 指定目标数据库,它必须已存在且为空
pg_restore -d new_database my_database.dump

# 使用 -j 参数可以并行恢复,大幅提升速度
pg_restore -j 8 -d new_database my_database.dump
25.3 时间点恢复 (Point-in-Time Recovery, PITR)

PITR 是 PostgreSQL 最强大的数据保护功能之一。它允许你将数据库恢复到任意一个指定的时间点。例如,你可以恢复到“昨天下午3点半,在那个错误的 DELETE 语句执行之前”的状态。

PITR 的实现基于两部分:

  1. 一个基础物理备份: 使用 pg_basebackup 创建的数据库文件快照。
  2. 持续归档的 WAL 文件: WAL (Write-Ahead Log) 文件记录了数据库中发生的每一次更改。你需要配置 PostgreSQL,让它在写满一个 WAL 文件后,自动将其复制到一个安全的归档位置。

恢复过程:

  1. 从归档位置恢复基础物理备份。
  2. 创建一个 recovery.signal 文件(PostgreSQL 12+)或 recovery.conf 文件,在其中指定恢复的目标(例如,一个具体的时间点)。
  3. 启动 PostgreSQL。它会进入恢复模式,从 WAL 归档中读取并重放从基础备份结束到指定时间点的所有 WAL 记录,从而精确地重建数据库状态。
25.4 使用 pgBackRest 实现专业备份管理

虽然可以手动配置 PITR,但使用专业的备份管理工具(如 pgBackRest)能极大地简化流程并提供更多高级功能。pgBackRest 是一个开源、可靠、高性能的 PostgreSQL 备份与恢复工具。

pgBackRest 核心特性:

  • 并行备份与恢复: 大幅缩短操作时间。
  • 增量备份与差异备份: 极大地节省存储空间和备份时间。
  • 备份压缩: 进一步减少存储占用。
  • 备份校验: 确保备份文件的完整性和可恢复性。
  • 简单的配置与命令: 相比手动配置,更容易上手和管理。
25.5 场景实战:使用 pgBackRest 配置 PITR

业务场景描述:

为一个重要的生产数据库配置每日全量备份和持续的 WAL 归档,要求能够将数据库恢复到过去7天内的任意一分钟。

配置与操作 (概念性):

1. 安装 pgBackRest 在数据库服务器和专门的备份服务器上安装 pgBackRest

2. 配置 pgbackrest.conf

1
2
3
4
5
6
7
8
# /etc/pgbackrest.conf
[global]
repo1-path=/var/lib/pgbackrest  # 备份仓库路径
repo1-retention-full=7          # 保留7个全量备份
start-fast=y                    # 允许快速启动 checkpoint

[my_prod_db]
pg1-path=/var/lib/postgresql/14/main # 数据库的数据目录

3. 配置 postgresql.conf

1
2
3
# postgresql.conf
archive_mode = on
archive_command = 'pgbackrest --stanza=my_prod_db archive-push %p'

4. 创建 Stanza (备份配置集) Stanza 是 pgBackRest 中关于一个特定 PostgreSQL 集群的备份配置集合。

1
2
# 在备份服务器上执行
sudo -u postgres pgbackrest --stanza=my_prod_db stanza-create

5. 执行备份

1
2
3
4
5
6
7
8
# 执行一个全量备份
sudo -u postgres pgbackrest --stanza=my_prod_db backup

# 执行一个差异备份 (只备份自上次全量备份以来变化的文件)
# sudo -u postgres pgbackrest --stanza=my_prod_db backup --type=diff

# 执行一个增量备份 (只备份自上次任意类型备份以来变化的文件)
# sudo -u postgres pgbackrest --stanza=my_prod_db backup --type=incr

6. 执行恢复

假设在 2025-07-12 11:30:00 发生了误操作,需要恢复到 11:29:00

1
2
3
4
5
6
7
8
9
# 停止 PostgreSQL
# 清空数据目录
# rm -rf /var/lib/postgresql/14/main/*

# 执行恢复命令
sudo -u postgres pgbackrest --stanza=my_prod_db restore \
    --type=time "--target=2025-07-12 11:29:00"

# 恢复完成后,启动 PostgreSQL

代码解释与思考:

  • archive_command: 这是 PostgreSQL 与备份工具集成的关键。当 PostgreSQL 写满一个 WAL 段时,它会调用这个命令,并将 WAL 文件名作为 %p 参数传递。pgBackRestarchive-push 命令会接收这个文件,压缩并存储到备份仓库中。
  • Stanza: 使用 Stanza 将不同数据库集群的备份配置隔离开,使得管理多个集群的备份变得清晰。
  • 恢复流程: pgBackRestrestore 命令会自动找到最近的一个全量备份进行恢复,然后找到所有需要的 WAL 文件,并自动创建恢复所需的配置文件。整个过程比手动操作大大简化。
25.6 总结

本章我们系统地学习了 PostgreSQL 的备份与恢复策略。我们对比了逻辑备份和物理备份的优缺点,并掌握了 pg_dumppg_restore 的基本用法。我们重点深入了 PITR 的核心原理,并强烈推荐使用像 pgBackRest 这样的专业工具来自动化和简化备份管理。一个经过演练的、可靠的备份恢复策略是任何生产数据库的生命线。

在下一章,我们将探讨数据库的另一个重要方面:安全性管理与权限控制。