选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0
历史版本PostgreSQL 9.0 已于 2015 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

F.32. pg_upgrade #

pg_upgrade(以前称为 pg_migrator)使存储在 PostgreSQL 数据文件中的数据可以迁移到 更高版本的 PostgreSQL主版本,而无需执行主版本升级 通常所需的数据转储/重新装载,例如从 8.4.7 升级到 PostgreSQL 的当前主版本。次版本升级 不需要使用它,例如从 9.0.1 升级到 9.0.4。

pg_upgrade 之所以可行,是因为尽管 PostgreSQL 主版本会定期加入新特性,内部数据存储格式却很少变化。 pg_upgrade 会尽最大努力确保新旧集簇 二进制兼容,例如检查编译时设置(包括 32/64 位二进制)是否兼容。 重要的是,任何外部模块也必须二进制兼容,不过这一点无法由 pg_upgrade 检查。

F.32.1. Supported Versions

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

F.32.2. pg_upgrade Options

pg_upgrade accepts the following command-line arguments:

-b old_bindir
--old-bindir OLDBINDIR

指定旧集簇可执行文件目录

-B new_bindir
--new-bindir NEWBINDIR

指定新集簇可执行文件目录

-c
--check

只检查集簇,不更改任何数据

-d old_datadir
--old-datadir OLDDATADIR

指定旧集簇数据目录

-D new_datadir
--new-datadir NEWDATADIR

指定新集簇数据目录

-g
--debug

启用调试

-G debug_filename
--debugfile DEBUGFILENAME

将调试活动输出到文件

-k
--link

使用硬链接而不是将文件复制到新集簇

-l log_filename
--logfile LOGFILENAME

将会话活动记录到文件

-p old_portnum
--old-port portnum

指定旧集簇端口号

-P new_portnum
--new-port portnum

指定新集簇端口号

-u username
--user username

clusters superuser

-v
--verbose

enable verbose output

-V
--version

display version information, then exit

-?
-h
--help

show help, then exit

F.32.3. Upgrade Steps

  1. 移动旧集簇(可选)

    如果你使用的是带版本号的安装目录,例如 /opt/PostgreSQL/8.4,则无需移动旧集簇。 一键安装程序都使用带版本号的安装目录。

    如果你的安装目录不是带版本号的,例如 /usr/local/pgsql, 就必须移动当前的 PostgreSQL 安装目录,以免它干扰新的 PostgreSQL 安装。当前的 PostgreSQL 服务器关闭后,就可以安全地重命名 PostgreSQL 安装目录。假设旧目录是 /usr/local/pgsql, 你可以这样做:

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

    以上命令会重命名该目录。

  2. 对于源码安装,编译新版本

    使用与旧集簇兼容的 configure 标志编译新的 PostgreSQL 源码。 pg_upgrade 会在开始升级前检查 pg_controldata, 以确保所有设置都兼容。

  3. 安装新的 PostgreSQL 二进制文件

    安装新服务器的二进制文件和支持文件。两个集簇可以使用相同的 端口号(通常是 5432),因为新旧集簇不会同时运行。

    对于源码安装,如果你希望把新服务器安装到自定义位置,可以使用 prefix 变量:

    gmake prefix=/usr/local/pgsql.new install
    
  4. 安装 pg_upgrade 和 pg_upgrade_support

    Install pg_upgrade and pg_upgrade_support in the new PostgreSQL cluster

  5. 初始化新的 PostgreSQL 集簇

    使用 initdb 初始化新集簇。这里同样要使用与旧集簇匹配的兼容 initdb 标志。许多预构建的安装程序会自动执行该步骤。 无需启动新集簇。

  6. 安装自定义共享对象文件

    把旧集簇使用的任何自定义共享对象文件(或 DLL)安装到新集簇中, 例如 pgcrypto.so,无论它们来自 contrib 还是其他来源。不要安装模式定义, 例如 pgcrypto.sql,因为它们会从旧集簇迁移 过来。

  7. 调整认证

    pg_upgrade 会连接新旧服务器若干次,因此 你可能希望在 pg_hba.conf 中把 local Unix 域套接字认证设置为 ident,或者使用 ~/.pgpass 文件(见 第 31.14 节)。

  8. 停止两个服务器

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

    pg_ctl -D /opt/PostgreSQL/8.4 stop
    pg_ctl -D /opt/PostgreSQL/9.0 stop
    

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

    NET STOP postgresql-8.4
    NET STOP postgresql-9.0
    

    NET STOP pgsql-8.3  (PostgreSQL 8.3 及更早版本使用不同的服务名)
    
  9. Run pg_upgrade

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

    如果使用链接模式,升级将快得多(无需复制文件),但一旦在 升级后启动新集簇,就无法再访问旧集簇。链接模式还要求新旧 集簇的数据目录位于同一文件系统中。完整选项列表请参阅 pg_upgrade --help

    对于 Windows 用户,必须以管理员账户登录,然后以 postgres 用户启动一个 shell 并设置正确的 路径:

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

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

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

    一旦启动,pg_upgrade 会验证两个集簇是否 兼容,然后执行迁移。你可以使用 pg_upgrade --check 只执行检查,即使旧服务器仍在运行。 pg_upgrade --check 还会概述迁移后你需要 手动调整的任何内容。 pg_upgrade 需要对当前目录有写权限。

    显然,迁移期间不应有人访问集簇。可以考虑为旧集簇和新集簇 使用非默认端口号,例如 50432,以避免升级期间出现意外的客户端 连接。

    如果在恢复数据库模式期间发生错误, pg_upgrade 会退出,你将不得不按下文 步骤 14 所述回退到旧集簇。要再次尝试 pg_upgrade,需要修改旧集簇,使 pg_upgrade 的模式恢复能够成功。如果问题出在 contrib 模块上,可能需要 从旧集簇卸载该 contrib 模块,并在迁移后把它安装到新集簇中, 前提是该模块没有被用来存储用户数据。

  10. 恢复 pg_hba.conf

    If you modified pg_hba.conf, restore its original settings.

  11. 迁移后处理

    如果需要任何迁移后处理,pg_upgrade 在完成时会发出警告。它还 会生成必须由管理员运行的脚本文件。这些脚本会连接到每个需要 迁移后处理的数据库。每个脚本应通过以下方式运行:

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

    这些脚本可以按任意顺序运行,运行完毕后即可删除。

    小心

    一般来说,在重建脚本运行完成之前访问其中引用的表是不安全的;这样做可能产生错误结果 或较差的性能。未在重建脚本中引用的表则可以立即访问。

  12. 统计信息

    由于优化器统计信息不会被 pg_upgrade 传输,系统会指示你在迁移结束时 运行一条命令来重新生成这些信息。

  13. 删除旧集簇

    对升级结果满意后,可以运行 pg_upgrade 完成时提到的脚本删除旧集簇的 数据目录。还可以删除旧的安装目录 (例如 binshare)。

  14. 恢复到旧集簇

    如果在运行 pg_upgrade 之后希望回退到旧集簇,有以下 几种选择:

    • 如果你运行 pg_upgrade 时使用了 --check,旧集簇未做任何修改,可以随时 重新使用它。

    • 如果你运行 pg_upgrade 时使用了 --link,数据文件由新旧集簇共享。如果你 已经启动过新集簇,新服务器已写入这些共享文件,再使用旧 集簇就不安全了。

    • 如果你运行 pg_upgrade没有使用 --link,或者没有启动过新服务器,那么除了 在 $PGDATA/global/pg_control(可能还有 表空间目录)追加了 .old 后缀之外,旧集簇 未被修改。要重新使用旧集簇,请移除 $PGDATA/global/pg_control.old 后缀;如果迁移目标是 8.4 或更早版本,还要删除迁移创建的表空间目录并移除表空间 目录名中的 .old 后缀;然后就可以重启 旧集簇了。

