↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本。 PostgreSQL 7.2 已结束支持。 请参阅 当前版本手册.

第 9 章 备份与恢复

与任何包含有价值数据的事物一样,PostgreSQL 数据库也应定期备份。虽然这个过程基本上很简单,但理解其底层技术和前提假设的基本概念非常重要。

备份PostgreSQL数据有两种根本不同的方法:

  • SQL 转储

  • 文件系统级别的备份

9.1. SQL 转储 #

SQL 转储方法的思路是生成一个包含 SQL 命令的文本文件,当把这些命令送回服务器时,服务器会把数据库重建为转储时的状态。PostgreSQL为此提供了工具程序 pg_dump。该命令的基本用法是:

pg_dump dbname > outfile

如你所见,pg_dump把结果写到标准输出。我们将在下面看到这样做的用处。

pg_dump是一个常规的PostgreSQL 客户端应用(尽管是一个特别聪明的应用)。这意味着你可以从任何能访问数据库的远程主机上执行这个备份过程。但请记住, pg_dump并不会以特殊的权限运行。特别是,你必须对所有想要备份的表拥有读权限,因此在实践中你几乎总是必须是数据库超级用户。

要指定pg_dump应当连接哪个数据库服务器,可以使用命令行选项-h host和-p port。默认主机是本地主机,或者由PGHOST环境变量指定的主机。类似地,默认端口由PGPORT环境变量指示,若未设置,则使用编译时的默认值。(方便的是,服务器通常也有相同的编译时默认值。)

与任何其他PostgreSQL客户端应用一样, pg_dump默认以与当前 Unix 用户名相同的数据库用户名连接。要覆盖这一行为,可以指定-U选项或设置环境变量PGUSER。请记住,pg_dump 的连接同样受常规的客户端认证机制约束(这些机制在第 4 章中描述)。

pg_dump创建的转储在内部是一致的,也就是说, pg_dump运行期间对数据库的更新不会出现在转储中。 pg_dump工作时不会阻塞数据库上的其他操作。(例外是那些需要以排他锁运行的操作,例如VACUUM FULL。)

重要

当你的数据库模式依赖于 OID(例如用作外键)时,你必须指示 pg_dump把 OID 也一并转储。为此,可以使用 -o命令行选项。“大对象”默认也不会被转储。如果你使用了大对象,请参阅pg_dump的命令参考页。

9.1.1. 恢复转储 #

pg_dump创建的文本文件应由psql 程序读入。恢复转储的一般命令形式是:

psql dbname < infile

其中infile就是你在 pg_dump 命令中用作outfile 的文件。数据库dbname不会由此命令创建,你必须在执行psql之前自己从 template0 创建它(例如用createdb -T template0 dbname)。 psql支持与pg_dump类似的用于控制数据库服务器位置和用户名的选项。更多信息见其参考页。

如果原始数据库中的对象属于不同的用户,那么转储会指示 psql依次以每个受影响的用户连接,然后创建相应的对象。这样便保留了原来的属主关系。然而,这也意味着所有这些用户必须已经存在,而且你必须被允许以每个用户的身份连接。因此,可能有必要临时放宽客户端认证设置。

pg_dump和psql能够写入或读取管道,这使得把一个数据库从一台服务器直接转储到另一台服务器成为可能,例如

pg_dump -h host1 dbname | psql -h host2 dbname

重要

pg_dump 产生的转储是相对于 template0 的。这意味着任何添加到 template1 中的语言、过程等也会被pg_dump转储。因此,恢复时如果你使用了定制的 template1,就必须像上面的例子那样从 template0 创建空数据库。

9.1.2. 使用pg_dumpall #

上述机制在备份整个数据库集群时既繁琐又不合适。为此提供了 pg_dumpall程序。pg_dumpall 备份给定集群中的每个数据库,同时确保用户和组等全局数据的状态得到保留。pg_dumpall的调用序列很简单:

pg_dumpall > outfile

得到的转储可以按上文所述用psql恢复。但这种情况下你肯定需要数据库超级用户权限,因为恢复用户和组信息需要这样的权限。

9.1.3. 大型数据库 #

致谢

本文最初由 Hannu Krosing()写于 1999-06-19

由于PostgreSQL允许表大于系统上的最大文件尺寸,把该表转储到一个文件可能会成问题,因为得到的文件很可能大于系统允许的最大尺寸。由于 pg_dump可以写到标准输出,你可以直接使用标准 *nix 工具来绕过这个潜在问题。

使用压缩转储。.  使用你喜欢的压缩程序,例如 gzip。

pg_dump dbname | gzip > filename.gz

恢复时用:

createdb dbname
gunzip -c filename.gz | psql dbname

或者:

cat filename.gz | gunzip | psql dbname

使用split。.  它允许你把输出分割成底层文件系统可接受大小的块。例如,要切分为 1 MB 的块:

pg_dump dbname | split -b 1m - filename

恢复时用:

createdb dbname
cat filename* | psql dbname

使用定制转储格式。.  如果PostgreSQL是在安装了zlib 压缩库的系统上构建的,定制转储格式会在把数据写入输出文件时压缩数据。对于大型数据库,这会产生与使用gzip 相当的转储尺寸,而且还有一个额外的优点:可以选择性地恢复部分表。下面的命令用定制转储格式转储一个数据库:

pg_dump -Fc dbname > filename

详情见pg_dump和pg_restore的参考页。

9.1.4. 注意事项 #

pg_dump(相应地也包括pg_dumpall)有一些限制,这些限制源于从系统目录中重建某些信息的困难。

具体来说,pg_dump写对象的顺序并不十分精巧。例如,当函数被用作列默认值时,这可能导致问题。唯一的解决办法是手动对转储重新排序。如果你在模式中创建了循环依赖,那么你要做的工作会更多。

出于向后兼容的原因,pg_dump默认不转储大对象。要转储大对象,你必须使用定制输出格式或 TAR 输出格式,并在 pg_dump中使用 -b 选项。详情见参考页。PostgreSQL源码树的 contrib/pg_dumplo目录中也包含一个可以转储大对象的程序。

请熟悉pg_dump参考页。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.