↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 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 已于 2007 年 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参考页。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。