在 PostgreSQL 適用的 AlloyDB 與 AlloyDB Omni 之間複製資料

選取說明文件版本:

本頁說明如何使用 pglogical 擴充功能,在 PostgreSQL 適用的 AlloyDB 和 AlloyDB Omni 之間複製資料。

如要瞭解 AlloyDB Omni 中的 pglogical 總覽、優點和限制,請參閱「關於 pglogical 擴充功能」。

pglogical 的主要元件

pglogical 擴充功能的關鍵元件如下:

  • 節點:PostgreSQL 叢集內資料庫的參照。 pglogical 擴充功能會安裝到叢集中的任意數量資料庫,並對這些資料庫運作,每個資料庫都會做為不同的 pglogical 節點。每個節點可以是供應商 (也稱為複製來源) 或訂閱者 (也稱為複製目標),也可以同時是兩者。每個資料庫只能有一個節點。
  • 複寫集:在供應商資料庫中定義為要遷移的資料表和序列的邏輯分組,以及需要複寫的 SQL 陳述式,例如 INSERT, UPDATE, DELETE, TRUNCATE。您可以將資料表指派給多個複寫集。系統預設提供三組預先設定的複寫集,例如 defaultdefault_insert_onlyddl_sql,您可以視需要新增任意數量的複寫集。
  • 訂閱:提供從供應商資料庫複製的變更詳細資料,以及從訂閱者資料庫複製的變更。訂閱項目會透過連線字串指定供應商資料庫,並視需要指定要從該供應商複製哪些複寫集。此外,您也可以在建立訂閱項目時指定是否要使用 apply delay

在這個部署作業中,PostgreSQL 適用的 AlloyDB 服務是供應商,而地端 AlloyDB Omni 是訂閱者。請注意,您也可以設定相反的配置。

支援的驗證方法

在 AlloyDB Omni 上實作 pglogical 擴充功能之前,請務必考量複寫節點之間的網路和安全性。與 pglogical 擴充功能搭配使用的兩種主要驗證方法是密碼和信任驗證方法。

建議使用信任驗證方法,因為在密碼驗證方法中,密碼會以純文字格式儲存在 pglogical 擁有的資料庫表格中。如果使用者有權查詢這些資料表、存取非二進位備份檔,以及查看 PostgreSQL 記錄檔,就能以純文字形式看到這些密碼。

如果您使用信任驗證方法,則必須在主機式驗證檔案 pg_hba.conf 中建立特定項目,才能確保最高安全性。您可以指定目標資料庫來限制存取權,只允許複製選項或特定資料庫、複製使用者,以及僅限來自訂閱者特定 IP 位址的存取要求。

事前準備

您可以在特定資料庫中安裝 pglogical 做為擴充功能。

在 AlloyDB Omni 上實作 pglogical 擴充功能前,請確認您符合下列系統需求:

  • AlloyDB for PostgreSQL 叢集,以及主要執行個體的讀取/寫入存取權 (以 AlloyDB for PostgreSQL 管理員身分)。如需如何佈建 AlloyDB for PostgreSQL 叢集的說明,請參閱「建立及連線至 AlloyDB for PostgreSQL 資料庫」。
  • 已安裝及設定的 AlloyDB Omni 伺服器。如需安裝 AlloyDB Omni 的操作說明,請參閱「安裝 AlloyDB Omni」。
  • PostgreSQL 適用的 AlloyDB 主要執行個體和 AlloyDB Omni 主機伺服器的 IP 位址。
  • AlloyDB for PostgreSQL 與 AlloyDB Omni 主機伺服器之間已建立安全網路。必須透過標準 PostgreSQL 通訊埠 5432 建立 TCP 連線。

調整 AlloyDB for PostgreSQL 供應商的參數

pglogical 擴充功能需要在 PostgreSQL 適用的 AlloyDB 供應商叢集上進行最少的參數調整。您必須將 wal_level 參數設為 logical,並在 postgresql.conf 檔案中,將 pglogical 附加至 shared_preload_libraries 參數。

   cp postgresql.conf postgresql.bak
   sed -r -i "s|(\#)?wal_level\s*=.*|wal_level=logical|" postgresql.conf
   sed -r -i "s|(\#)?(shared_preload_libraries\s*=\s*)'(.*)'.*$|\2'\3,pglogical'|" postgresql.conf
   sed -r -i "s|',|'|" postgresql.conf

