(可选)移动旧集群

pg_upgrade

pg_upgrade —升级 PostgreSQL 服务器实例

Synopsis

pg_upgrade -b oldbindir -B newbindir -d oldconfigdir -D newconfigdir [ option ...]

Description

pg_upgrade(以前称为 pg_migrator)允许将存储在 PostgreSQL 数据文件中的数据升级到更高版本的 PostgreSQL 主版本,而无需进行主版本升级通常所需的数据转储/重新加载。从 9.5.8 到 9.6.4 或从 10.7 到 11.2. 次要版本升级不需要,例如从 9.6.2 到 9.6.3 或从 10.1 到 10.2.

PostgreSQL 的主要发行版定期添加新功能,这些新功能通常会更改系统表的布局,但是内部数据存储格式很少更改。 pg_upgrade 利用这一事实通过创建新的系统表并简单地重用旧的用户数据文件来执行快速升级。如果将来的主要发行版曾以使旧数据格式不可读的方式更改了数据存储格式,则 pg_upgrade 将无法用于此类升级。 (社区将尝试避免这种情况.)

pg_upgrade 尽最大努力确保新旧集群是二进制兼容的,例如通过检查兼容的编译时设置,包括 32/64 位二进制文件。尽管 pg_upgrade 无法检查,但是任何外部模块也是二进制兼容的,这一点很重要。

pg_upgrade 支持从 8.4.X 及更高版本升级到 PostgreSQL 的当前主要版本,包括快照和 beta 版本。

Options

pg_upgrade 接受以下命令行参数:

  • -b bindir
    --old-bindir= bindir

    • 旧的 PostgreSQL 可执行目录;环境变量PGBINOLD
  • -B bindir
    --new-bindir= bindir

    • 新的 PostgreSQL 可执行文件目录;环境变量PGBINNEW
  • -c
    --check

    • 仅检查群集,不更改任何数据
  • -d configdir
    --old-datadir= configdir

    • 旧数据库集群配置目录;环境变量PGDATAOLD
  • -D configdir
    --new-datadir= configdir

    • 新的数据库集群配置目录;环境变量PGDATANEW
  • -j njobs
    --jobs=njobs

    • 要使用的并发进程或线程数
  • -k
    --link

    • 使用硬链接而不是将文件复制到新集群
  • -o options
    --old-options options

    • 选项直接传递给旧的postgres命令;附加了多个选项调用
  • -O options
    --new-options options

    • 直接传递给新的postgres命令的选项;附加了多个选项调用
  • -p port
    --old-port= port

    • 旧集群端口号;环境变量PGPORTOLD
  • -P port
    --new-port= port

    • 新的群集端口号;环境变量PGPORTNEW
  • -r
    --retain

    • 即使成功完成后仍保留 SQL 和日志文件
  • -U username
    --username= username

    • 集群的安装用户名;环境变量PGUSER
  • -v
    --verbose

    • 启用详细的内部日志记录
  • -V
    --version

    • 显示版本信息,然后退出
  • -?
    --help

    • 显示帮助,然后退出

Usage

这些是使用 pg_upgrade 进行升级的步骤:

  • 如果您使用的是特定于版本的安装目录,例如/opt/PostgreSQL/11,您无需移动旧群集。图形安装程序均使用特定于版本的安装目录。

如果您的安装目录不是特定于版本的,例如/usr/local/pgsql,有必要移动当前的 PostgreSQL 安装目录,以免干扰新的 PostgreSQL 安装。一旦关闭当前的 PostgreSQL 服务器,就可以重命名 PostgreSQL 安装目录了。假设旧目录为/usr/local/pgsql,则可以执行以下操作:

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

重命名目录。

  • 对于源代码安装,请构建新版本

使用与旧集群兼容的configure标志构建新的 PostgreSQL 源。 pg_upgrade 将在开始升级之前检查pg_controldata以确保所有设置兼容。

  • 安装新的 PostgreSQL 二进制文件

安装新服务器的二进制文件和支持文件。 pg_upgrade 包含在默认安装中。

