2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18)
開發版本: devel

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 可執行目錄中。

  • 舊叢集已將所有事務和邏輯解碼訊息複製到訂閱伺服器。

  • 舊叢集上的所有槽都必須可用,即沒有槽的 pg_replication_slots.conflictingtrue

  • 新叢集不能有永久邏輯槽,即不能有 pg_replication_slots.temporaryfalse 的槽。

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 節 中指定的步驟來升級雙節點邏輯複製叢集。

  • 請按照 第 29.13.3.2 節 中指定的步驟來升級級聯邏輯複製叢集。

  • 請按照 第 29.13.3.3 節 中指定的步驟來升級雙節點迴圈邏輯複製叢集。

29.13.3.1. 升級雙節點邏輯複製叢集的步驟 #

假設釋出伺服器在 node1,訂閱伺服器在 node2。訂閱伺服器 node2 有一個訂閱 sub1_node1_node2,它訂閱了來自 node1 的更改。

  1. 透過使用 ALTER SUBSCRIPTION ... DISABLE 命令,停用 node2 上所有訂閱了來自 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. 透過使用 ALTER SUBSCRIPTION ... ENABLE 命令,啟用 node2 上所有訂閱了來自 node1 的更改的訂閱,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
    
  12. 使用 ALTER SUBSCRIPTION ... REFRESH PUBLICATION 命令重新整理 node2 訂閱的釋出,例如:

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

注意

在上述步驟中,先升級釋出伺服器,然後升級訂閱伺服器。或者,使用者也可以使用類似的步驟先升級訂閱伺服器,然後升級釋出伺服器。

29.13.3.2. 升級級聯邏輯複製叢集的步驟 #

假設我們有一個級聯邏輯複製設定 node1->node2->node3。這裡 node2 訂閱來自 node1 的更改,而 node3 訂閱來自 node2 的更改。node2 有一個訂閱 sub1_node1_node2,它訂閱來自 node1 的更改。node3 有一個訂閱 sub1_node2_node3,它訂閱來自 node2 的更改。

  1. 透過使用 ALTER SUBSCRIPTION ... DISABLE 命令,停用 node2 上所有訂閱了來自 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. 透過使用 ALTER SUBSCRIPTION ... DISABLE 命令,停用 node3 上所有訂閱了來自 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. 透過使用 ALTER SUBSCRIPTION ... ENABLE 命令,啟用 node2 上所有訂閱了來自 node1 的更改的訂閱,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
    
  13. 使用 ALTER SUBSCRIPTION ... REFRESH PUBLICATION 命令重新整理 node2 訂閱的釋出,例如:

    /* 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. 透過使用 ALTER SUBSCRIPTION ... ENABLE 命令,啟用 node3 上所有訂閱了來自 node2 的更改的訂閱,例如:

    /* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 ENABLE;
    
  20. 使用 ALTER SUBSCRIPTION ... REFRESH PUBLICATION 命令重新整理 node3 訂閱的釋出,例如:

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

29.13.3.3. 升級雙節點迴圈邏輯複製叢集的步驟 #

假設我們有一個迴圈邏輯複製設定 node1->node2node2->node1。這裡 node2 訂閱來自 node1 的更改,而 node1 訂閱來自 node2 的更改。node1 有一個訂閱 sub1_node2_node1,它訂閱來自 node2 的更改。node2 有一個訂閱 sub1_node1_node2,它訂閱來自 node1 的更改。

  1. 透過使用 ALTER SUBSCRIPTION ... DISABLE 命令,停用 node2 上所有訂閱了來自 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. 透過使用 ALTER SUBSCRIPTION ... ENABLE 命令,啟用 node2 上所有訂閱了來自 node1 的更改的訂閱,例如:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
    
  7. node1 上,建立在 步驟 1 和現在之間在 node2 中建立的任何表,例如:

    /* node1 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
    
  8. 使用 ALTER SUBSCRIPTION ... REFRESH PUBLICATION 命令重新整理 node1 訂閱的釋出,以從 node2 複製初始表資料,例如:

    /* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 REFRESH PUBLICATION;
    
  9. 透過使用 ALTER SUBSCRIPTION ... DISABLE 命令,停用 node1 上所有訂閱了來自 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. 透過使用 ALTER SUBSCRIPTION ... ENABLE 命令,啟用 node1 上所有訂閱了來自 node2 的更改的訂閱,例如:

    /* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 ENABLE;
    
  15. node2 上,建立在 步驟 9 和現在之間在升級後的 node1 中建立的任何表,例如:

    /* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
    
  16. 使用 ALTER SUBSCRIPTION ... REFRESH PUBLICATION 命令重新整理 node2 訂閱的釋出,以從 node1 複製初始表資料,例如:

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

提交更正

如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。