↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18)
开发中的版本: 19 / 20devel

29.13. 升级 #

仅当旧逻辑复制集群的所有成员都为 17.0 或更高版本时,才支持迁移逻辑复制集群。

29.13.1. 为发布端升级做准备 #

pg_upgrade 会尝试迁移逻辑槽。这有助于避免在新发布端手工定义相同的逻辑槽。仅当旧集簇版本为 17.0 或更高时才支持逻辑槽迁移。17.0 之前集簇中的逻辑槽会被静默忽略。

在开始升级发布端集簇前,请通过执行 ALTER SUBSCRIPTION ... DISABLE 临时禁用订阅。升级完成后再重新启用订阅。

pg_upgrade 升级逻辑槽有若干前置条件。若不满足,将报错。

  • 新集簇必须将 wal_level 设为 logical。

  • 新集簇中 max_replication_slots 的配置值必须大于等于旧集簇中的槽数量。

  • 旧集簇中复制槽引用的输出插件必须安装在新 PostgreSQL 可执行文件目录中。还必须将它们包含在新集簇的 output_plugin_libraries 中;有关安全信息,请参阅该参数的文档。

  • 旧集簇必须已将所有事务和逻辑解码消息复制到订阅端。

  • 旧集簇中的所有槽都必须可用,即不存在 pg_replication_slots.conflicting 不为 true 的槽。

  • 新集簇中不能存在永久逻辑槽,即不能有 pg_replication_slots.temporary 为 false 的槽。

29.13.2. 为订阅端升级做准备 #

在新订阅端完成订阅端配置。pg_upgrade 会尝试迁移订阅依赖,包括 pg_subscription_rel 系统目录中的订阅表信息,以及订阅的复制源。这样新订阅端上的逻辑复制可以从旧订阅端停止的位置继续。仅当旧集簇版本为 17.0 或更高时才支持订阅依赖迁移。17.0 之前集簇中的订阅依赖会被静默忽略。

pg_upgrade 升级订阅也有若干前置条件。若不满足,将报错。

29.13.3. 升级逻辑复制集群 #

在升级订阅端时,发布端仍可执行写操作。这些变更会在订阅端升级完成后继续复制。

注意

逻辑复制的限制同样适用于逻辑复制集群升级。详见第 29.8 节。

发布端升级的前置条件同样适用于逻辑复制集群升级。详见第 29.13.1 节。

订阅端升级的前置条件同样适用于逻辑复制集群升级。详见第 29.13.2 节。

警告

升级逻辑复制集群需要在多个节点执行多个步骤。由于并非所有操作都是事务性的,建议按第 25.3.2 节所述先做好备份。

下列逻辑复制集群的升级步骤详见后文:

29.13.3.1. 升级双节点逻辑复制集群的步骤 #