对于源代码安装,如果希望将新服务器安装在自定义位置,请使用prefix变量:

make prefix=/usr/local/pgsql.new install
  • 初始化新的 PostgreSQL 集群

使用initdb初始化新集群。同样,使用与旧群集匹配的兼容initdb标志。许多预安装的安装程序会自动执行此步骤。无需启动新集群。

  • 安装自定义共享对象文件

将旧群集使用的所有自定义共享对象文件(或 DLL)安装到新群集中,例如pgcrypto.so,无论它们来自contrib还是其他来源。请勿安装架构定义,例如CREATE EXTENSION pgcrypto,因为它们将从旧群集中升级。另外,所有自定义全文搜索文件(词典,同义词,同义词库,停用词)也必须复制到新群集中。

  • Adjust authentication

pg_upgrade将多次连接到旧服务器和新服务器,因此您可能希望将pg_hba.conf中的peer设置为身份验证,或使用~/.pgpass文件(请参见Section 34.15)。

  • 停止两个服务器

确保在 Unix 上停止使用两个数据库服务器,例如:

pg_ctl -D /opt/PostgreSQL/9.6 stop
pg_ctl -D /opt/PostgreSQL/11 stop

或在 Windows 上,使用正确的服务名称:

NET STOP postgresql-9.6
NET STOP postgresql-11

流复制和日志传送备用服务器可以保持运行,直到后续步骤。

  • 准备升级备用服务器

如果要使用第Step 10节中概述的方法升级备用服务器,请通过对旧的主群集和备用群集运行 pg_controldata 来验证旧的备用服务器是否已被捕获。验证“最新检查点位置”值在所有群集中均匹配。 (如果在旧的备用服务器之前关闭了旧的备用服务器,或者旧的备用服务器仍在运行,则会出现不匹配的情况.)而且,在新的主群集上的postgresql.conf文件中将wal_level更改为replica

  • Run pg_upgrade

始终运行新服务器的 pg_upgrade 二进制文件,而不是旧服务器。 pg_upgrade 需要指定新旧集群的数据和可执行文件(bin)目录。您还可以指定用户和端口值,以及是否要链接数据文件而不是默认的复制行为。

如果使用链接模式,则升级将更快(不复制文件)并且使用更少的磁盘空间,但是一旦升级后启动新集群,您将无法访问旧集群。链接模式还要求新旧群集数据目录位于同一文件系统中。 (表空间和pg_wal可以位于不同的文件系统上.)有关选项的完整列表,请参见pg_upgrade --help

--jobs选项允许将多个 CPU 内核用于文件的复制/链接以及并行转储和重新加载数据库模式。一个不错的起点是最大数量的 CPU 核心和表空间。此选项可以大大减少升级在 multiprocessing 器计算机上运行的多数据库服务器的时间。

对于 Windows 用户,您必须登录到 Management 帐户,然后以postgres用户身份启动 Shell 并设置正确的路径:

RUNAS /USER:postgres "CMD.EXE"
SET PATH=%PATH%;C:\Program Files\PostgreSQL\11\bin;

然后使用带引号的目录运行 pg_upgrade,例如:

pg_upgrade.exe
        --old-datadir "C:/Program Files/PostgreSQL/9.6/data"
        --new-datadir "C:/Program Files/PostgreSQL/11/data"
        --old-bindir "C:/Program Files/PostgreSQL/9.6/bin"
        --new-bindir "C:/Program Files/PostgreSQL/11/bin"

启动后,pg_upgrade将验证两个群集是否兼容,然后进行升级。即使旧服务器仍在运行,也可以使用pg_upgrade --check仅执行检查。 pg_upgrade --check还将概述升级后您需要进行的任何手动调整。如果要使用链接模式,则应将--link选项与--check结合使用以启用特定于链接模式的检查。 pg_upgrade要求在当前目录中具有写权限。