F.32.4. Limitations in Migrating from PostgreSQL 8.3

从 PostgreSQL 8.3 升级有从更高 PostgreSQL 发行版升级时不存在的 额外限制。例如,如果用户列定义为以下类型,pg_upgrade 将无法 用于从 8.3 的迁移:

  • tsquery 数据类型

  • name 数据类型且不是第一列

如果数据库中安装了ltree contrib 模块,pg_upgrade 将无法工作。

必须删除所有这样的列,并手动迁移它们。

如果出现下列情况,pg_upgrade 将要求重建表:

  • 某个用户列的数据类型为tsvector

如果出现下列情况,pg_upgrade 将要求重新索引:

  • 某个索引为 hash 或 GIN 类型

  • 某个索引使用了bpchar_pattern_ops

此外,在PostgreSQL 8.3 之后,默认的日期时间存储格式改为了整数。pg_upgrade 会检查新旧集簇使用的日期时间存储格式是否匹配。请确保你的新集簇在构建时使用了 configure 选项--disable-integer-datetimes

对于 Windows 用户,请注意,由于一键安装程序和 MSI 安装程序 使用的整数日期时间设置不同,只能从一键发行版的 8.3 版本升级到 一键发行版的 8.4 或更高版本。无法从 MSI 安装程序升级到一键 安装程序。

F.32.5. 注解

pg_upgrade 不支持迁移包含这些引用 OID 的 reg* 系统数据类型的数据库: regprocregprocedureregoperregoperatorregconfigregdictionary。(regtype 可以迁移。)

所有失败、重建和重建索引的情况,只要影响你的安装,都会由 pg_upgrade 报告;用于重建表和索引的 迁移后脚本会自动生成。

对于部署测试,可以创建旧集簇的模式专用副本,插入虚拟数据, 然后迁移该副本。

如果你希望使用链接模式,而又不希望旧集簇在新集簇启动时被修改, 可以先制作旧集簇的一份副本,再用链接模式迁移该副本。要制作 有效的旧集簇副本,可在服务器运行期间用 rsync 创建旧集簇的脏副本,然后关闭旧服务器 并再次运行 rsync,用所有变更更新副本,使其保持一致。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。