受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

18.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,打包方也许提供了辅助主版本升级的脚本。详细信息请查阅该软件包级别的文档。)

新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明(Appendix E)中;请特别留意标为Migration的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。

谨慎的用户会希望在完全切换之前,先在新版本上测试客户端应用。因此,同时安装旧版本和新版本通常是个好主意。测试PostgreSQL主版本升级时,可以考虑以下几类可能的变化:

管理

管理员可用于监控和控制服务器的功能,在每个主版本中常常都会变化并有所增强。

SQL

通常这意味着 SQL 命令能力会增加,而行为不会变化,除非发行说明中特别提到。

库 API

通常像libpq这样的库只会增加新功能,除非发行说明中特别说明。

系统目录

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

服务器端 C 语言 API

这涉及以后端函数 API 为代表的变更,该 API 使用 C 语言编写。这类变更会影响那些深入引用服务器内部后端函数的代码。

18.6.1. 通过pg_dumpall升级数据 #

一种升级方法是从某个主版本的PostgreSQL导出数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。)

建议使用来自较新版本PostgreSQLpg_dumppg_dumpall程序,以利用这些程序可能包含的改进。当前版本的转储程序可以读取从 9.2 起任意服务器版本的数据。

以下说明假定你现有的安装位于/usr/local/pgsql目录下,数据区域位于/usr/local/pgsql/data。请根据实际情况替换成你的路径。

  1. 如果是在制作备份,请确认数据库此时没有正在进行更新。这不会影响备份的一致性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf中的访问权限(或采用等效方法),禁止除你之外的其他人访问数据库。有关访问控制的更多信息见Chapter 20

    要备份整个数据库安装,请输入:

    pg_dumpall > outputfile
    

    制作备份时,你可以使用当前正在运行版本中的pg_dumpall命令,详见Section 25.1.2。不过,为了获得最佳结果,尽量使用PostgreSQL 16.13 自带的pg_dumpall命令,因为这一版本相较旧版本包含了缺陷修复和改进。这个建议看起来可能有些反常,因为你这时还没有安装新版本;但如果你计划让新旧版本并行安装,遵循这一建议是明智的。在那种情况下,你可以先正常完成新版本安装,稍后再迁移数据,这样也能减少停机时间。

  2. 关闭旧服务器:

    pg_ctl stop
    

    在那些会自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以:

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

    有关服务器启动和停止的细节见Chapter 18

  3. 如果是从备份恢复,请重命名或删除旧的安装目录,前提是它不是按版本区分的目录。与其删除,不如重命名,这样如果你遇到问题需要回退,它仍然还在。请记住,该目录可能会占用相当可观的磁盘空间。要重命名该目录,可以使用类似下面的命令:

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

    (请确保把该目录作为一个整体移动,这样相对路径才会保持不变。)

  4. 按照 Chapter 17 安装新版本的 PostgreSQL

  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
    

    这里务必使用新的psql

若要把停机时间降到最低,可以把新服务器安装到不同目录中,并让新旧两个服务器在不同端口上并行运行。这样就可以使用类似下面的命令:

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

来传输数据。

18.6.2. 通过pg_upgrade升级数据 #

pg_upgrade模块允许把一次安装从一个PostgreSQL主版本就地迁移到另一个主版本。升级可在几分钟内完成,特别是在使用--link模式时更是如此。它需要执行与上面pg_dumpall方法类似的步骤,例如启动/停止服务器、运行initdb等。pg_upgrade文档概述了所需步骤。

18.6.3. 通过复制升级数据 #

也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换通常只会带来几秒钟的停机时间。

这种升级方法既可以使用内置的逻辑复制功能,也可以使用外部逻辑复制系统,例如pglogicalSlonyLondisteBucardo

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。