進階災難復原 (DR) 搭配邏輯容錯移轉時段

本頁面說明如何使用邏輯容錯移轉位置,設定 PostgreSQL 適用的 Cloud SQL 邏輯複製功能,與進階災難復原 (DR) 作業 (特別是 Cloud SQL Enterprise Plus 版執行個體上的切換和副本容錯移轉) 順暢搭配運作。

Cloud SQL 的進階災難復原 (DR) 功能可提供強大的災難復原能力。與 PostgreSQL 的邏輯複製功能搭配使用時,請務必確保複製串流在切換或副本容錯移轉後仍保持不中斷。

透過 PostgreSQL 的邏輯複寫功能使用進階災難復原 (DR) 功能,確保邏輯訂閱者不會遺失任何資料,並在災難復原事件後自動重新連線至新的主要執行個體,確保業務持續運作。

您可以在具備下列設定的 Cloud SQL 執行個體上使用這項功能:

  • PostgreSQL 17 以上版本
  • Cloud SQL Enterprise Plus 版
  • 私人服務連線

    建議使用私人服務存取權網域名稱服務 (DNS) 寫入端點,啟用自動邏輯訂閱者重新連線功能。

事前準備

使用邏輯複製設定進階災難復原 (DR)

如要使用 PostgreSQL 的邏輯複製功能設定進階災難復原 (DR),請按照下列高階步驟操作:

  1. 設定環境變數和堡壘主機
  2. 建立及設定主要執行個體
  3. 建立及指派 DR 副本
  4. 建立及設定邏輯訂閱者執行個體
  5. 建立邏輯複寫訂閱項目
  6. 執行切換或備用資源容錯移轉
  7. 驗證複製作業
  8. 清理新副本上孤立的複製運算單元
  9. 選用:執行切換作業

設定環境變數和堡壘 VM

  1. 設定下列環境變數。

    # Project
    export PROJECT="PROJECT_ID"
    
    # Instance names
    export PRIMARY_INSTANCE_NAME="PRIMARY_INSTANCE"
    export DR_REPLICA_NAME="DR_REPLICA"
    export SUBSCRIBER_INSTANCE_NAME="SUBSCRIBER_INSTANCE"
    export BASTION_VM_NAME="BASTION_VM"
    
    # Regions and zones
    export PRIMARY_REGION="PRIMARY_REGION"
    export REPLICA_REGION="REPLICA_REGION"
    export SUBSCRIBER_REGION="SUBSCRIBER_REGION"
    export VM_ZONE="VM_ZONE"
    
    # Network
    export NETWORK_NAME="NETWORK"
    
    # Credentials
    export POSTGRES_PASSWORD="PASSWORD"
    
    # Set gcloud project
    gcloud config set project PROJECT_ID
    

    更改下列內容:

    • PROJECT_ID:專案的 ID。
    • :主要 Cloud SQL 執行個體的名稱。PRIMARY_INSTANCE
    • DR_REPLICA:副本名稱。
    • SUBSCRIBER_INSTANCE:訂閱端執行個體的名稱。
    • BASTION_VM:防禦主機 VM 的名稱。
    • PRIMARY_REGION:主要執行個體所在的區域。
    • REPLICA_REGION:副本所在的區域。備用資源必須與主要執行個體位於不同地區。
    • SUBSCRIBER_REGION:訂閱者所在的區域。
    • VM_ZONE:堡壘 VM 所在的可用區。
    • NETWORK:虛擬私有雲網路的名稱。
    • PASSWORDpostgres 使用者的密碼。
  2. 建立 Compute Engine 堡壘主機 VM。

    Cloud SQL 執行個體使用私人 IP。因此,請在虛擬私有雲網路中建立 Compute Engine 堡壘主機 VM。

    gcloud compute instances create $BASTION_VM_NAME \
      --zone=$VM_ZONE \
      --machine-type=e2-small \
      --network=projects/$PROJECT_ID/global/networks/$NETWORK_NAME \
      --image-project=debian-cloud \
      --image-family=debian-11 \
      --project=$PROJECT
    
  3. 連線至堡壘 VM。

    gcloud compute ssh $BASTION_VM_NAME \
      --zone=$VM_ZONE \
      --project=$PROJECT
    
  4. 在堡壘主機 VM 上安裝 PostgreSQL 用戶端。

    sudo apt-get update
    sudo apt-get install -y postgresql-client
    exit
    

