全部產品
Search
文件中心

ApsaraDB RDS:唯讀執行個體本地邏輯複製槽

更新時間:Jun 19, 2026

RDS PostgreSQL支援在唯讀執行個體上建立本地邏輯複製槽,下遊訂閱者可以直接連接唯讀執行個體消費變更,從而將邏輯複製的消費流量從主執行個體轉移到唯讀執行個體,減輕主執行個體的負載。

前提條件

PostgreSQL 16或以上版本,且核心小版本不低於20260530。如提示不支援,請升級核心小版本,具體操作,請參見升級核心小版本

背景資訊

PostgreSQL 原生邏輯複製槽(Logical Replication Slot)在主執行個體上建立,下遊訂閱者必須串連主執行個體消費變更。RDS PostgreSQL 支援在唯讀執行個體上建立本地邏輯複製槽,使下遊訂閱者可以直接連接唯讀執行個體消費變更,以減輕主執行個體負載。邏輯複製槽的更多資訊,請參見PostgreSQL官方文檔

注意事項

  • 在唯讀執行個體上建立的邏輯複製槽為本地 slot,不參與主備容錯移轉。唯讀執行個體重搭(重建)後,這些 slot 將丟失,需要在重搭後重新建立。

  • 建議僅在非高可用的唯讀執行個體上使用此方式。如果唯讀執行個體承擔高可用讀流量,slot 丟失可能導致下遊訂閱中斷,需評估業務影響。

使用樣本

以下樣本假設已有主執行個體(RW)和唯讀執行個體(RO),且唯讀執行個體通過流複製與主執行個體保持資料同步。本文介紹以下三種典型使用方式:

  • 基本用法:在唯讀執行個體上手動建立並消費slot(使用test_decoding外掛程式),適用於自訂解碼邏輯情境。

  • 通過Subscription訂閱唯讀執行個體(自動建立slot):最典型的使用情境,由CREATE SUBSCRIPTION自動在唯讀執行個體上建立slot。

  • 通過Subscription訂閱唯讀執行個體(手動預建立slot):進階用法,先手動建立slot再建立訂閱,確保不丟失建立期間的變更。

基本用法:手動建立並消費slot

本樣本示範如何在唯讀執行個體上手動建立邏輯複製槽,並通過test_decoding外掛程式消費主執行個體的資料變更。

  1. 在唯讀執行個體上建立本地邏輯複製槽。

    -- [RO] 建立本地logical slot
    SELECT pg_create_logical_replication_slot('my_slot', 'test_decoding');
  2. 確認slot建立成功。

    -- [RO] 確認slot建立成功
    SELECT slot_name, plugin FROM pg_replication_slots WHERE slot_name = 'my_slot';

    查詢結果:

     slot_name |    plugin     
    -----------+---------------
     my_slot   | test_decoding 
    (1 row)
  3. 在主執行個體上寫入資料。

    -- [RW] 主庫寫入資料
    INSERT INTO my_table VALUES (1), (2), (3);
  4. 等待WAL回放到唯讀執行個體。

    在主執行個體上查詢當前WAL位置:

    -- [RW] 擷取主庫當前WAL位置
    SELECT pg_current_wal_lsn();

    在唯讀執行個體上查詢回放進度,直到回放位置不小於主執行個體的WAL位置:

    -- [RO] 查看唯讀執行個體回放進度
    SELECT pg_last_wal_replay_lsn();
    說明

    PostgreSQL 15及以上版本,也可以使用pg_wal_replay_wait(target_lsn)函數主動等待回放至指定LSN,無需輪詢。

  5. 在唯讀執行個體上通過slot消費變更。

    -- [RO] 通過slot消費變更
    SELECT * FROM pg_logical_slot_get_changes('my_slot', NULL, NULL);

    查詢結果:

        lsn    | xid |                  data
    -----------+-----+----------------------------------------
     0/XXXXXXX | 123 | table public.my_table: INSERT: ...
    (3 rows)
  6. 不再需要時,刪除slot。

    -- [RO] 刪除slot
    SELECT pg_drop_replication_slot('my_slot');

通過Subscription訂閱唯讀執行個體(自動建立slot)

這是最典型的使用情境:下遊訂閱執行個體(Subscriber)直接連接唯讀執行個體,由CREATE SUBSCRIPTION自動在唯讀執行個體上建立slot。

  1. 在主執行個體上建立表和發布。

    -- [RW] 主庫上建立表和publication
    CREATE TABLE tab_rep (id int PRIMARY KEY, data text);
    CREATE PUBLICATION my_pub FOR TABLE tab_rep;
  2. 等待WAL回放到唯讀執行個體,確保publication在唯讀執行個體上可見。等待方法請參見"基本用法"中的步驟4。

  3. 在下遊訂閱執行個體上建立相同的表結構。

    -- [Subscriber] 下遊執行個體建立表結構
    CREATE TABLE tab_rep (id int PRIMARY KEY, data text);
  4. 在下遊訂閱執行個體上建立訂閱,串連唯讀執行個體。

    -- [Subscriber] 建立subscription,串連唯讀執行個體
    -- subscription會自動在唯讀執行個體上建立名為'my_sub'的slot
    CREATE SUBSCRIPTION my_sub
        CONNECTION 'host=<RO_HOST> port=<RO_PORT> dbname=postgres'
        PUBLICATION my_pub
        WITH (copy_data = off);
    說明

    此操作會在唯讀執行個體上自動建立一個邏輯複製槽。該slot為唯讀執行個體本地slot,不參與容錯移轉,唯讀執行個體重搭後會丟失。

  5. 在主執行個體上寫入資料並驗證同步。

    -- [RW] 主庫寫入資料
    INSERT INTO tab_rep VALUES (1, 'hello'), (2, 'world');

    資料流向:RW →(流複製/WAL)→ RO →(邏輯複製)→ Subscriber。

    -- [Subscriber] 驗證資料已同步
    SELECT * FROM tab_rep;

    查詢結果:

     id | data
    ----+-------
      1 | hello
      2 | world
    (2 rows)
  6. 不再需要時,在下遊執行個體上刪除訂閱(會自動刪除唯讀執行個體上的slot)。

    -- [Subscriber] 刪除subscription,自動清理唯讀執行個體上的slot
    DROP SUBSCRIPTION my_sub;

通過Subscription訂閱唯讀執行個體(手動預建立slot)

如果需要先建立slot再建立訂閱(例如確保不丟失建立期間的變更),可以手動預建立slot。

  1. 在唯讀執行個體上手動建立slot。

    -- [RO] 先在唯讀執行個體上手動建立slot
    SELECT pg_create_logical_replication_slot('my_sub', 'pgoutput');
  2. 在下遊訂閱執行個體上建立訂閱,使用已有的slot。

    -- [Subscriber] 建立subscription,使用已有的slot,不再自動建立
    CREATE SUBSCRIPTION my_sub
        CONNECTION 'host=<RO_HOST> port=<RO_PORT> dbname=postgres'
        PUBLICATION my_pub
        WITH (copy_data = off, create_slot = false);
    說明

    通過指定create_slot = false,CREATE SUBSCRIPTION將直接使用唯讀執行個體上已有的slot,不會重複建立。後續使用方式與"通過Subscription訂閱唯讀執行個體(自動建立slot)"相同。