在 AlloyDB for PostgreSQL 服務中,您可以設定適當的叢集標記來調整參數。

您必須調整下列 AlloyDB for PostgreSQL 旗標的參數:

  • alloydb.enable_pglogical = on
  • alloydb.logical_decoding = on

如要瞭解如何在 AlloyDB for PostgreSQL 中設定資料庫標記,請參閱「設定執行個體的資料庫標記」。

如要設定其他必要供應商節點資料庫參數,請按照下列方式設定 AlloyDB for PostgreSQL 預設值:

  • max_worker_processes:每個供應商資料庫各一個,且每個訂閱者節點至少一個。這個參數的標準值為至少 10。
  • max_replication_slots:提供者節點上每個節點各一個。
  • max_wal_senders:提供者節點上每個節點各一個。
  • track_commit_timestamp:如果需要解決最後或第一次更新的衝突,請設為 on
  • listen_addresses:必須包含 AlloyDB Omni IP 位址,或透過涵蓋的 CIDR 區塊提及。

您可以使用任何查詢工具 (例如 psql) 檢查這些參數。

調整 AlloyDB Omni 訂閱端叢集的參數

pglogical擴充功能也需要在 AlloyDB Omni 訂閱者上進行最少的參數調整。您必須在 DATA_DIR/postgresql.conf 檔案中,將 pglogical 附加至 shared_preload_libraries 參數。如果叢集中的任何資料庫充當供應商資料庫,請對供應商資料庫進行必要的參數變更。

DATA_DIR 替換為資料目錄的檔案系統路徑,例如 /home/$USER/alloydb-data

  1. 調整參數:

    sudo sed -r -i "s|(shared_preload_libraries\s*=\s*)'(.*)'.*$|\1'\2,pglogical'|" DATA_DIR/postgresql.conf
  2. 確認參數設定正確無誤:

    grep -iE 'shared_preload_libraries' DATA_DIR/postgresql.conf
  3. 重新啟動 AlloyDB Omni,讓參數變更生效:

    Docker

     docker container restart CONTAINER_NAME

    CONTAINER_NAME 替換為您在安裝 AlloyDB Omni 容器時指派的名稱。

    Podman

     podman container restart CONTAINER_NAME

    CONTAINER_NAME 替換為您在安裝 AlloyDB Omni 容器時指派的名稱。

  4. 為其他供應商資料庫參數設定 AlloyDB Omni 預設值:

    • max_worker_processes:每個供應商資料庫各一個,每個訂閱者節點各一個。
    • track_commit_timestamp:如果需要解決最後或首次更新的衝突,請設為 on
  5. 確認所有參數值都已正確設定:

    Docker

     docker exec CONTAINER_NAME psql -h localhost -U postgres -c "
     SELECT name, setting
       FROM pg_catalog.pg_settings
      WHERE name IN ('listen_addresses',
                     'wal_level',
                     'shared_preload_libraries',
                     'max_worker_processes',
                     'max_replication_slots',
                     'max_wal_senders',
                     'track_commit_timestamp')
          ORDER BY name;"

    Podman

     podman exec CONTAINER_NAME psql -h localhost -U postgres -c "
     SELECT name, setting
       FROM pg_catalog.pg_settings
      WHERE name IN ('listen_addresses',
                     'wal_level',
                     'shared_preload_libraries',
                     'max_worker_processes',
                     'max_replication_slots',
                     'max_wal_senders',
                     'track_commit_timestamp')
          ORDER BY name;"

調整 AlloyDB Omni 訂閱者叢集的主機型驗證

pglogical 會建立與 AlloyDB Omni 訂閱端資料庫的本機 TCP 連線。因此,您必須將訂閱者的主機伺服器 IP 位址新增至 AlloyDB Omni DATA_DIR/pg_hba.conf 檔案。

  1. DATA_DIR/pg_hba.conf 檔案中,為新 pglogical_replication 使用者新增本機伺服器的信任驗證項目:

    echo -e "# pglogical entries:
    host all pglogical_replication samehost trust
    " | column -t | sudo tee -a DATA_DIR/pg_hba.conf
  2. 確認輸入的內容正確無誤:

    tail -2 DATA_DIR/pg_hba.conf
  3. 重新啟動 AlloyDB Omni,讓驗證變更生效:

    Docker

    docker container restart CONTAINER_NAME

    Podman

    podman container restart CONTAINER_NAME

在提供者和訂閱者叢集中建立 pglogical 使用者