後續步驟中的 PostgreSQL 指令將從堡壘主機 VM 執行。

建立及設定主要執行個體

  1. 建立主要 Cloud SQL 執行個體。

    gcloud sql instances create $PRIMARY_INSTANCE_NAME \
      --database-version=POSTGRES_17 \
      --edition=ENTERPRISE_PLUS \
      --region=$PRIMARY_REGION \
      --tier=db-perf-optimized-N-2 \
      --no-assign-ip \
      --network=projects/$PROJECT/global/networks/$NETWORK_NAME \
      --project=$PROJECT
    
  2. 啟用邏輯解碼。

    gcloud sql instances patch $PRIMARY_INSTANCE_NAME \
      --database-flags=cloudsql.logical_decoding=on \
      --project=$PROJECT
    
  3. 在主要節點上為 postgres 使用者設定密碼。

    gcloud sql users set-password postgres \
      --instance=$PRIMARY_INSTANCE_NAME \
      --password="$POSTGRES_PASSWORD" \
      --project=$PROJECT
    
  4. 從防禦主機 VM 連線至主要執行個體。

    1. 擷取主要執行個體的私人 IP 位址。

      gcloud sql instances describe $PRIMARY_INSTANCE_NAME \
        --format="value(ipAddresses[0].ipAddress)" \
        --project=$PROJECT
      

      複製並保留主要執行個體的私人 IP 位址。

    2. 透過 SSH 連線至堡壘主機 VM。

      gcloud compute ssh $BASTION_VM_NAME --zone=$VM_ZONE --project=$PROJECT
      
    3. 從防禦主機 VM 連線至主要執行個體。

      psql -h PRIMARY_PRIVATE_IP -U postgres
      

      PRIMARY_PRIVATE_IP 替換為您在本程序的步驟 4.a 中擷取的主要執行個體私人 IP。

    4. 系統提示輸入密碼時,請輸入變數 $POSTGRES_PASSWORD

      現在,堡壘 VM 會透過 PostgreSQL 連線至主要執行個體。

  5. 授予權限並建立發布內容。

    1. REPLICATION 權限授予 postgres 使用者。

      ALTER USER postgres WITH REPLICATION;
      
    2. 授予 public 結構定義和資料表的必要權限。

      GRANT SELECT ON ALL TABLES IN SCHEMA public TO postgres;
      
    3. 為所有資料表建立發布作業。

      CREATE PUBLICATION my_publication FOR ALL TABLES;
      
    4. 輸入 exit 退出 PostgreSQL,然後再次輸入 exit 關閉堡壘 VM 的 SSH 工作階段。

建立及指派災難復原備用資源 (DR 備用資源)

  1. 建立 DR 副本。

    gcloud sql instances create $DR_REPLICA_NAME \
      --master-instance-name=$PRIMARY_INSTANCE_NAME \
      --edition=ENTERPRISE_PLUS \
      --tier=db-perf-optimized-N-2 \
      --region=$REPLICA_REGION \
      --no-assign-ip \
      --network=projects/$PROJECT/global/networks/$NETWORK_NAME \
      --project=$PROJECT
    
  2. 將這個副本指派為災難復原副本。

    gcloud sql instances patch $PRIMARY_INSTANCE_NAME \
      --failover-dr-replica-name=$DR_REPLICA_NAME \
      --project=$PROJECT
    
  3. 設定 DR 副本,以進行邏輯時段同步。

    gcloud sql instances patch $DR_REPLICA_NAME \
      --database-flags="^:^cloudsql.logical_decoding=on:hot_standby_feedback=on:sync_replication_slots=on:cloudsql.logical_slot_sync_dbname=postgres" \
      --project=$PROJECT
    
  4. 在主要執行個體和 DR 副本之間設定同步複製。

    為避免主要執行個體突然中斷服務,導致邏輯訂閱者可能遺失資料,並防止後續的備用資源容錯移轉失敗,建議您在主要執行個體和 DR 備用資源之間設定同步複製。

    在主要執行個體上設定 cloudsql.synchronized_standby_replicas,會強制主要執行個體的邏輯複製預先寫入記錄 (WAL) 傳送者等待,直到 DR 副本收到並清除特定交易的 WAL,再將該交易傳送至邏輯訂閱者。這可確保 DR 副本的狀態一律領先或等同於邏輯訂閱者的狀態。

    gcloud sql instances patch $PRIMARY_INSTANCE_NAME \
      --database-flags="^:^cloudsql.logical_decoding=on:cloudsql.synchronized_standby_replicas=$DR_REPLICA_NAME" \
      --project=$PROJECT
    

