3. 逻辑备份工具pg_dump与pg_dumpall

逻辑备份与物理备份的根本差别在于:物理备份复制的是数据文件与 WAL 的字节级副本,而逻辑备份导出的是“可重放的 SQL 或可还原的归档数据”。PostgreSQL 提供的 pg_dump 与 pg_dumpall 就是逻辑备份的主力工具。理解它们的关键,不是记住命令参数,而是理解三件事:导出格式决定了还原方式与灵活性,一致性快照决定了备份是否“自洽”,全局对象与权限决定了还原后数据库是否“可用且可控”。

一、pg_dump 与 pg_dumpall 的职责边界

pg_dump 一次只针对一个数据库,导出该库内的模式、表、索引、约束、函数、触发器、序列、大对象以及数据本身。它不导出角色、表空间定义、数据库级配置等“实例级”对象。pg_dumpall 则面向整个实例,它先导出全局对象(角色、表空间、以及部分实例级设置),再对实例中的每个数据库依次调用 pg_dump 逻辑,从而形成一份覆盖全实例的脚本集合。因此,单库迁移、单库版本回退、按库做逻辑归档用 pg_dump;整实例搬迁、需要保留角色与表空间时用 pg_dumpall。

两者都通过普通 SQL 连接读取数据,因此可以在数据库在线、业务持续写入的情况下执行,不需要停库。这是逻辑备份最大的工程价值,也是它必须依赖一致性快照的原因。

二、四种导出格式与还原路径

pg_dump -F 决定输出格式,选择不同格式会直接改变后续的还原手段:

  • -Fp(plain,默认):输出纯文本 SQL 脚本,可用 psql -f 直接重放,便于人工查看和局部编辑,但无法并行还原,也不支持选择性还原单个表。
  • -Fc(custom):自定义二进制归档,必须用 pg_restore 还原。它支持压缩、支持 -j 并行还原、支持 -t 只还原指定表、-l 列出归档目录,是生产环境最常用的格式。
  • -Fd(directory):目录格式,把每个表的数据拆成独立文件并默认压缩,天然支持并行导出与并行还原,适合大型库。
  • -Ft(tar):tar 归档,兼容性一般,且不支持并行与选择性还原,实际使用较少。

一个典型的生产用法是:

pg_dump -h 10.0.0.12 -U backup_user -d appdb \
  -Fd -j 4 -f /backup/appdb_20240612 \
  --no-owner --no-privileges

这里 -j 4 表示用 4 个并行工作进程导出,-Fd 是并行导出的前提(custom 格式的导出阶段不能并行,只有还原阶段可以)。--no-owner 与 --no-privileges 则与下一节的权限问题直接相关。

三、并行备份:并行发生在哪一步

很多人误以为 -j 对任何格式都生效。实际上:导出阶段只有 directory 格式支持并行,因为每个表可以独立写成一个文件;custom 格式导出时是单进程顺序写归档。还原阶段 custom 与 directory 都支持 pg_restore -j 并行,因为还原时每个表、每个索引可以拆成独立任务。并行度并非越高越好,它受限于磁盘 IO、CPU 以及数据库可承受的连接数,通常设置为 CPU 核数或略高即可。

四、全局对象、权限与所有者

用 pg_dump 还原到新实例时,最常见的失败不是数据丢失,而是“角色不存在”“权限不足”。原因是 pg_dump 默认会在脚本中写入 ALTER TABLE ... OWNER TO xxx 以及 GRANT 语句,而目标实例可能没有同名角色。处理方式有三类:

  • 先用 pg_dumpall -g(或 --globals-only)导出角色与表空间,在目标实例先建好角色,再还原数据。
  • 导出时加 --no-owner --no-privileges,还原后对象归执行还原的用户所有,权限由后续统一授权脚本处理。
  • 用 pg_restore -O 在还原阶段忽略所有者信息。

需要强调的是,pg_dumpall 导出的角色包含口令哈希(若使用 md5/scram 存储),这属于敏感信息,备份文件必须按机密数据管理,不能随意放在共享目录。