您必須在供應商和訂閱者叢集中建立新使用者。 如要使用 pglogical,使用者必須同時具備 superuserreplication 權限。

  1. 在 AlloyDB for PostgreSQL 供應商叢集中,建立使用者並授予 alloydbsuperuser 角色:

    CREATE USER pglogical_replication LOGIN PASSWORD 'secret';
    ALTER USER pglogical_replication WITH replication;
    GRANT alloydbsuperuser TO pglogical_replication;
    
  2. 在 AlloyDB Omni 訂閱端叢集中,建立使用者並授予 replicationsuperuser 屬性:

    CREATE USER pglogical_replication LOGIN PASSWORD 'secret';
    ALTER USER pglogical_replication WITH replication;
    ALTER USER pglogical_replication WITH superuser;
    

在 PostgreSQL 適用的 AlloyDB 提供者資料庫中新增 pglogical 和節點

  1. 授予必要權限。

    您必須在每個資料庫中安裝 pglogical 擴充功能,並將 usage 權限授予 pglogical 資料庫使用者。在 PostgreSQL 適用的 AlloyDB 中,您必須授予 pglogical 結構定義的權限。

    舉例來說,如果資料庫是 my_test_db,請對 AlloyDB for PostgreSQL 供應商資料庫執行下列指令:

       \c my_test_db;
     CREATE EXTENSION IF NOT EXISTS pglogical;
     GRANT usage ON SCHEMA pglogical TO pglogical_replication;
    -- For Google Cloud AlloyDB we also need to manually grant privileges:
     GRANT ALL PRIVILEGES ON ALL tables IN SCHEMA pglogical TO pglogical_replication;
    
  2. 為供應商資料庫建立 pglogical 節點。 node_name 是任意值,而 dsn 字串必須是連回相同資料庫的有效 TCP 連線。如果是 PostgreSQL 適用的 AlloyDB,dsn 的主機部分是為主要執行個體提供的 IP 位址。

    對於 PostgreSQL 適用的 AlloyDB,系統不允許信任驗證,且密碼引數必須包含在 dsn 中。參數。

    舉例來說,如要使用 my_test_db 資料庫,請執行下列指令:

    SELECT pglogical.create_node(node_name := 'provider', dsn := 'host=SERVER_IP_ADDRESS
    port=5432 dbname=my_test_db user=pglogical_replication password=secret');
    

建立資料表並新增至預設複寫集

建立資料表,並將其新增至 PostgreSQL 適用的 AlloyDB 供應商資料庫預設複製集。

  1. 在供應商資料庫中建立名為 test_table_1 的測試資料表:

    CREATE TABLE test_table_1 (col1 INT PRIMARY KEY);
    INSERT INTO test_table_1 VALUES (1),(2),(3);
    
  2. 在個別資料表上授予 SELECT,或執行 GRANT SELECT ON ALL TABLES 指令。凡是屬於複寫集一部分的資料表,都必須授予複寫使用者 pglogical_replication 查詢權限。

    GRANT SELECT ON ALL TABLES IN SCHEMA public TO pglogical_replication;
    
  3. 手動將測試資料表新增至預設複寫集。 您可以建立自訂的 pglogical 複寫集,也可以使用預設的複寫集。建立擴充功能時,系統會建立多個預設複寫集,例如 defaultdefault_insert_onlyddl_sql。您可以個別將資料表和序列新增至複寫集,也可以一次新增指定結構定義的所有資料表和序列。

    -- Add the specified table to the default replication set:
    SELECT pglogical.replication_set_add_table(set_name := 'default', relation := 'test_table_1', synchronize_data := TRUE);
    
    -- Check which tables have been added to all replication sets:
    SELECT * FROM pglogical.replication_set_table;
    
  4. (選用) 新增指定結構定義中的所有資料表,例如 public

    -- Add all "public" schema tables to the default replication set:
    SELECT pglogical.replication_set_add_all_tables('default', ARRAY['public']);
    
    -- Check which tables have been added to all replication sets:
    SELECT * FROM pglogical.replication_set_table;
    
    -- Add all "public" schema sequences to the default replication:
    SELECT pglogical.replication_set_add_all_sequences('default', ARRAY['public']);
    
     -- Check which sequences have been added to all replication sets:
    SELECT * FROM pglogical.replication_set_seq;
    
  5. default 複寫集移除資料表。 如果結構定義中有任何資料表沒有主鍵,您可以設定僅供 INSERT 複製,也可以使用 REPLICA IDENTITY 功能搭配 ALTER TABLE 指令,設定可唯一識別資料列的資料欄。如果您使用 replication_set_add_all_tables 函式,將這些表格自動新增至 default 複寫集,則必須手動從該複寫集中移除這些表格,並將其新增至 default_insert_only 集。

    -- Remove the table from the **default** replication set:
    SELECT pglogical.replication_set_remove_table(set_name := 'default', relation := 'test_table_2');
    
    -- Manually add to the **default_insert_only** replication set:
    SELECT pglogical.replication_set_add_table(set_name := 'default_insert_only', relation := 'test_table_2');
    

    或者,如要將新建立的資料表自動新增至複寫集,請按照pglogical來源中的建議新增 pglogical_assign_repset 觸發條件。

將資料庫複製到 AlloyDB Omni 訂閱者叢集

  1. 使用 pg_dump 公用程式,建立來源資料庫的僅限結構定義備份。

  2. 使用 AlloyDB for PostgreSQL 主要執行個體的 IP 位址,從 AlloyDB Omni 訂閱者伺服器執行 pg_dump 指令。

    pg_dump -h SERVER_IP_ADDRESS -U postgres --create --schema-only my_test_db > my_test_db.schema-only.sql
  3. 將備份檔匯入訂閱端 AlloyDB Omni 伺服器的訂閱端資料庫:

    Docker

    docker exec -i CONTAINER_NAME psql -h localhost -U postgres < my_test_db.schema-only.sql

    Podman

    podman exec -i CONTAINER_NAME psql -h localhost -U postgres < my_test_db.schema-only.sql

請忽略 alloydbsuperuser not existing 等錯誤。這個角色專為 PostgreSQL 適用的 AlloyDB 而設。

這項操作會建立資料庫和結構定義,但不包含任何資料列資料。pglogical 擴充功能會複製資料列。手動複製或重新建立任何其他必要的使用者或角色。

在 AlloyDB Omni 訂閱者資料庫上建立節點和訂閱項目

  1. 在 AlloyDB Omni 訂閱端資料庫上建立節點:

    Docker

    docker exec CONTAINER_NAME psql -h localhost -U postgres -d my_test_db -c "
    SELECT pglogical.create_node(node_name := 'subscriber', dsn := 'host=localhost port=5432 dbname=my_test_db user=pglogical_replication');"

    Podman

    podman exec CONTAINER_NAME psql -h localhost -U postgres -d my_test_db -c "
    SELECT pglogical.create_node(node_name := 'subscriber', dsn := 'host=localhost port=5432 dbname=my_test_db user=pglogical_replication');"
  2. 在訂閱者資料庫中建立訂閱項目,指向 AlloyDB for PostgreSQL 提供者資料庫的主要執行個體。

    Docker

    docker exec CONTAINER_NAME psql -h localhost -U postgres -d my_test_db -c "
    SELECT pglogical.create_subscription(subscription_name := 'test_sub_1', provider_dsn := 'host=SERVER_IP_ADDRESS port=5432 dbname=my_test_db user=pglogical_replication password=secret');"

    Podman

    podman exec CONTAINER_NAME psql -h localhost -U postgres -d my_test_db -c "
    SELECT pglogical.create_subscription(subscription_name := 'test_sub_1', provider_dsn := 'host=SERVER_IP_ADDRESS port=5432 dbname=my_test_db user=pglogical_replication password=secret');"
  3. 視資料表大小和要複製的資料而定,複製時間可能從幾秒到幾分鐘不等,之後初始資料應該就會從供應商複製到訂閱者:

    Docker

    docker exec CONTAINER_NAME psql -h localhost -U postgres -d my_test_db -c "
    SELECT * FROM test_table_1 ORDER BY 1;"

    Podman

    podman exec CONTAINER_NAME psql -h localhost -U postgres -d my_test_db -c "
    SELECT * FROM test_table_1 ORDER BY 1;"

    新增至供應商資料庫的額外資料列也會在幾秒內複製。

其他 pglogical 部署注意事項

pglogical 擴充功能提供許多進階功能,本文件未涵蓋這些功能。其中許多功能都適用於您的實作項目。您可以考慮使用下列進階功能:

  • 解決衝突
  • 多主機和雙向複製
  • 納入序列
  • 切換和容錯移轉程序

後續步驟