建立及設定邏輯訂閱端執行個體

  1. 建立訂閱端執行個體。

    gcloud sql instances create $SUBSCRIBER_INSTANCE_NAME \
      --database-version=POSTGRES_17 \
      --tier=db-perf-optimized-N-2 \
      --region=$SUBSCRIBER_REGION \
      --no-assign-ip \
      --network=projects/$PROJECT/global/networks/$NETWORK_NAME \
      --project=$PROJECT
    
  2. 在訂閱者上啟用邏輯解碼。

    gcloud sql instances patch $SUBSCRIBER_INSTANCE_NAME \
      --database-flags=cloudsql.logical_decoding=on \
      --project=$PROJECT
    

建立邏輯複製訂閱項目

  1. 擷取主要執行個體的私人服務存取權寫入端點。

    gcloud sql instances describe $PRIMARY_INSTANCE_NAME \
      --format="value(replicationCluster.psaWriteEndpoint)" \
      --project=$PROJECT
    

    複製並保留寫入端點。

  2. 連線至訂閱端執行個體。

    1. 更新訂閱端執行個體的 postgres 使用者密碼。

      gcloud sql users set-password postgres \
        --instance=$SUBSCRIBER_INSTANCE_NAME \
        --password="$POSTGRES_PASSWORD" \
        --project=$PROJECT
      
    2. 擷取訂閱端執行個體的私人 IP 位址。

      gcloud sql instances describe $SUBSCRIBER_INSTANCE_NAME \
        --format="value(ipAddresses[0].ipAddress)" \
        --project=$PROJECT
      

      複製並保留私人 IP 位址。

    3. 透過 SSH 連線至防禦主機 VM。

      gcloud compute ssh $BASTION_VM_NAME \
        --zone=$VM_ZONE \
        --project=$PROJECT
      
    4. 從防禦 VM 透過 PostgreSQL 連線至訂閱者執行個體。

      psql -h SUBSCRIBER_PRIVATE_IP -U postgres
      

      SUBSCRIBER_PRIVATE_IP 替換成您在本程序的步驟 2.b 中複製的訂閱者執行個體私人 IP。

    5. 系統提示輸入密碼時,請輸入變數 $POSTGRES_PASSWORD

  3. 建立訂閱項目。

    CREATE SUBSCRIPTION my_subscription
    CONNECTION 'host=DR_CLUSTER_PSA_DNS_WRITE_ENDPOINT port=5432 dbname=postgres user=postgres password=PASSWORD'
    PUBLICATION my_publication
    WITH (failover = true);
    

    更改下列內容:

    • DR_CLUSTER_PSA_DNS_WRITE_ENDPOINT:您在本程序步驟 1 複製的私有服務存取寫入端點。
    • PASSWORD:變數 ${POSTGRES_PASSWORD} 的值。
  4. 退出 PostgreSQL 和堡壘主機 VM 的 SSH 工作階段。

  5. 選用。確認 DR 副本上的時段持續性。

    如果主要裝置活動量較低,通常會在幾秒內轉換為持續性 (temporary = false)。如果主要節點的寫入負載量很高,這個程序可能需要較長時間,通常約為一分鐘。完成這些手動指令後,該時段應會持續存在。

    1. 取得 DR 副本的私人 IP 位址。

      gcloud sql instances describe $DR_REPLICA_NAME \
        --format="value(ipAddresses[0].ipAddress)" \
        --project=$PROJECT
      

      複製並保留 DR 副本的私人 IP 位址。

    2. 透過 SSH 連線至防禦主機 VM。

      gcloud compute ssh $BASTION_VM_NAME \
        --zone=$VM_ZONE \
        --project=$PROJECT
      
    3. 從防禦 VM 連線至 DR 副本。

      psql -h DR_REPLICA_PRIVATE_IP -U postgres
      

      DR_REPLICA_PRIVATE_IP 替換為您在本程序的步驟 5.a 中擷取的 DR 副本私人 IP 位址。

    4. 系統提示輸入密碼時,請輸入變數 $POSTGRES_PASSWORD

    5. 檢查插槽狀態。

      SELECT slot_name, slot_type, temporary, failover, synced
      FROM pg_replication_slots
      WHERE slot_type = 'logical' AND failover = true;
      

      等待 temporary 欄變成 f。這通常不到一分鐘即可完成。

    6. 退出 PostgreSQL 和堡壘主機 VM 的 SSH 工作階段。