显然,在升级过程中没有人可以访问群集。 pg_upgrade 默认在端口 50432 上运行服务器,以避免意外的 Client 端连接。升级时,两个群集可以使用相同的端口号,因为新旧群集不会同时运行。但是,在检查运行中的旧服务器时,旧端口号和新端口号必须不同。

如果还原数据库架构时发生错误,则pg_upgrade将退出,您将必须还原到旧群集,如下面的Step 16所述。要再次尝试pg_upgrade,您将需要修改旧集群,以便 pg_upgrade 模式还原成功。如果问题是contrib模块,则可能需要从旧集群中卸载contrib模块,并在升级后将其安装在新集群中,前提是该模块未用于存储用户数据。

  • 升级流复制和日志传送备用服务器

如果您使用链接模式并具有 Streaming Replication(请参见Section 26.2.5)或 Log-Shipping(请参见Section 26.2)备用服务器,则可以按照以下步骤快速升级它们。您不会在备用服务器上运行 pg_upgrade,而是在主服务器上运行 rsync。尚未启动任何服务器。

如果您使用链接模式,没有或不想使用 rsync,或者想要一个更简单的解决方案,请跳过本节中的说明,并在 pg_upgrade 完成并运行新的主服务器后简单地重新创建备用服务器。

  • 在备用服务器上安装新的 PostgreSQL 二进制文件

确保所有备用服务器上都安装了新的二进制文件和支持文件。

  • *确保新的备用数据目录不存在

确保新的备用数据目录不存在或为空。如果运行了 initdb,请删除备用服务器的新数据目录。

  • 安装自定义共享对象文件

在新的主群集中安装的新备用数据库上安装相同的自定义共享库文件。

  • 备用服务器

如果备用服务器仍在运行,请按照上述说明立即停止它们。

  • 保存配置文件

从您需要保留的旧备用数据库的配置目录中保存所有配置文件,例如postgresql.confrecovery.conf,因为这些将在下一步中被覆盖或删除。

  • Run rsync

使用链接模式时,可以使用 rsync 快速升级备用服务器。为此,请在主服务器上的旧数据库集群目录和新数据库集群目录之上的目录中,在每个备用服务器的* primary *上运行此命令:

rsync --archive --delete --hard-links --size-only --no-inc-recursive old_cluster new_cluster remote_dir

其中old_clusternew_cluster相对于主数据库上的当前目录,而remote_dir位于备用数据库上的新旧群集目录之上。主数据库和备用数据库上指定目录下的目录结构必须匹配。有关指定远程目录的详细信息,请查阅 rsync 手册页,例如

rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/PostgreSQL/9.5 \
      /opt/PostgreSQL/9.6 standby.example.com:/opt/PostgreSQL

您可以使用 rsync 的--dry-run选项验证该命令将执行的操作。尽管必须至少在一个备用数据库上在主数据库上运行 rsync,但是只要尚未启动升级的备用数据库,就可以在升级的备用数据库上运行 rsync 来升级其他备用数据库。

这样做是为了记录由 pg_upgrade 的链接模式创建的链接,这些链接连接了主服务器上新旧集群中的文件。然后,它在备用数据库的旧群集中找到匹配的文件,并在备用数据库的新群集中为其创建链接。未在主数据库上链接的文件从主数据库复制到备用数据库。 (它们通常很小.)这提供了快速的备用升级。不幸的是,rsync 不必要地复制与临时表和未记录表关联的文件,因为这些文件通常在备用服务器上不存在。

如果有表空间,则需要为每个表空间目录运行类似的 rsync 命令,例如:

rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tblsp/PG_9.5_201510051 \
      /vol1/pg_tblsp/PG_9.6_201608131 standby.example.com:/vol1/pg_tblsp

如果您已将pg_wal重定位到数据目录之外,则 rsync 也必须在这些目录上运行。

  • 配置流复制和日志运送备用服务器

配置服务器以进行日志传送。 (您无需运行pg_start_backup()pg_stop_backup()或进行文件系统备份,因为备用数据库仍与主数据库保持同步.)

  • 还原pg_hba.conf

