这种导出方法的原理是生成一个包含 SQL 命令的文件,这些命令在反馈回服务器后,将重新创建数据库,使其状态与导出时相同。 PostgreSQL 提供了实用程序 pg_dump 用于此目的。此命令的基本用法如下:
pg_dumpdbname
>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
。)
由 pg_dump 创建的文本文件旨在由 psql 程序读取。恢复转储的一般命令形式如下:
psqldbname
<dumpfile
其中 dumpfile
是 pg_dump 命令输出的文件。数据库 dbname
不会由此命令创建,因此您必须在执行 psql 之前从 template0
自己创建它(例如,使用 createdb -T template0
)。psql 支持类似于 pg_dump 的选项,用于指定要连接到的数据库服务器和要使用的用户名。有关更多信息,请参阅 psql 参考页面。非文本文件转储使用 pg_restore 实用程序恢复。dbname
在恢复 SQL 转储之前,所有拥有转储数据库中对象的或被授予对象权限的用户都必须已存在。如果不存在,则恢复将无法使用原始所有权和/或权限重新创建对象。(有时这是您想要的,但通常不是。)
默认情况下,psql 脚本将在遇到 SQL 错误后继续执行。您可能希望使用设置了 ON_ERROR_STOP
变量的 psql 来更改此行为,如果发生 SQL 错误,则使 psql 退出并返回退出状态 3
psql --set ON_ERROR_STOP=ondbname
<dumpfile
无论哪种方式,您都只会拥有一个部分恢复的数据库。或者,您可以指定整个转储应作为单个事务恢复,因此恢复要么完全完成,要么完全回滚。此模式可以通过将 -1
或 --single-transaction
命令行选项传递给 psql 来指定。使用此模式时,请注意,即使是微小的错误也可能回滚已经运行了数小时的恢复。但是,这可能仍然优于在部分恢复的转储后手动清理复杂的数据库。
pg_dump 和 psql 能够写入或读取管道,这使得可以将数据库直接从一台服务器转储到另一台服务器,例如
pg_dump -hhost1
dbname
| psql -hhost2
dbname
由 pg_dump 生成的转储相对于 template0
。这意味着通过 template1
添加的任何语言、过程等也将由 pg_dump 转储。因此,在恢复时,如果您使用的是自定义的 template1
,则必须从 template0
创建空数据库,如上例所示。
恢复备份后,建议在每个数据库上运行 ANALYZE
,以便查询优化器拥有有用的统计信息;有关更多信息,请参阅第 24.1.3 节和第 24.1.6 节。有关如何有效地将大量数据加载到 PostgreSQL 中的更多建议,请参阅第 14.4 节。
pg_dump 每次只转储一个数据库,并且它不转储有关角色或表空间的信息(因为这些信息是集群范围的,而不是每个数据库的)。为了支持方便地转储数据库集群的全部内容,提供了 pg_dumpall 程序。pg_dumpall 备份给定集群中的每个数据库,并且还保留集群范围的数据,例如角色和表空间定义。此命令的基本用法如下:
pg_dumpall > dumpfile
可以使用 psql 恢复生成的转储
psql -f dumpfile
postgres
(实际上,您可以指定任何现有的数据库名称作为起始点,但是如果您要加载到空集群中,则通常应使用 postgres
。)在恢复 pg_dumpall 转储时,始终需要具有数据库超级用户访问权限,因为这需要恢复角色和表空间信息。如果您使用表空间,请确保转储中的表空间路径适合新安装。
pg_dumpall 通过发出重新创建角色、表空间和空数据库的命令来工作,然后为每个数据库调用 pg_dump。这意味着虽然每个数据库在内部都是一致的,但不同数据库的快照没有同步。
可以使用 pg_dumpall --globals-only
选项单独转储集群范围的数据。如果在各个数据库上运行 pg_dump 命令,则必须完全备份集群。
某些操作系统具有最大文件大小限制,这在创建大型 pg_dump 输出文件时会导致问题。幸运的是,pg_dump 可以写入标准输出,因此您可以使用标准的 Unix 工具来解决此潜在问题。有几种可能的方法
使用压缩转储。您可以使用您喜欢的压缩程序,例如 gzip
pg_dumpdbname
| gzip >filename
.gz
使用以下命令重新加载:
gunzip -cfilename
.gz | psqldbname
或
catfilename
.gz | gunzip | psqldbname
使用 split
。split
命令允许您将输出拆分为较小的文件,这些文件的大小在底层文件系统中是可以接受的。例如,要创建 2 GB 的块
pg_dumpdbname
| split -b 2G -filename
使用以下命令重新加载:
catfilename
* | psqldbname
如果使用 GNU split,可以将其与 gzip 结合使用。
pg_dump dbname
| split -b 2G --filter='gzip > $FILE.gz'
可以使用 zcat
恢复。
使用 pg_dump 的自定义转储格式。 如果 PostgreSQL 在安装了 zlib 压缩库的系统上构建,则自定义转储格式会在将数据写入输出文件时对其进行压缩。这将生成与使用 gzip
类似的转储文件大小,但它还具有可以选择性地恢复表的额外优势。以下命令使用自定义转储格式转储数据库
pg_dump -Fcdbname
>filename
自定义格式的转储不是 psql 的脚本,而必须使用 pg_restore 恢复,例如
pg_restore -ddbname
filename
有关详细信息,请参阅 pg_dump 和 pg_restore 参考页面。
对于非常大的数据库,您可能需要将 split
与其他两种方法之一结合使用。
使用 pg_dump 的并行转储功能。 为了加快大型数据库的转储速度,可以使用 pg_dump 的并行模式。这将同时转储多个表。您可以使用 -j
参数控制并行度。并行转储仅支持“目录”归档格式。
pg_dump -jnum
-F d -fout.dir
dbname
您可以使用 pg_restore -j
并行恢复转储。这适用于“自定义”或“目录”归档模式的任何归档,无论它是否使用 pg_dump -j
创建。
如果您在文档中发现任何不正确的内容、与您对特定功能的体验不符的内容或需要进一步说明的内容,请使用 此表单 报告文档问题。