五、一致性快照:逻辑备份为什么是自洽的

pg_dump 启动时会开启一个可重复读(REPEATABLE READ)事务,并在整个导出期间持有该事务的快照。这意味着:即使导出持续数十分钟、业务在不停写入,所有表读到的都是“备份开始那一刻”的一致视图,不会出现 A 表已包含新订单、B 表却还没有对应明细的撕裂现象。这是逻辑备份能够在线执行且结果可信的核心机制。

注意:一致性快照只保证“同一个 pg_dump 进程内部”一致。如果先跑 pg_dump 导 A 库、再跑一次导 B 库,两次快照时间点不同,跨库之间不保证一致。需要跨库一致时,应使用同一时刻的导出或改用物理备份/快照方案。

六、使用场景与选型

逻辑备份适合:版本升级迁移(跨大版本通常要求逻辑导出导入)、单表误删后的定向恢复、把生产数据裁剪后导入测试环境、跨平台/跨云搬迁、以及需要人工审阅 SQL 的合规场景。它不适合:TB 级全库的快速灾难恢复(还原慢、耗时长)、需要恢复到任意时间点(PITR 属于物理备份 + WAL 的领域)。

下面这张图把本节的核心关系集中呈现:两种工具的覆盖范围、四种格式的还原路径、并行发生的位置,以及一致性快照的作用点。

pg_dump / pg_dumpall 逻辑备份核心关系图 PostgreSQL 实例 全局对象 角色 / 表空间 / 实例设置 数据库 appdb 模式/表/索引/数据 数据库 reportdb 模式/表/索引/数据 一致性快照 REPEATABLE READ 事务 pg_dump 单库导出 · 不含角色/表空间 在线执行 · 依赖一致性快照 pg_dumpall 先导全局对象,再逐库调用 pg_dump 整实例搬迁 · 保留角色与表空间 导出格式(-F)与还原路径 -Fp 纯文本 psql -f 重放 不可并行 / 不可选表 适合小库与人工审阅 -Fc 自定义 pg_restore 还原 支持 -j 并行还原 支持 -t 选表还原 -Fd 目录 每表独立文件 导出与还原均可并行 大型库首选 -Ft tar 归档为 tar 不支持并行 使用较少 并行发生的位置 导出并行:仅 -Fd 支持(-j N) 还原并行:-Fc / -Fd 均支持 并行度受 IO / CPU / 连接数约束 权限与所有者处理 pg_dumpall -g 先建角色与表空间 --no-owner --no-privileges 跳过归属 角色口令哈希属敏感数据,需加密保管

七、一份可直接套用的备份命令清单

把上面的结论落成可执行清单,便于日常运维直接使用:

场景推荐命令要点还原方式
单库日常逻辑归档pg_dump -Fc -Z 6 -f appdb.dump appdbpg_restore -d appdb appdb.dump
大型库快速导出pg_dump -Fd -j 4 -f /backup/appdb appdbpg_restore -j 4 -d appdb /backup/appdb
整实例搬迁pg_dumpall -g -f globals.sql 再逐库 pg_dump先 psql -f globals.sql,再逐库还原
迁移到无同名角色的实例导出加 --no-owner --no-privileges还原后统一执行授权脚本
误删单表定向恢复已有 -Fc 归档pg_restore -t 表名 -d 目标库 归档
判断逻辑备份是否“够用”的三个问题:还原目标实例上角色是否已存在?备份文件是否包含所需格式以便选择性还原?备份期间业务写入是否被一致性快照正确隔离?三问都能回答,逻辑备份方案才算闭环。

最后要建立的一个认知是:pg_dump 与 pg_dumpall 解决的是“数据与对象的可移植性”,而不是“灾难发生时的最短恢复时间”。它们与后续要讲的物理备份、WAL 归档、PITR 是互补关系,而不是替代关系。选型时先问清楚恢复目标(RTO/RPO)和恢复粒度,再决定用逻辑还是物理,才是正确的顺序。