執行切換或備用資源容錯移轉

根據您的情境選擇要執行的作業:

  • 切換 (角色反轉):如果主要執行個體處於上線且運作正常的狀態,請選擇這個選項,以便進行定期維護、災難復原測試或切換角色。這項作業可確保實體複寫不會遺失任何資料。

    gcloud sql instances switchover $DR_REPLICA_NAME \
      --project=$PROJECT
    
  • 副本容錯移轉 (災難復原):主要執行個體無法使用或沒有回應時,請選擇這個選項。這項作業會將 DR 副本升級為主要副本。為盡量降低邏輯訂閱者遺失資料的風險,請務必按照「建立及指派災難復原副本 (DR 副本)」一文的建議,在主要執行個體上設定 cloudsql.synchronized_standby_replicas

    gcloud sql instances promote-replica $DR_REPLICA_NAME \
      --failover \
      --project=$PROJECT
    

    $DR_REPLICA_NAME的升級速度很快,不過,原始主要執行個體 ($PRIMARY_INSTANCE_NAME) 恢復連線後,只會重新設定為新主要執行個體的副本。如要追蹤這項作業,請在作業記錄中尋找 $PRIMARY_INSTANCE_NAME 上的 RECONFIGURE_OLD_PRIMARY 作業是否已完成。執行下列指令:

    gcloud sql operations list --instance=$PRIMARY_INSTANCE_NAME --project=$PROJECT --limit=10`
    

    只有在這個階段完成後,災難復原設定才會完全還原。

完成任一作業後,訂閱者會透過私有服務存取寫入端點,自動重新連線至新的主要 $DR_REPLICA_NAME

管理檢舉

在容錯移轉和副本容錯移轉作業期間和之後,Cloud SQL 的工作流程會自動管理災難復原叢集中兩個執行個體上的必要資料庫標記,包括:

  • 系統會確保成為新副本的執行個體,其邏輯運算單元同步處理旗標 (cloudsql.logical_decodinghot_standby_feedbacksync_replication_slotscloudsql.logical_slot_sync_dbname) 正確無誤。
  • 系統會自動更新成為新主要執行個體的執行個體上的 cloudsql.synchronized_standby_replicas 標記,指向新的 DR 副本名稱。

切換或副本容錯移轉作業後,您不需要手動重新套用或變更這些標記。Cloud SQL 會維護主要和備用角色正確的設定。

驗證複製作業

  1. 檢查訂閱者的狀態。

    1. 從防禦主機 VM 執行下列指令。

      psql -h SUBSCRIBER_PRIVATE_IP -U postgres
      

      SUBSCRIBER_PRIVATE_IP 替換為訂閱端執行個體的私人 IP 位址。

    2. 在訂閱者執行個體上執行下列指令。

      SELECT subname, pid IS NOT NULL AS is_active
      FROM pg_stat_subscription;
      

      狀態應為 streaming

  2. 檢查新主節點的複製運算單元狀態。新的主要資源是先前的 DR 備用資源 ($DR_REPLICA_NAME)。

    1. 取得新主節點的私人 IP 位址。

      gcloud sql instances describe $DR_REPLICA_NAME \
        --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"
      

      複製並保留新主機的私人 IP 位址。

    2. 透過 SSH 連線至防禦主機 VM。

      psql -h NEW_PRIMARY_PRIVATE_IP -U postgres
      

      NEW_PRIMARY_PRIVATE_IP 替換成您在上一個步驟中複製的新主要執行個體私有 IP 位址。

    3. 在新主要執行個體上執行下列指令。

      SELECT
          slot_name,
          slot_type,
          active,
          synced,
          active_pid,
          pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) AS replication_lag
      FROM pg_replication_slots
      WHERE slot_type = 'logical';
      

      插槽 (例如 my_subscription) 應為 active = t

      SELECT
          application_name,
          state
      FROM pg_stat_replication;
      

      pg_stat_replication 應會顯示已連線的訂閱者。

清理新副本上孤立的複製運算單元

切換和容錯移轉作業完成後,原始主要執行個體 ($PRIMARY_INSTANCE_NAME) 現在是副本。這個新備用執行個體仍會在磁碟上保留名為 my_subscription 的原始邏輯複寫時段。這個 my_subscription 時段現在已成為孤立時段,因為訂閱者應透過私人服務存取寫入端點,連線至新的主要時段 ($DR_REPLICA_NAME)。

Cloud SQL 不會自動從新的副本移除這個孤立的時段。這是因為 Cloud SQL 無法判斷訂閱者是否已設定為使用執行個體的 IP 位址,而非私人服務存取權寫入端點。在手動變更訂閱項目之前,訂閱者可能仍會嘗試連線至新副本上的舊時段。自動捨棄時段可能會導致這類設定中斷。

新副本上出現這個孤立的時段 ($PRIMARY_INSTANCE_NAME),會導致這個執行個體上的 slotsync 工作站程序在記錄中產生錯誤。您可能會在新的副本 postgres.log 中看到類似下列內容的錯誤訊息。由於 slotsync 工作人員會持續嘗試,因此這個錯誤會不斷重複。

ERROR: exiting from slot synchronization because same name slot "my_subscription" already exists on the standby

如要避免這類錯誤,並讓 slotsync 工作站正確建立這個副本上 my_subscription 廣告空間的新同步版本,您需要手動捨棄孤立的廣告空間。這樣一來,日後切換回舊版時,這個執行個體就能正常運作。

  1. 擷取新副本的私人 IP 位址 ($PRIMARY_INSTANCE_NAME)。

    gcloud sql instances describe $PRIMARY_INSTANCE_NAME \
      --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"
    

    複製並保留新副本的私人 IP 位址。

  2. 透過 SSH 連線至防禦主機 VM。

    gcloud compute ssh $BASTION_VM_NAME \
      --zone=$VM_ZONE \
      --project=$PROJECT
    
  3. 從防禦 VM 連線至新的副本。

    psql -h NEW_REPLICA_IP -U postgres
    

    NEW_REPLICA_IP 替換為您在本程序步驟 1 中複製的新副本 IP 位址。

  4. 系統提示輸入密碼時,請輸入變數 $POSTGRES_PASSWORD

  5. 在新副本 ($PRIMARY_INSTANCE_NAME) 上,捨棄孤立的運算單元。

    SELECT slot_name, slot_type, temporary, failover, synced, active
    FROM pg_replication_slots
    WHERE slot_name = 'my_subscription';
    

    確認該位置有 synced = falseactive = false,然後將其放下。

    SELECT pg_drop_replication_slot('my_subscription');
    

    系統會移除孤立的運算單元。

自動重新同步處理時段

孤立的時段遭捨棄後,新副本 ($PRIMARY_INSTANCE_NAME) 上的 slotsync 工作人員會在下一個週期自動連線至新的主要副本 ($DR_REPLICA_NAME)。這會建立新的本機 my_subscription 片段,並與新主項目的有效片段同步。

您可以在新副本的 postgres.log 中看到類似下列內容的訊息,表示成功:

LOG: newly created slot "my_subscription" is sync-ready now

新的同步化時段會標示為 failover=true,最終會成為永久時段 (temporary=false),確保您之後切換回來時,這個執行個體已準備就緒。

選用:執行切換回原版本

  1. 現在切換回來,再次將 $PRIMARY_INSTANCE_NAME 設為主要執行個體。

    gcloud sql instances switchover $PRIMARY_INSTANCE_NAME \
      --project=$PROJECT
    
  2. 切換回原先的帳戶後,請完成驗證。

    1. 檢查訂閱端執行個體的狀態。

      SELECT subname, pid IS NOT NULL AS is_active
      FROM pg_stat_subscription;
      

      訂閱方案應仍處於有效狀態,也就是 is_active = t

    2. 檢查新主要節點 ($PRIMARY_INSTANCE_NAME) 的狀態。

      SELECT slot_name, active FROM pg_replication_slots WHERE slot_type = 'logical';
      SELECT * FROM pg_stat_replication;
      

      該時段應處於啟用狀態,且訂閱者已連線。

疑難排解

問題 疑難排解

切換後,新備用資源 (即舊的主要執行個體) 發生錯誤:

"exiting from slot synchronization because same name slot already exists on the standby"

請按照「清除新副本上孤立的複寫位置」一文中的步驟操作。