9.3 9.4 9.5 9.6 10 11 12 13 14 15 16 17 Current(18)
PostgreSQL中文社区 问题报告 纠错本页面

25.1. SQL Dump #

25.1.1. 从转储中恢复
25.1.2. 使用pg_dumpall
25.1.3. 处理大型数据库

SQL转储方法的思想是创建一个由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或(如果PGPORT不存在)内建的默认值。(服务器通常有相同的默认值,所以还算方便。)

和任何其他PostgreSQL客户端应用一样,pg_dump默认使用与当前操作系统用户名同名的数据库用户名进行连接。要覆盖此行为,要么声明-U选项,要么设置环境变量PGUSER。请注意pg_dump的连接也要通过正常的客户端认证机制(在第 20 章里描述)。

pg_dump对于其他备份方法的一个重要优势是,pg_dump的输出可以很容易地在新版本的PostgreSQL中载入,而文件级备份和连续归档都是极度的服务器版本特定的。pg_dump也是唯一可以将一个数据库传送到一个不同机器架构上的方法,例如从一个32位服务器到一个64位服务器。

pg_dump创建的备份在内部是一致的,也就是说,转储表现了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工具进行恢复。

在开始恢复之前,转储库中对象的拥有者以及在其上被授予了权限的用户必须已经存在。如果它们不存在,那么恢复过程将无法将对象创建成具有原来的所属关系以及权限(有时候这就是你所需要的,但通常不是)。

默认情况下,psql脚本在遇到SQL错误后会继续执行。您可能希望通过设置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吉字节:

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创建的。