Postgresql 中文操作指南

26.1. SQL Dump #

此转储方法的思想在于生成一个包含 SQL 命令的文件,这些命令在反馈给服务器后,会将数据库重新创建为与转储时相同的状态。PostgreSQL 为此提供了实用程序 pg_dump 。此命令的基本用法如下:

pg_dump dbname > dumpfile

正如你所看到的,pg_dump 将其结果写入标准输出。我们将在下面看到这如何发挥作用。上述命令创建一个文本文件,而 pg_dump 可以创建其他格式的文件,用于并行处理和更细致的对象还原控制。

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

若要指定 pg_dump 应该联系哪个数据库服务器,请使用命令行选项 -h _host and -p _port. The default host is the local host or whatever your PGHOST 指定的环境变量。类似地,默认端口由 PGPORT 环境变量或(如果没有环境变量则)由已编译默认值指定。(很方便的是,服务器通常具有相同的已编译默认值。)

与其他任何 PostgreSQL 客户端应用程序类似,pg_dump 默认情况下将使用与当前操作系统用户名相同的数据库用户名进行连接。要覆盖此连接方法,请指定 -U 选项或设置 PGUSER 环境变量。请记住,pg_dump 连接需遵守正常的客户端验证机制( Chapter 21 中有所描述)。

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

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

26.1.1. Restoring the Dump #

pg_dump 创建的文本文件旨在供 psql 程序读取。还原转储的一般命令格式为:

psql dbname < dumpfile

其中 dumpfile 是由 pg_dump 命令输出的文件。此命令不会创建数据库 dbname ,因此你必须在执行 psql 之前从 template0 手动创建它(例如,使用 createdb -T template0 _dbname_ )。psql 为指定要连接到的数据库服务器和要使用的用户名提供了类似于 pg_dump 的选项。有关更多信息,请参阅 psql 参考页。非文本文件转储使用 pg_restore 实用程序进行恢复。

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

默认情况下,在遇到 SQL 错误后,psql 脚本将继续执行。你可能希望使用 ON_ERROR_STOP 变量来运行 psql 来更改该行为,并在出现 SQL 错误时让 psql 以退出状态 3 退出:

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 25.1.3Section 25.1.6 。有关如何将大量数据高效加载到 PostgreSQL 中的更多建议,请参阅 Section 14.4

26.1.2. Using 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 命令,这就对于完全备份集群而言是必要的。

26.1.3. Handling Large Databases #

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

*Use compressed dumps. * 您可以使用您喜欢的压缩程序,例如 gzip:

pg_dump dbname | gzip > filename.gz

使用以下命令重新加载:

gunzip -c filename.gz | psql dbname

或:

cat filename.gz | gunzip | psql dbname

*Use split. * split 命令允许你将输出分割成更小的文件,这些文件的大小可以被底层文件系统接受。例如,要创建 2 千兆字节的大块:

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 进行还原。

*Use pg_dump’s custom dump format. * 如果 PostgreSQL 是在安装有 zlib 压缩库的系统上构建的,则自定义转储格式会在将数据写入输出文件时对数据进行压缩。这将生成类似于使用 gzip 的转储文件大小,但它具有可以有选择地还原表的附加优点。以下命令使用自定义转储格式转储数据库:

pg_dump -Fc dbname > filename

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

pg_restore -d dbname filename

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

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

*Use pg_dump’s parallel dump feature. * 为了加快大型数据库的转储速度,可以使用 pg_dump 的并行模式。这将同时转储多个表。你可以使用 -j 参数控制并行度。仅针对“目录”存档格式支持并行转储。

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

您可以使用 pg_restore -j 来并行还原转储。这适用于“custom”或“directory”存档模式的任何存档,无论是否使用 pg_dump -j 创建。