18.6. 升级一个PostgreSQL集簇

18.6.1. 通过pg_dumpall升级数据
18.6.2. 通过pg_upgrade升级数据
18.6.3. 通过复制升级数据

本节讨论如何把你的数据库数据从一个PostgreSQL发行升级到一个更新的发行。

当前PostgreSQL版本号由主要版本号和次要版本号组成。 例如,在版本号10.1中,10是主要版本号,1是次要版本号,这意味着这将是主版本10的第一个次要版本。 对于PostgreSQL版本10.0之前的版本,版本号由三个数字组成,例如9.5.3。 在这些情况下,主要版本由版本号的前两个数字组(例如9.5)组成,次要版本是第三个数字, 例如3,这意味着这将是主要版本9.5的第三次要版本。

次要发行从来不改变内部存储格式并且总是向前并向后兼容同一主版本号中的次要发行。 例如版本10.1与版本10.0和版本10.6兼容。类似的,例如9.5.3与9.5.0、9.5.1和9.5.6兼容。 要在兼容的版本间升级,你只需要简单地在服务器关闭时替换可执行文件并重启服务器。 数据目录则保持不变 — 次要升级就这么简单。

对于PostgreSQL发行, 内部数据存储格式常被改变,这使升级复杂化。传统的把数据移动到 新主版本的方法是先转储然后重新载入到数据库,不过这可能会很慢。 一种更快的方式是pg_upgrade。如下文所讨论的, 复制方法也能被用于升级。

新的主版本也通常会引入一些用户可见的不兼容性,因此可能需要应用程序编程上的改变。所有用户可见的更改都被列在发行注记(附录 E)中,请特别注意标有 "Migration" 的小节。如果你正在跨越几个主版本升级,一定要阅读每个中间版本的发行注记。

小心的用户在完全切换过去之前将希望在新版本上测试他们的客户端应用。因此,建立一个新旧版本的并存安装通常是一个好主意。在测试一个PostgreSQL主要升级时,考虑下列可能的改变类别:

管理

用于管理员监控和控制服务器的功能在每一个主发行中经常会改变和增加。

SQL

通常这包括新的 SQL 命令功能并且在行为上没有更改,除非在发行注记中有特别提到。

库 API

通常libpq等库值增加新功能,除非在发行注记中有特别提到。

系统目录

系统目录改变通常只影响数据库管理工具。

服务器 C-语言 API

这涉及到后端函数 API 中的改变,它使用 C 编程语言编写。这些改变影响引用服务器内部后端函数的代码。

18.6.1. 通过pg_dumpall升级数据

一种升级方法是从PostgreSQL的一个主版本转储数据并将它重新载入到另一个主版本中 — 要这样做,你必须使用pg_dumpall这样的逻辑备份工具,文件系统级别的备份方法将不会有用(这也阻止你在一个不兼容版本的PostgreSQL中使用一个数据目录,因此在一个数据目录上尝试启动一个错误的服务器版本不会造成很大的危害)。

我们推荐你从较新版本的PostgreSQL中使用pg_dumppg_dumpall程序,这样可以利用在这些程序中可能存在的改进。当前发行的转储程序可以读取任何 7.0 以上版本服务器中的数据。

这些指令假定你现有的安装位于/usr/local/pgsql目录,并且数据区域在/usr/local/pgsql/data。请用你的路径进行适当的替换。

  1. 如果在创建一个备份,确认你的数据库没有在被更新。这不会影响备份的完整性,但是那些更改当然不会被包括在备份中。如果必要,编辑/usr/local/pgsql/data/pg_hba.conf文件中的权限(或等效的方法)来不允许除你之外的任何人使用数据库。关于访问控制的额外信息请见第 20 章

    要备份你的数据库安装,键入:

    pg_dumpall > outputfile

    要制作备份,你可以使用你正在运行版本的pg_dumpall命令,详见第 25.1.2 节。但是,要得到最好的结果,试试使用PostgreSQL 10.1 的pg_dumpall命令,因为这个版本包含了对旧版本的缺陷修复和改进。虽然这个建议可能看起来很奇怪,因为你还没有安装新版本,但如果你计划平行地安装新版本,遵循这个建议是很明智的。在这种情况下,你可以正常完成安装并且稍后再来传输数据。这也将减少停机时间。

  2. 关闭就服务器:

    pg_ctl stop

    在那些自动启动PostgreSQL的系统上,可能有一个启动文件将完成同样的事情。例如,在一个Red Hat Linux系统中,我们会发现这也能用:

    /etc/rc.d/init.d/postgresql stop

    关于启动和停止服务器的细节请见第 18 章

  3. 如果从备份恢复,重命名或删除旧的安装目录(如果它不是针对特定版本的)。重命名该目录是一个好主意,而不是删除它,因为如果你碰到问题并需要返回到它,它还存在。记住该目录可能消耗可观的磁盘空间。要重命名该目录,使用类似的命令:

    mv /usr/local/pgsql /usr/local/pgsql.old

    (注意将该目录作为一个单一单元移动,这样相对路径可以保持不变)。

  4. 安装新版本的PostgreSQL第 16.4 节.

  5. 如果需要,创建一个新的数据库集簇。记住你必须在登录到一个特殊的数据库用户账户(如果你在升级,你就已经有了这个账户)时执行这些命令。

    /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data

  6. 恢复你之前的pg_hba.conf以及任何postgresql.conf修改。

  7. 启动数据库服务器,也要使用特殊的数据库用户账户:

    /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data

  8. 最后,使用新的 psql从备份恢复你的数据:

    /usr/local/pgsql/bin/psql -d postgres -f outputfile

通过在一个不同的目录中安装新的服务器并且并行地在不同的端口运行新旧两个服务器可以达到最低的停机时间。那么你可以这样用:

pg_dumpall -p 5432 | psql -d postgres -p 5433

来转移你的数据。

18.6.2. 通过pg_upgrade升级数据

pg_upgrade模块允许一个安装从一个 PostgreSQL主版本“就地”升级成另一个主版本。 升级可以在数分钟内被执行,特别是使用--link模式时。它 要求和上面的pg_dumpall相似的步骤,例如启动/停止 服务器、运行initdbpg_upgrade 文档概述了所需的步骤。

18.6.3. 通过复制升级数据

也可以使用某些复制方法来使用PostgreSQL的已更新版本创建一个后备服务器,例如Slony,它支持在不同主版本的PostgreSQL之间的复制。后备服务器可以在同一台计算机或者不同的计算机上。一旦它和主服务器(运行旧版本的PostgreSQL)同步好,你可以切换主机并且将后备服务器作为主机,然后关闭旧的数据库实例。这样一种切换使得一次升级的停机时间只有数秒。