如果您修改了pg_hba.conf,请还原其原始设置。可能还需要调整新集群中的其他配置文件以匹配旧集群,例如postgresql.conf

  • 启动新服务器

现在可以安全启动新服务器,然后安全启动所有备用服务器。

  • Post-Upgrade processing

如果需要任何升级后的处理,pg_upgrade 将在完成时发出警告。它还将生成必须由 Management 员运行的脚本文件。脚本文件将连接到每个需要升级后处理的数据库。每个脚本应使用以下命令运行:

psql --username=postgres --file=script.sql postgres

脚本可以以任何 Sequences 运行,并且可以在运行后将其删除。

Caution

通常,在重建脚本运行完成之前,访问重建脚本中引用的表是不安全的。这样做可能会产生错误的结果或性能不佳。重建脚本中未引用的表可以立即访问。

  • Statistics

由于pg_upgrade不会传输优化器统计信息,因此系统会指示您在升级结束时运行命令以重新生成该信息。您可能需要设置连接参数以匹配新集群。

  • 删除旧集群

对升级感到满意之后,您可以通过运行pg_upgrade完成时提到的脚本来删除旧群集的数据目录。 (如果您在旧数据目录中有用户定义的表空间,则无法自动删除.)您也可以删除旧的安装目录(例如binshare)。

  • 还原到旧群集

如果在运行pg_upgrade之后希望还原到旧群集,则有以下几种选择:

  • 如果使用了--check选项,则旧集群未被修改;它可以重新启动。

  • 如果未使用--link选项,则旧集群未修改;它可以重新启动。

  • 如果使用了--link选项,则数据文件可能会在新旧群集之间共享:

  • 如果pg_upgrade在开始链接之前中止,则旧集群未修改;它可以重新启动。

    • 如果您启动新集群,则旧集群将保持不变,只是在开始链接时,在$PGDATA/global/pg_control后面附加了一个.old后缀。要重用旧集群,请从$PGDATA/global/pg_control删除.old后缀;然后可以重新启动旧群集。

    • 如果确实启动了新群集,则它已写入共享文件,因此使用旧群集是不安全的。在这种情况下,将需要从备份中还原旧群集。

Notes

pg_upgrade 不支持使用reg* OID 引用系统数据类型regprocregprocedureregoperregoperatorregconfigregdictionary来升级包含表列的数据库。 (regtype可以升级.)

如果所有失败,重建和重新索引的情况影响安装,将由 pg_upgrade 报告。用于重建表和索引的升级后脚本将自动生成。如果要自动执行许多集群的升级,则应该发现具有相同数据库架构的集群对于所有集群升级都需要相同的升级后步骤;这是因为升级后的步骤基于数据库模式,而不是用户数据。

为了进行部署测试,请创建旧集群的仅架构副本,插入虚拟数据,然后进行升级。

如果要升级使用仅配置文件目录的 PostgreSQL 9.2 之前的集群,则必须将实际数据目录位置传递给 pg_upgrade,并将配置目录位置传递给服务器,例如-d /real-data-directory -o '-D /configuration-directory'

如果使用的是 9.1 以前版本的旧服务器,而该服务器使用的是非默认 Unix 域套接字目录或与新集群的默认值不同的默认服务器,则设置PGHOST指向旧服务器的套接字位置。 (这在 Windows 上不相关.)

如果要使用链接模式,并且不想在启动新集群时修改旧集群,请复制旧集群,然后以链接模式进行升级。要创建旧集群的有效副本,请在服务器运行时使用rsync创建旧集群的脏副本,然后关闭旧服务器并再次运行rsync --checksum以进行任何更改以更新该副本以使其一致。 (--checksum是必需的,因为rsync的文件修改时间间隔只有一秒钟.)您可能希望排除某些文件,例如postmaster.pid,如Section 25.3.3中所述。如果文件系统支持文件系统快照或写时复制文件副本,则尽管必须同时创建快照和副本或在数据库服务器关闭时创建快照,但是仍可以使用该文件副本来备份旧的集群和表空间。

See Also

initdb, pg_ctl, pg_dump, postgres