2025年9月25日: PostgreSQL 18 发布!
支持的版本:当前18)/ 17 / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2

25.1. SQL转储 #

此转储方法的理念是生成一个包含 SQL 命令的文件,当将这些命令重新馈送到服务器时,将重新创建数据库,使其恢复到转储时的状态。PostgreSQL为此目的提供了实用程序 pg_dump。该命令的基本用法是

pg_dump dbname > dumpfile

正如您所见,pg_dump 将其结果写入标准输出。下面我们将看到这如何有用。虽然上面的命令创建了一个文本文件,但 pg_dump 可以创建其他格式的文件,这些格式允许并行处理和更精细地控制对象的恢复。

pg_dump 是一个常规的 PostgreSQL 客户端应用程序(尽管是一个特别聪明的应用程序)。这意味着您可以从任何能够访问数据库的远程主机执行此备份过程。但请记住,pg_dump 不会以特殊权限运行。特别是,它必须具有对您想要备份的所有表的读取访问权限,因此为了备份整个数据库,您几乎总是需要以数据库超级用户的身份运行它。(如果您没有足够的权限来备份整个数据库,您仍然可以使用 -n schema-t table 等选项备份您有权访问的数据库部分。)

要指定 pg_dump 应该联系哪个数据库服务器,请使用命令行选项 -h host-p port。默认主机是本地主机,或者您的 PGHOST 环境变量指定的任何内容。同样,默认端口由 PGPORT 环境变量指示,或者在没有该变量的情况下,由编译时默认值指示。(方便的是,服务器通常具有相同的编译时默认值。)

与其他任何 PostgreSQL 客户端应用程序一样,pg_dump 默认将以与当前操作系统用户名相同的数据库用户名进行连接。要覆盖此设置,请指定 -U 选项或设置环境变量 PGUSER。请记住,pg_dump 连接受常规客户端身份验证机制(在第 20 章中描述)的约束。

pg_dump 相对于后面描述的其他备份方法的一个重要优点是,pg_dump 的输出通常可以重新加载到较新版本的 PostgreSQL 中,而文件级备份和连续归档都与服务器版本高度相关。pg_dump 也是在将数据库传输到不同机器架构(例如从 32 位服务器迁移到 64 位服务器)时唯一可行的方法。

pg_dump 创建的转储是内部一致的,这意味着转储代表了 pg_dump 开始运行时数据库的快照。pg_dump 在工作时不会阻止数据库上的其他操作。(例外情况是那些需要以独占锁运行的操作,例如大多数形式的 ALTER TABLE。)

25.1.1. 恢复转储 #

pg_dump 创建的文本文件旨在由 psql 程序使用其默认设置进行读取。恢复文本转储的通用命令形式是

psql -X dbname < dumpfile

其中 dumpfile 是由 pg_dump 命令输出的文件。此命令不会创建 dbname 数据库,因此您必须在执行 psql 之前从 template0 创建它(例如,使用 createdb -T template0 dbname)。为确保 psql 以其默认设置运行,请使用 -X--no-psqlrc)选项。psql 支持类似于 pg_dump 的选项,用于指定要连接的数据库服务器和要使用的用户名。有关更多信息,请参阅 psql 参考页。

应使用 pg_restore 实用程序恢复非文本文件转储。

在恢复 SQL 转储之前,所有拥有对象或在转储数据库中被授予对象权限的用户必须已存在。如果不存在,则恢复将无法以原始所有权和/或权限重新创建对象。(有时这就是您想要的,但通常不是。)

默认情况下,SQL 错误发生后,psql 脚本将继续执行。您可能希望运行 psql 并将 ON_ERROR_STOP 变量设置为更改此行为,并使 psql 在发生 SQL 错误时以退出状态 3 退出

psql -X --set ON_ERROR_STOP=on dbname < dumpfile

无论哪种方式,您只会得到一个部分恢复的数据库。或者,您可以指定整个转储应作为单个事务恢复,这样恢复就会完全完成或完全回滚。此模式可以通过将 -1--single-transaction 命令行选项传递给 psql 来指定。使用此模式时,请注意,即使是微小的错误也可能回滚已运行数小时的恢复。但是,这可能仍然比手动清理复杂的数据库(在部分恢复的转储之后)更好。

