pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
与任何包含有价值数据的事物一样,PostgreSQL 数据库也应定期备份。虽然这个过程基本上很简单,但理解其 底层技术和前提假设的基本概念非常重要。
备份PostgreSQL数据有两种根本不同的方法:
SQL 转储
文件系统级别的备份
SQL 转储方法的思路是生成一个包含 SQL 命令的文本文件,当把这些命令 送回服务器时,服务器会把数据库重建为转储时的状态。 PostgreSQL为此提供了工具程序 pg_dump。该命令的基本用法是:
pg_dumpdbname>outfile
如你所见,pg_dump把结果写到标准输出。我们将在 下面看到这样做的用处。
pg_dump是一个常规的PostgreSQL 客户端应用(尽管是一个特别聪明的应用)。这意味着你可以从任何 能访问数据库的远程主机上执行这个备份过程。但请记住, pg_dump并不会以特殊的权限运行。特别是,你必须 对所有想要备份的表拥有读权限,因此在实践中你几乎总是必须是 数据库超级用户。
要指定pg_dump应当连接哪个数据库服务器,可以使用 命令行选项-h 和host-p 。默认 主机是本地主机,或者由portPGHOST环境变量指定的主机。 类似地,默认端口由PGPORT环境变量指示,若未设置, 则使用编译时的默认值。(方便的是,服务器通常也有相同的编译时 默认值。)
与任何其他PostgreSQL客户端应用一样, pg_dump默认以与当前操作系统用户名相同的数据库 用户名连接。要覆盖这一行为,可以指定-U选项或 设置环境变量PGUSER。请记住,pg_dump 的连接同样受常规的客户端认证机制约束(这些机制在第 6 章中描述)。
pg_dump创建的转储在内部是一致的,也就是说, pg_dump运行期间对数据库的更新不会出现在转储中。 pg_dump工作时不会阻塞数据库上的其他操作。 (例外是那些需要以排他锁运行的操作,例如VACUUM FULL。)
当你的数据库模式依赖于 OID(例如用作外键)时,你必须指示 pg_dump把 OID 也一并转储。为此,可以使用 -o命令行选项。“大对象”默认也不会被 转储。如果你使用了大对象,请参阅pg_dump的 命令参考页。
pg_dump创建的文本文件应由psql 程序读入。恢复转储的一般命令形式是:
psqldbname<infile
其中infile就是你 在pg_dump命令中用作outfile 的文件。数据库dbname不会由此命令创建,你必须 在执行psql之前自己从template0创建它 (例如用createdb -T template0 )。 psql支持与pg_dump类似的用于 控制数据库服务器位置和用户名的选项。更多信息见其参考页。dbname
如果原始数据库中的对象属于不同的用户,那么转储会指示 psql依次以每个受影响的用户连接,然后创建 相应的对象。这样便保留了原来的属主关系。然而,这也意味着 所有这些用户必须已经存在,而且你必须被允许以每个用户的 身份连接。因此,可能有必要临时放宽客户端认证设置。
pg_dump和psql能够写入或读取 管道,这使得把一个数据库从一台服务器直接转储到另一台服务器 成为可能;例如:
pg_dump -hhost1dbname| psql -hhost2dbname
pg_dump产生的转储是相对于template0 的。这意味着任何添加到template1中的语言、过程等 也会被pg_dump转储。因此,恢复时如果你使用了 定制的template1,就必须像上面的例子那样从 template0创建空数据库。
pg_dumpall #上述机制在备份整个数据库集群时既繁琐又不合适。为此提供了 pg_dumpall程序。pg_dumpall 备份给定集群中的每个数据库,同时确保用户和组等全局数据的 状态得到保留。pg_dumpall的调用序列很简单:
pg_dumpall > outfile
得到的转储可以按上文所述用psql恢复。但这种 情况下你肯定需要数据库超级用户权限,因为恢复用户和组信息 需要这样的权限。
本文最初由 Hannu Krosing (<hannu@trust.ee>)写于 1999-06-19
由于PostgreSQL允许表大于系统上 的最大文件尺寸,把该表转储到一个文件可能会成问题, 因为得到的文件很可能大于系统允许的最大尺寸。由于 pg_dump可以写到标准输出,你可以直接使用 标准 *nix 工具来绕过这个潜在问题。
使用压缩转储。. 使用你喜欢的压缩程序,例如 gzip。
pg_dumpdbname| gzip >filename.gz
恢复时用:
createdbdbnamegunzip -cfilename.gz | psqldbname
或者:
catfilename.gz | gunzip | psqldbname
使用split。. 它允许你把输出分割成底层文件系统 可接受大小的块。例如,要切分为 1 MB 的块:
pg_dumpdbname| split -b 1m -filename
恢复时用:
createdbdbnamecatfilename* | psqldbname
使用定制转储格式。. 如果PostgreSQL是在安装了zlib 压缩库的系统上构建的,定制转储格式会在把数据写入输出文件时 压缩数据。对于大型数据库,这会产生与使用gzip 相当的转储尺寸,而且还有一个额外的优点:可以选择性地恢复部分 表。下面的命令用定制转储格式转储一个数据库:
pg_dump -Fcdbname>filename
详情见pg_dump和pg_restore的 参考页。
pg_dump(相应地也包括pg_dumpall) 有一些限制,这些限制源于从系统目录中重建某些信息的困难。
具体来说,pg_dump写对象的顺序并不十分精巧。 例如,当函数被用作列默认值时,这可能导致问题。唯一的解决办法 是手动对转储重新排序。如果你在模式中创建了循环依赖,那么 你要做的工作会更多。
出于向后兼容的原因,pg_dump默认 不转储大对象。要转储大对象,你必须使用 定制输出格式或 TAR 输出格式,并在 pg_dump中使用-b选项。详情见参考页。 PostgreSQL源码树的 contrib/pg_dumplo目录中也包含一个可以转储 大对象的程序。
请熟悉pg_dump参考页。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。