19.6. 升级 PostgreSQL 集簇 #
本节讨论如何把数据库数据从一个 PostgreSQL 发行版升级到较新的发行版。
当前 PostgreSQL 的版本号由主版本号和次版本号组成。例如,在版本号 10.1 中,10 是主版本号,1 是次版本号,这意味着它是主版本 10 的第一个次版本。对于 10.0 之前的 PostgreSQL 版本,版本号由三个数字组成,例如 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。此外,也可以使用复制方法,如下所述。(如果你使用的是预打包的 PostgreSQL,打包方也许提供了辅助主版本升级的脚本。详细信息请查阅该软件包级别的文档。)
新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明(附录 E)中;请特别留意标为“迁移(Migration)”的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。
谨慎的用户会希望在完全切换之前,先在新版本上测试客户端应用。因此,同时安装旧版本和新版本通常是个好主意。测试 PostgreSQL 主版本升级时,可以考虑以下几类可能的变化:
- 管理
管理员可用于监控和控制服务器的功能,在每个主版本中常常都会变化并有所增强。
- SQL
通常这意味着 SQL 命令能力会增加,而行为不会变化,除非发行说明中特别提到。
- 库 API
通常像 libpq 这样的库只会增加新功能,除非发行说明中特别说明。
- 系统目录
系统目录的变化通常只影响数据库管理工具。
- 服务器端 C 语言 API
这涉及使用 C 语言编写的后端函数 API 的变更。这类变更会影响那些深入引用服务器内部后端函数的代码。
19.6.1. 通过 pg_dumpall 升级数据 #
一种升级方法是从某个主版本的 PostgreSQL 转储数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如 pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的 PostgreSQL 上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。)
建议使用来自较新版本 PostgreSQL 的 pg_dump 和 pg_dumpall 程序,以利用这些程序可能包含的改进。当前版本的转储程序可以读取从 9.2 起任意服务器版本的数据。
以下说明假定你现有的安装位于 /usr/local/pgsql 目录下,数据区域位于 /usr/local/pgsql/data。请根据实际情况替换成你的路径。
如果是在制作备份,请确认数据库此时没有正在进行更新。更新操作不会影响备份的完整性,但那些变更当然不会包含在备份中。必要时,可修改
/usr/local/pgsql/data/pg_hba.conf(或等效文件)中的访问权限,禁止除你之外的其他人访问数据库。有关访问控制的更多信息见第 21 章。pg_dumpall >outputfile制作备份时,你可以使用当前正在运行版本中的 pg_dumpall 命令,详见第 26.1.2 节。不过,为了获得最佳结果,尽量使用 PostgreSQL 15.19 自带的 pg_dumpall 命令,因为这一版本相较旧版本包含了缺陷修复和改进。这个建议看起来可能有些反常,因为你这时还没有安装新版本;但如果你计划让新旧版本并行安装,遵循这一建议是明智的。在那种情况下,你可以先正常完成新版本安装,稍后再迁移数据,这样也能减少停机时间。
关闭旧服务器:
pg_ctl stop在那些会在开机时自动启动 PostgreSQL 的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在 Red Hat Linux 系统上,也许下面这条命令就可以:
/etc/rc.d/init.d/postgresql stop有关服务器启动和停止的细节见第 19 章。
如果是从备份恢复,请重命名或删除旧的安装目录,前提是它不是按版本区分的目录。与其删除,不如重命名,这样如果你遇到问题需要回退,它仍然还在。请记住,该目录可能会占用相当可观的磁盘空间。要重命名该目录,可以使用类似下面的命令:
mv /usr/local/pgsql /usr/local/pgsql.old(请确保把该目录作为一个整体移动,这样相对路径才会保持不变。)
按照第 17.4 节安装新版本的 PostgreSQL。
如有需要,创建一个新的数据库集簇。请记住,执行这些命令时必须登录到专用数据库用户账户(如果你正在升级,就已经拥有这个账户)。
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data恢复先前的
pg_hba.conf,以及你对postgresql.conf所做的任何修改。启动数据库服务器,同样要使用该专门的数据库用户账户:
/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data最后,使用以下命令从备份恢复数据:
/usr/local/pgsql/bin/psql -d postgres -foutputfile这里应使用新版 psql。
若要把停机时间降到最低,可以把新服务器安装到不同目录中,并让新旧两个服务器在不同端口上并行运行。这样就可以使用类似下面的命令:
pg_dumpall -p 5432 | psql -d postgres -p 5433
来传输数据。
19.6.2. 通过 pg_upgrade 升级数据 #
pg_upgrade 模块允许把一次安装从一个 PostgreSQL 主版本“就地”迁移到另一个主版本。升级可在几分钟内完成,特别是在使用 --link 模式时更是如此。它需要执行与上面 pg_dumpall 方法类似的步骤,例如启动/停止服务器、运行 initdb 等。pg_upgrade 的文档概述了所需步骤。
19.6.3. 通过复制升级数据 #
也可以使用逻辑复制方法,创建一个运行较新版本 PostgreSQL 的备库。之所以可行,是因为逻辑复制支持在不同主版本的 PostgreSQL 之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本 PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换使升级只需几秒钟的停机时间。
这种升级方法既可以使用内置的逻辑复制功能,也可以使用外部逻辑复制系统,例如 pglogical、Slony、Londiste 和 Bucardo。
报告文档问题
阅读 上游文档. 通过 PostgreSQL 文档反馈表单.