pg_dumppsql 能够读写管道,这使得可以直接将数据库从一个服务器转储到另一个服务器,例如

pg_dump -h host1 dbname | psql -X -h host2 dbname

重要提示

pg_dump 生成的转储是相对于 template0 的。这意味着通过 template1 添加的任何语言、过程等也将由 pg_dump 转储。因此,在恢复时,如果您使用的是自定义的 template1,则必须从 template0 创建空数据库,如上面的示例所示。

在恢复备份后,明智的做法是对每个数据库运行 ANALYZE,以便查询优化器拥有有用的统计信息;有关更多信息,请参阅第 24.1.3 节第 24.1.6 节。有关如何高效地将大量数据加载到 PostgreSQL 中的更多建议,请参阅第 14.4 节

25.1.2. 使用 pg_dumpall #

pg_dump 一次只能转储一个数据库,并且不转储有关角色或表空间的信息(因为这些是集群范围的,而不是每个数据库的)。为了方便地转储数据库集群的全部内容,提供了 pg_dumpall 程序。pg_dumpall 会备份给定集群中的每个数据库,并保留集群范围的数据,如角色和表空间定义。该命令的基本用法是

pg_dumpall > dumpfile

生成的转储可以使用 psql 进行恢复

psql -X -f dumpfile postgres

(实际上,您可以指定任何现有的数据库名称作为起点,但如果您正在加载到一个空集群,则通常应使用 postgres。)恢复 pg_dumpall 转储时,始终需要数据库超级用户访问权限,因为这是恢复角色和表空间信息所必需的。如果您使用了表空间,请确保转储中的表空间路径适合新安装。

pg_dumpall 的工作方式是发出命令来重新创建角色、表空间和空数据库,然后为每个数据库调用 pg_dump。这意味着虽然每个数据库将是内部一致的,但不同数据库的快照不是同步的。

可以使用 pg_dumpall--globals-only 选项单独转储集群范围的数据。这对于在单独的数据库上运行 pg_dump 命令时完全备份集群是必需的。

25.1.3. 处理大型数据库 #

某些操作系统有最大文件大小限制,这在创建大型 pg_dump 输出文件时会导致问题。幸运的是,pg_dump 可以写入标准输出,因此您可以使用标准的 Unix 工具来解决此潜在问题。有几种可能的方法:

使用压缩转储。 您可以使用您喜欢的压缩程序,例如 gzip

pg_dump dbname | gzip > filename.gz

使用以下命令重新加载:

gunzip -c filename.gz | psql dbname

cat filename.gz | gunzip | psql dbname

使用 split。 split 命令允许您将输出分割成对底层文件系统大小可接受的更小文件。例如,创建 2 GB 的块:

pg_dump dbname | split -b 2G - filename

使用以下命令重新加载:

cat filename* | psql dbname

如果使用 GNU split,则可以将它与 gzip 一起使用:

pg_dump dbname | split -b 2G --filter='gzip > $FILE.gz'

可以使用 zcat 进行恢复。

使用 pg_dump 的自定义转储格式。 如果 PostgreSQL 是在安装了 zlib 压缩库的系统上构建的,则自定义转储格式在写入输出文件时将压缩数据。这将产生与使用 gzip 相似的转储文件大小,但它还有一个额外的优点,即可以有选择地恢复表。以下命令使用自定义转储格式转储数据库:

pg_dump -Fc dbname > filename

自定义格式的转储不是用于 psql 的脚本,而是必须使用 pg_restore 进行恢复,例如:

pg_restore -d dbname filename

有关详细信息,请参阅 pg_dumppg_restore 参考页。

对于非常大的数据库,您可能需要将 split 与其他两种方法之一结合使用。

使用 pg_dump 的并行转储功能。 要加快大型数据库的转储速度,可以使用 pg_dump 的并行模式。这将同时转储多个表。您可以使用 -j 参数控制并行度。并行转储仅支持“目录”存档格式。

pg_dump -j num -F d -f out.dir dbname

您可以使用 pg_restore -j 来并行恢复转储。这适用于任何“自定义”或“目录”存档模式的存档,无论它是否是用 pg_dump -j 创建的。

提交更正

如果您在文档中看到任何不正确的内容、与您对特定功能的体验不符或需要进一步澄清的内容,请使用此表单报告文档问题。