# pg_dump 与 pg_restore

> 使用纯文本和自定义格式的逻辑转储备份和恢复练习数据库。

---

LLMS 索引： [llms.txt](/llms.txt)

---

`pg_dump` 是 PostgreSQL 的标准备份工具。它会为单个数据库生成一致的快照，格式可以是纯文本 SQL 脚本，也可以是自定义格式的二进制归档。它的配套工具 `pg_restore` 可以读取二进制归档并将其恢复。对于整个集群的备份（`pg_dumpall`）、各表空间的数据备份以及时间点恢复，PostgreSQL 提供了单独的工具——但 `pg_dump` 已经覆盖了绝大多数“备份我的数据库”需求。遇到这类需求时，通常先用它。

## 本章要点 {#learn}

- 两种输出格式（纯文本 `.sql` 和自定义格式 `.dump`）
- 值得记住的 `pg_dump` 和 `pg_restore` 选项
- 仅转储数据库结构、仅转储数据，或两者都转储
- 包含或排除指定的表或模式
- 并行恢复以提高速度

**准备工作。** 这些是 Shell 命令，不是 SQL。请在终端中运行它们。本课的源文件只是对这些命令的简单封装和记录。

## 示例 {#example}

```bash {num="54.1" caption="pg_dump 与 pg_restore"}
# Plain-text SQL dump (human-readable, runnable with psql)
pg_dump --dbname=postgres --format=plain --file=backup.sql

# Custom-format dump (compressed binary, restorable with pg_restore)
pg_dump --dbname=postgres --format=custom --file=backup.dump

# Schema only (DDL, no data) — useful for reproducing the shape of a database
pg_dump --schema-only --dbname=postgres --file=schema.sql

# Data only (no DDL)
pg_dump --data-only --dbname=postgres --file=data.sql

# Dump only specific tables (or use --exclude-table)
pg_dump --table=fruits --table=orders_example --dbname=postgres --file=subset.sql

# Dump only one schema
pg_dump --schema=app --dbname=postgres --file=app_schema.dump --format=custom

# Restore from a custom-format dump
pg_restore --dbname=postgres --jobs=4 --clean --if-exists backup.dump

# Restore a plain SQL dump
psql --dbname=postgres --file=backup.sql

# Dump every database in the cluster, plus roles and globals
pg_dumpall --file=cluster.sql
```

**自定义格式**（`--format=custom` 或 `-Fc`）是大多数团队使用的格式。它默认经过压缩，支持并行恢复（`--jobs=N`），还可以选择性地恢复单个对象（先运行 `pg_restore --list backup.dump` 查看清单，再使用 `--use-list` 选择要恢复的对象）。纯文本格式更容易阅读和用 grep 搜索，但灵活性较低。

`pg_dump` 使用一致快照，并对要转储的表获取 `ACCESS SHARE` 锁。并发数据变更不会使该快照失效，普通写入者可以继续工作。与之冲突的 DDL 可能需要等待，也可能导致转储失败；并行转储使用同步快照。

`--clean --if-exists` 会在重新创建归档中包含的对象之前先删除它们；它不会删除所有无关对象，也不能保证恢复过程不报错。为了得到可预测的结果，请恢复到一个全新的练习数据库。`--jobs=4` 可以加快自定义格式或目录格式的恢复。

对于生产环境的备份，`pg_dump` 是策略的一部分，但不是全部。*持续归档*（`archive_mode = on`）加上基础备份（`pg_basebackup`）可以提供时间点恢复。云托管的 PostgreSQL 会透明地处理这些工作。

## 运行示例 {#run}

运行方式（这是一个 Shell 示例——记录这些命令的 SQL 文件可供参考）：

```text
$ pg_dump --dbname=postgres --format=custom --file=backup.dump
$ pg_restore --dbname=postgres --clean --if-exists --jobs=4 backup.dump
```

## 常见陷阱 {#pitfalls}

- 使用 `pg_dumpall --globals-only` 备份角色和表空间。它和 `pg_dump` 都不会备份复制槽；如有需要，请单独记录并重新创建复制槽。
- 恢复到已经存在该模式的数据库会产生冲突。可以使用 `--clean --if-exists`，删除并重新创建数据库，或者恢复到一个空数据库。
- 使用 `psql` 恢复纯文本 SQL 转储时，默认不会在第一个错误处停止——传入 `-v ON_ERROR_STOP=1`，让它在出错时直接失败。
- 版本兼容性：`pg_dump` 不能转储比自身大版本更新的服务器。转储文件的用途是恢复到相同或更高的 PostgreSQL 大版本；恢复到更低的大版本并无保证。升级时，如果目标大版本的 `pg_dump` 支持源服务器，应使用它。

> [!TIP] 提示
> `pg_dump -t my_table -Fc db | pg_restore -t my_table -d other_db` 可以通过一条管道将一个数据库中的一张表复制到另一个数据库，而无需中间文件——适合移动快照。

> [!NOTE] 动手练习
> 转储你的练习数据库，删除一张表，然后从转储中恢复它。运行 `pg_restore --list backup.dump` 查看对象清单。尝试运行 `pg_restore --schema-only`，只在全新的数据库上重新创建结构。

## 下载 {#downloads}

SQL 文件：[pg-dump-and-restore.sql](/examples/source/pg-dump-and-restore.sql) · [全部示例文件](/examples/examples.zip) · [准备工作](/#prerequisites)