假设发布端位于 node1,订阅端位于 node2。订阅端 node2 上有订阅 sub1_node1_node2,用于订阅来自 node1 的变更。

  1. 在 node2 上,使用 ALTER SUBSCRIPTION ... DISABLE 禁用所有订阅来自 node1 变更的订阅,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
    

  2. 停止 node1 上的发布端服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data1 stop
    

  3. 使用目标新版本初始化 data1_upgraded 实例。

  4. 将发布端 node1 升级到目标新版本,例如:

    pg_upgrade
            --old-datadir "/opt/PostgreSQL/postgres/17/data1"
            --new-datadir "/opt/PostgreSQL/postgres/18/data1_upgraded"
            --old-bindir "/opt/PostgreSQL/postgres/17/bin"
            --new-bindir "/opt/PostgreSQL/postgres/18/bin"
    

  5. 启动升级后的 node1 发布端服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile
    

  6. 停止 node2 上的订阅端服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data2 stop
    

  7. 使用目标新版本初始化 data2_upgraded 实例。

  8. 将订阅端 node2 升级到目标新版本,例如:

    pg_upgrade
           --old-datadir "/opt/PostgreSQL/postgres/17/data2"
           --new-datadir "/opt/PostgreSQL/postgres/18/data2_upgraded"
           --old-bindir "/opt/PostgreSQL/postgres/17/bin"
           --new-bindir "/opt/PostgreSQL/postgres/18/bin"
    

  9. 启动升级后的 node2 订阅端服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile
    

  10. 在 node2 上,创建从步骤 1 到当前期间在升级后的发布端 node1 新建的表,例如:

    /* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
    

  11. 在 node2 上,使用 ALTER SUBSCRIPTION ... ENABLE 启用所有订阅来自 node1 变更的订阅,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
    

  12. 在 node2 上使用 ALTER SUBSCRIPTION ... REFRESH PUBLICATION 刷新订阅发布,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
    

注意

上述步骤中先升级发布端,再升级订阅端。也可以采用类似步骤先升级订阅端,再升级发布端。

29.13.3.2. 升级级联逻辑复制集群的步骤 #

假设有级联逻辑复制拓扑 node1->node2->node3。其中 node2 订阅 node1 的变更,node3 订阅 node2 的变更。node2 上有订阅 sub1_node1_node2,node3 上有订阅 sub1_node2_node3。

  1. 在 node2 上,使用 ALTER SUBSCRIPTION ... DISABLE 禁用所有订阅 node1 变更的订阅,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
    

  2. 停止 node1 上的服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data1 stop
    

  3. 使用目标新版本初始化 data1_upgraded 实例。

  4. 将 node1 服务器升级到目标新版本,例如:

    pg_upgrade
            --old-datadir "/opt/PostgreSQL/postgres/17/data1"
            --new-datadir "/opt/PostgreSQL/postgres/18/data1_upgraded"
            --old-bindir "/opt/PostgreSQL/postgres/17/bin"
            --new-bindir "/opt/PostgreSQL/postgres/18/bin"
    

  5. 启动升级后的 node1 服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile
    

  6. 在 node3 上,使用 ALTER SUBSCRIPTION ... DISABLE 禁用所有订阅 node2 变更的订阅,例如:

    /* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 DISABLE;
    

  7. 停止 node2 上的服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data2 stop
    

  8. 使用目标新版本初始化 data2_upgraded 实例。

  9. 将 node2 服务器升级到目标新版本,例如:

    pg_upgrade
            --old-datadir "/opt/PostgreSQL/postgres/17/data2"
            --new-datadir "/opt/PostgreSQL/postgres/18/data2_upgraded"
            --old-bindir "/opt/PostgreSQL/postgres/17/bin"
            --new-bindir "/opt/PostgreSQL/postgres/18/bin"
    

  10. 启动升级后的 node2 服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile
    

  11. 在 node2 上,创建从步骤 1 到当前期间在升级后的发布端 node1 新建的表,例如:

    /* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
    

  12. 在 node2 上,使用 ALTER SUBSCRIPTION ... ENABLE 启用所有订阅 node1 变更的订阅,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
    

  13. 在 node2 上使用 ALTER SUBSCRIPTION ... REFRESH PUBLICATION 刷新订阅发布,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
    

  14. 停止 node3 上的服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data3 stop
    

  15. 使用目标新版本初始化 data3_upgraded 实例。

  16. 将 node3 服务器升级到目标新版本,例如:

    pg_upgrade
            --old-datadir "/opt/PostgreSQL/postgres/17/data3"
            --new-datadir "/opt/PostgreSQL/postgres/18/data3_upgraded"
            --old-bindir "/opt/PostgreSQL/postgres/17/bin"
            --new-bindir "/opt/PostgreSQL/postgres/18/bin"
    

  17. 启动升级后的 node3 服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data3_upgraded start -l logfile
    

  18. 在 node3 上,创建从步骤 6 到当前期间在升级后的 node2 新建的表,例如:

    /* node3 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
    

  19. 在 node3 上,使用 ALTER SUBSCRIPTION ... ENABLE 启用所有订阅 node2 变更的订阅,例如:

    /* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 ENABLE;
    

  20. 在 node3 上使用 ALTER SUBSCRIPTION ... REFRESH PUBLICATION 刷新订阅发布,例如:

    /* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 REFRESH PUBLICATION;
    

29.13.3.3. 升级双节点环形逻辑复制集群的步骤 #

假设有环形逻辑复制拓扑 node1->node2 以及 node2->node1。其中 node2 订阅 node1 的变更,node1 订阅 node2 的变更。node1 上有订阅 sub1_node2_node1,node2 上有订阅 sub1_node1_node2。

  1. 在 node2 上,使用 ALTER SUBSCRIPTION ... DISABLE 禁用所有订阅 node1 变更的订阅,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
    

  2. 停止 node1 上的服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data1 stop
    

  3. 使用目标新版本初始化 data1_upgraded 实例。

  4. 将 node1 服务器升级到目标新版本,例如:

    pg_upgrade
            --old-datadir "/opt/PostgreSQL/postgres/17/data1"
            --new-datadir "/opt/PostgreSQL/postgres/18/data1_upgraded"
            --old-bindir "/opt/PostgreSQL/postgres/17/bin"
            --new-bindir "/opt/PostgreSQL/postgres/18/bin"
    

  5. 启动升级后的 node1 服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile
    

  6. 在 node2 上,使用 ALTER SUBSCRIPTION ... ENABLE 启用所有订阅 node1 变更的订阅,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
    

  7. 在 node1 上,创建从步骤 1 到当前期间在 node2 新建的表,例如:

    /* node1 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
    

  8. 在 node1 上使用 ALTER SUBSCRIPTION ... REFRESH PUBLICATION 刷新订阅发布,从 node2 复制初始表数据,例如:

    /* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 REFRESH PUBLICATION;
    

  9. 在 node1 上,使用 ALTER SUBSCRIPTION ... DISABLE 禁用所有订阅 node2 变更的订阅,例如:

    /* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 DISABLE;
    

  10. 停止 node2 上的服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data2 stop
    

  11. 使用目标新版本初始化 data2_upgraded 实例。

  12. 将 node2 服务器升级到目标新版本,例如:

    pg_upgrade
            --old-datadir "/opt/PostgreSQL/postgres/17/data2"
            --new-datadir "/opt/PostgreSQL/postgres/18/data2_upgraded"
            --old-bindir "/opt/PostgreSQL/postgres/17/bin"
            --new-bindir "/opt/PostgreSQL/postgres/18/bin"
    

  13. 启动升级后的 node2 服务器,例如:

    pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile
    

  14. 在 node1 上,使用 ALTER SUBSCRIPTION ... ENABLE 启用所有订阅 node2 变更的订阅,例如:

    /* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 ENABLE;
    

  15. 在 node2 上,创建从步骤 9 到当前期间在升级后的 node1 新建的表,例如:

    /* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
    

  16. 在 node2 上使用 ALTER SUBSCRIPTION ... REFRESH PUBLICATION 刷新订阅发布,从 node1 复制初始表数据,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
    

报告文档问题

阅读 上游文档. 通过 PostgreSQL 文档反馈表单.