pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
目录
与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。
备份PostgreSQL数据主要有三种根本不同的方法:
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连接同样受常规客户端认证机制约束(见第 20 章)。
由pg_dump创建的转储在内部是一致的,也就是说,在pg_dump运行期间对数据库的更新不会出现在转储中。pg_dump在工作期间不会阻塞数据库上的其他操作。(例外是那些需要独占锁的操作,例如VACUUM FULL。)
如果你的数据库模式依赖于 OID(例如用作外键),就必须指示pg_dump同时转储 OID。为此,请使用-o命令行选项。
由pg_dump创建的文本文件供psql程序读取。恢复转储的通用命令格式是
psqldbname<infile
其中infile就是你在pg_dump命令中作为outfile使用的文件。dbname数据库不会被这条命令创建,因此你必须先从template0自行创建它,然后再执行psql(例如用 createdb -T template0 ). psql 支持与pg_dump类似的用于指定要连接的数据库服务器和所用用户名的选项。更多信息见psql参考页。dbname
在恢复 SQL 转储之前,所有拥有对象或者在被转储数据库中曾被授予对象权限的用户都必须已经存在。否则,恢复将无法以原有所有权和/或权限重新创建这些对象。(有时这正是你想要的,但通常不是。)
默认情况下,psql脚本在遇到 SQL 错误后仍会继续执行。你可能希望在脚本开头使用下面的命令来改变这一行为,让psql在发生 SQL 错误时以退出状态码 3 退出:
\set ON_ERROR_STOP
无论哪种方式,你都只会得到一个部分恢复的数据库。另一种办法是指定把整个转储作为单个事务恢复,这样恢复要么完全完成,要么完全回滚。这种模式可以通过向psql传递-1或--single-transaction命令行选项来指定。使用这种模式时要注意,即使一个微小的错误也可能回滚一个已经运行了多个小时的恢复。不过,对于转储被部分恢复后复杂的数据库手工清理而言,这可能仍是更可取的选择。
pg_dump和psql能够写入或读取管道,这使得可以把数据库直接从一台服务器转储到另一台服务器,例如:
pg_dump -hhost1dbname| psql -hhost2dbname
pg_dump生成的转储是以template0为基准的。这意味着通过template1增加的任何语言、过程等也都会被pg_dump转储。因此,恢复时如果你使用的是定制过的template1,就必须像上面的例子那样,从template0创建空数据库。
恢复完备份后,最好对每个数据库运行ANALYZE,这样查询优化器就能拥有有用的统计信息。一个简便的方法是运行vacuumdb -a -z;这等价于对每个数据库手动运行VACUUM ANALYZE。关于如何高效地将大量数据装入PostgreSQL,请参见第 13.4 节。
pg_dump一次只转储一个数据库,而且不会转储角色或表空间的信息(因为这些是整个集簇级别的,而不是每个数据库各自的)。为了方便地转储整个数据库集簇的全部内容,提供了pg_dumpall程序。pg_dumpall会备份给定集簇中的每个数据库,并保留角色定义和表空间定义等集簇范围的数据。该命令的基本用法是:
pg_dumpall > outfile
得到的转储可以用psql恢复:
psql -f infile postgres
(实际上,你可以指定任意现有的数据库名作为起始,但如果是载入空集簇,通常应使用postgres。)恢复pg_dumpall转储时始终需要数据库超级用户权限,因为恢复角色和表空间信息需要这种权限。如果使用了表空间,请确保转储中的表空间路径适合新的安装。
由于PostgreSQL允许表大于系统上的最大文件大小,把这样一张表转储到文件可能会产生问题,因为得到的文件很可能超过系统允许的最大尺寸。幸运的是,pg_dump可以把输出写到标准输出,因此你可以利用标准 Unix 工具绕过这个潜在问题。
使用压缩转储。. 你可以使用自己喜欢的压缩程序,例如gzip。
pg_dumpdbname| gzip >filename.gz
恢复时用
createdbdbnamegunzip -cfilename.gz | psqldbname
或者
catfilename.gz | gunzip | psqldbname
使用split。. split命令允许你把输出分割成文件系统可接受大小的较小文件。例如,要切分为 1 MB 的块:
pg_dumpdbname| split -b 1m -filename
恢复时用
createdbdbnamecatfilename* | psqldbname
使用自定义转储格式。. 如果构建PostgreSQL所用的系统安装了zlib压缩库,自定义转储格式会在向输出文件写入数据时对其进行压缩。这会产生与使用gzip大致相同大小的转储文件,但额外的优点是其中的表可以有选择地恢复。下面的命令使用自定义转储格式转储数据库:
pg_dump -Fcdbname>filename
自定义格式的转储不是供psql执行的脚本,而必须通过pg_restore恢复。详细信息见pg_dump和pg_restore参考页。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。