25.1. SQL 转储

此转储方法的思想是使用 SQL 命令生成一个文件,当该文件反馈到服务器时,它将以与转储时相同的状态重新创建数据库。 PostgreSQL 为此提供了 Utilpg_dump。该命令的基本用法是:

pg_dump dbname > dumpfile

如您所见,pg_dump 将其结果写入标准输出。我们将在下面看到如何使用。在上述命令创建文本文件的同时,pg_dump 可以创建其他格式的文件,这些格式允许并行化以及对对象恢复的更细粒度控制。

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

要指定应与哪个数据库服务器 pg_dump 联系,请使用命令行选项-h host-p port。默认主机是 localhost 或您的PGHOST环境变量指定的主机。同样,默认端口由PGPORT环境变量指示,否则,由编译后的默认变量指示。 (通常,服务器通常具有相同的内置默认值.)

与其他任何 PostgreSQLClient 端应用程序一样,pg_dump 默认情况下将使用与当前 os 用户名相同的数据库用户名进行连接。要覆盖此设置,请指定-U选项或设置环境变量PGUSER。请记住,pg_dump 连接必须遵循常规的 Client 端身份验证机制(在Chapter 20中进行了描述)。

与稍后介绍的其他备份方法相比,pg_dump 的一个重要优势在于,通常可以将 pg_dump 的输出重新加载到 PostgreSQL 的较新版本中,而文件级备份和连续归档都非常依赖于服务器版本。 pg_dump 也是将数据库传输到其他计算机体系结构(例如从 32 位服务器转换为 64 位服务器)时唯一可用的方法。

pg_dump 创建的转储在内部是一致的,这意味着转储表示 pg_dump 开始运行时数据库的快照。 pg_dump 在工作时不会阻止对数据库的其他操作。 (exceptions 是那些需要使用排他锁进行操作的操作,例如大多数形式的ALTER TABLE.)

25 .1.1. 恢复转储

pg_dump 创建的文本文件应由 psql 程序读取。恢复转储的一般命令格式为

psql dbname < dumpfile

其中* dumpfile 是 pg_dump 命令输出的文件。该命令不会创建数据库 dbname *,因此在执行 psql(例如,使用createdb -T template0 dbname)之前,必须先从template0创建数据库。 psql 支持类似于 pg_dump 的选项,用于指定要连接的数据库服务器和要使用的用户名。有关更多信息,请参见psql参考页。使用pg_restoreUtil 还原非文本文件转储。

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

默认情况下,遇到 SQL 错误后,psql 脚本将 continue 执行。您可能希望在设置了ON_ERROR_STOP变量的情况下运行 psql 来更改该行为,并在发生 SQL 错误时以 3 的退出状态退出 psql:

psql --set ON_ERROR_STOP=on dbname < dumpfile

无论哪种方式,您都只会拥有部分还原的数据库。或者,您可以指定将整个转储作为单个事务进行还原,因此还原可以完全完成或完全回滚。可以通过将-1--single-transaction命令行选项传递给 psql 来指定此模式。使用此模式时,请注意,即使是很小的错误也可以回滚已经运行了多个小时的还原。但是,与部分还原的转储之后手动清理复杂的数据库相比,这仍然是更好的选择。

pg_dump 和 psql 能够对管道进行写入或读取,从而可以将数据库直接从一台服务器转储到另一台服务器,例如:

pg_dump -h host1 dbname | psql -h host2 dbname

Important

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

还原备份后,明智的做法是在每个数据库上运行ANALYZE,以便查询优化器具有有用的统计信息。有关更多信息,请参见Section 24.1.3Section 24.1.6。有关如何将大量数据有效地加载到 PostgreSQL 的更多建议,请参考Section 14.4

25 .1.2. 使用 pg_dumpall

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 命令,则对于完全备份集群是必需的。

25 .1.3. 处理大型数据库

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

使用压缩转储. 您可以使用自己喜欢的压缩程序,例如 gzip:

pg_dump dbname | gzip > filename.gz

Reload with:

gunzip -c filename.gz | psql dbname

or:

cat filename.gz | gunzip | psql dbname

使用split. split命令允许您将输出拆分为较小的文件,这些文件的大小对于基础文件系统是可接受的。例如,要制作 1 兆字节的块:

pg_dump dbname | split -b 1m - filename

Reload with:

cat filename* | psql dbname

使用 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创建。