使用 pglogical 跨執行個體同步資料 - Amazon Aurora

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 pglogical 跨執行個體同步資料

所有目前可用的 Aurora PostgreSQL 版本都支援 pglogical 延伸模組。pglogical 延伸模組早於 PostgreSQL 在第 10 版中引入的功能,其類似於邏輯複寫功能。如需詳細資訊,請參閱以 Aurora 使用 PostgreSQL 邏輯複寫

pglogical 延伸模組支援在兩個或以上 Aurora PostgreSQL 資料庫叢集之間進行邏輯複寫。它也支援在不同的 PostgreSQL 版本之間,以及在 RDS for PostgreSQL 資料庫執行個體和 Aurora PostgreSQL 資料庫叢集上執行的資料庫之間進行複寫。pglogical 延伸模組會使用發佈-訂閱模型,將資料表和其他物件 (例如序列) 的變更從發佈者複製到訂閱者。它依賴複寫槽,以確保變更從發佈者節點同步到訂閱者節點,其定義如下。

  • 發佈者節點Aurora PostgreSQL 資料庫叢集,其是要複寫到其他節點的資料來源。發佈者節點定義要在發佈集中複製的資料表。

  • 訂閱者節點Aurora PostgreSQL 資料庫叢集,其會從發佈者接收 WAL 更新。訂閱者會建立訂閱以連線至發佈者,並取得解碼的 WAL 資料。訂閱者建立訂閱時,系統會在發佈者節點上建立複寫槽。

您可以在以下內容中找到如何設定 pglogical 延伸模組的相關資訊。

pglogical 延伸模組的需求和限制

所有目前可用的 Aurora PostgreSQL 版本都支援 pglogical 延伸模組。

發佈者節點和訂閱者節點都必須針對邏輯複寫進行設定。

您想要從訂閱者複寫到發佈者的資料表必須具有相同的名稱和相同的結構描述。這些資料表亦須包含相同的資料欄,而且這些資料欄必須使用相同的資料類型。發佈者和訂閱者資料表都必須具有相同的主索引鍵。建議您僅使用 PRIMARY KEY 作為唯一限制條件。

對於 CHECK 限制條件和 NOT NULL 限制條件,訂閱者節點上的資料表與發佈者節點上的資料表相比之下,可以具有更寬鬆的限制條件。

pglogical 延伸模組會提供 PostgreSQL (第 10 版及更新版本) 內建邏輯複寫功能不支援的功能,例如雙向複寫。如需詳細資訊,請參閱使用 pglogical 進行 PostgreSQL 雙向複寫

設定 pglogical 延伸模組

若要在 Aurora PostgreSQL 資料庫叢集上設定 pglogical 延伸模組,請將 pglogical 新增至下列群組上的共用程式庫:RDS for PostgreSQL 資料庫執行個體的自訂資料庫參數群組。Aurora PostgreSQL 資料庫叢集的自訂資料庫叢集參數群組。您亦需將 rds.logical_replication 參數的值設為 1,以開啟邏輯解碼。最後,您可以在資料庫中建立延伸模組。您可以針對這些任務使用 AWS Management Console 或 AWS CLI。

您必須具有做為 rds_superuser 角色的許可,才能執行這些任務。

以下步驟假設您的 Aurora PostgreSQL 資料庫叢集與自訂資料庫叢集參數群組相關聯。如需建立自訂資料庫參數群組的相關資訊,請參閱 使用參數群組

設定 pglogical 延伸模組
  1. 登入 AWS Management Console,並開啟 Amazon RDS 主控台,網址為 https://console.aws.amazon.com/rds/

  2. 在導覽窗格中,選擇您的 Aurora PostgreSQL 資料庫叢集的寫入器執行個體

  3. 針對您的 Aurora PostgreSQL 資料庫叢集的寫入器執行個體開啟 Configuration (組態) 索引標籤。在執行個體詳細資訊之間,尋找 Parameter group (參數群組) 連結。

  4. 選擇連結以開啟與 Aurora PostgreSQL 資料庫叢集相關聯的自訂參數。

  5. Parameters (參數) 搜尋欄位中,輸入 shared_pre 以尋找 shared_preload_libraries 參數。

  6. 選擇 Edit parameters (編輯參數) 以存取屬性值。

  7. Values (值) 欄位中,將 pglogical 新增至清單。使用逗號區隔值清單中的項目。

    已新增 pglogical 之 shared_preload_libraries 參數的影像。
  8. 尋找 rds.logical_replication 參數並將其設為 1,以開啟邏輯複寫。

  9. 重新啟動 Aurora PostgreSQL 資料庫叢集的寫入器執行個體,讓您的變更生效。

  10. 當執行個體可用時,您可以使用 psql (或 pgAdmin) 連線至 Aurora PostgreSQL 資料庫叢集的寫入器執行個體。

    psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
  11. 若要驗證 pglogical 是否已初始化,請執行下列命令。

    SHOW shared_preload_libraries; shared_preload_libraries -------------------------- rdsutils,pglogical (1 row)
  12. 驗證啟用邏輯解碼的設定,如下所示。

    SHOW wal_level; wal_level ----------- logical (1 row)
  13. 建立延伸模組,如下所示。

    CREATE EXTENSION pglogical; EXTENSION CREATED
  14. 選擇儲存變更

  15. 前往 https://console.aws.amazon.com/rds/,開啟 Amazon RDS 主控台。

  16. 從資料庫清單中選擇 Aurora PostgreSQL 資料庫叢集的寫入器執行個體以選取它,然後從 Actions (動作) 功能表中選擇 Reboot (重新啟動)。

設定 pglogical 延伸模組

若要使用設定 pglogicalAWS CLI,請呼叫modify-db-parameter-group作業來修改自訂參數群組中的某些參數,如下列程序所示。

  1. 使用下列 AWS CLI 命令,將 pglogical 新增至 shared_preload_libraries 參數。

    aws rds modify-db-parameter-group \ --db-parameter-group-name custom-param-group-name \ --parameters "ParameterName=shared_preload_libraries,ParameterValue=pglogical,ApplyMethod=pending-reboot" \ --region aws-region
  2. 使用下列 AWS CLI 命令將 rds.logical_replication 設為 1,以開啟 Aurora PostgreSQL 資料庫叢集之寫入器執行個體的邏輯解碼功能。

    aws rds modify-db-parameter-group \ --db-parameter-group-name custom-param-group-name \ --parameters "ParameterName=rds.logical_replication,ParameterValue=1,ApplyMethod=pending-reboot" \ --region aws-region
  3. 使用下列 AWS CLI 命令重新啟動 Aurora PostgreSQL 資料庫叢集的寫入器執行個體,以便初始化 pglogical 程式庫。

    aws rds reboot-db-instance \ --db-instance-identifier writer-instance \ --region aws-region
  4. 當執行個體可用時,請使用 psql 連線至 Aurora PostgreSQL 資料庫叢集的寫入器執行個體。

    psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
  5. 建立延伸模組,如下所示。

    CREATE EXTENSION pglogical; EXTENSION CREATED
  6. 使用下列 AWS CLI 命令,重新啟動 Aurora PostgreSQL 資料庫叢集的寫入器執行個體

    aws rds reboot-db-instance \ --db-instance-identifier writer-instance \ --region aws-region

針對 Aurora PostgreSQL 資料庫叢集設定邏輯複寫

下列程序說明如何在兩個 Aurora PostgreSQL 資料庫叢集之間啟動邏輯複寫。這些步驟假設來源 (發佈者) 和目標 (訂閱者) 都已設定 pglogical 延伸模組,如 設定 pglogical 延伸模組 中所述。

建立發佈者節點並定義要複製的資料表

這些步驟假設您的 Aurora PostgreSQL 資料庫叢集具有一個內含資料庫的寫入器執行個體,其中包含一或多個您要複寫到另一個節點的資料表。您必須在訂閱者上重新建立來自發佈者的資料表結構,因此必要時先取得資料表結構。您可以使用 psq1 中繼命令 \d tablename,然後在訂閱者執行個體上建立相同的資料表,以執行該操作。下列程序會在發佈者 (來源) 上建立範例資料表,以供示範之用。

  1. 使用 psql 連線至具有資料表的執行個體,您想要將該資料表用作訂閱者的來源。

    psql --host=source-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb

    如果您沒有要複寫的現有資料表,則可以建立如下的範例資料表。

    1. 使用下列 SQL 陳述式建立範例資料表。

      CREATE TABLE docs_lab_table (a int PRIMARY KEY);
    2. 使用下列 SQL 陳述式,將產生的資料填入資料表中。

      INSERT INTO docs_lab_table VALUES (generate_series(1,5000)); INSERT 0 5000
    3. 使用下列 SQL 陳述式,驗證資料是否存在於資料表中。

      SELECT count(*) FROM docs_lab_table;
  2. 將此 Aurora PostgreSQL 資料庫叢集識別為發佈者節點,如下所示。

    SELECT pglogical.create_node( node_name := 'docs_lab_provider', dsn := 'host=source-instance.aws-region.rds.amazonaws.com port=5432 dbname=labdb'); create_node ------------- 3410995529 (1 row)
  3. 將您要複寫的資料表新增至預設複寫集。如需複寫集的詳細資訊,請參閱 pglogical 文件中的 Replication sets (複寫集)。

    SELECT pglogical.replication_set_add_table('default', 'docs_lab_table', 'true', NULL, NULL); replication_set_add_table --------------------------- t (1 row)

發佈者節點設定完成。您現在可以設定訂閱者節點,從發佈者接收更新。

設定訂閱者節點並建立訂閱來接收更新

這些步驟假設 Aurora PostgreSQL 資料庫叢集已使用 pglogical 延伸模組進行設定。如需詳細資訊,請參閱設定 pglogical 延伸模組

  1. 使用 psql 來連線至您想要從發佈者接收更新的執行個體。

    psql --host=target-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
  2. 在訂閱者 Aurora PostgreSQL 資料庫叢集上,建立存在於發佈者上的相同資料表。在此範例中,資料表是 docs_lab_table。您可以建立資料表,如下所示。

    CREATE TABLE docs_lab_table (a int PRIMARY KEY);
  3. 驗證此資料表是否為空的。

    SELECT count(*) FROM docs_lab_table; count ------- 0 (1 row)
  4. 將此 Aurora PostgreSQL 資料庫叢集識別為訂閱者節點,如下所示。

    SELECT pglogical.create_node( node_name := 'docs_lab_target', dsn := 'host=target-instance.aws-region.rds.amazonaws.com port=5432 sslmode=require dbname=labdb user=postgres password=********'); create_node ------------- 2182738256 (1 row)
  5. 建立訂閱。

    SELECT pglogical.create_subscription( subscription_name := 'docs_lab_subscription', provider_dsn := 'host=source-instance.aws-region.rds.amazonaws.com port=5432 sslmode=require dbname=labdb user=postgres password=*******', replication_sets := ARRAY['default'], synchronize_data := true, forward_origins := '{}' ); create_subscription --------------------- 1038357190 (1 row)

    完成此步驟時,會在訂閱者上的資料表中建立來自發佈者上資料表的資料。您可以使用下列 SQL 查詢來驗證是否已發生此情況。

    SELECT count(*) FROM docs_lab_table; count ------- 5000 (1 row)

從此開始,對發佈者上資料表所做的變更會複寫到訂閱者上的資料表。

在重大升級之後重新建立邏輯複寫

在對設為邏輯複寫之發佈者節點的 Aurora PostgreSQL 資料庫叢集執行主要版本升級之前,您必須捨棄所有複寫槽,即使是未作用中的複寫槽也一樣。建議您暫時從發佈者節點轉移資料庫交易、捨棄複寫槽、升級 Aurora PostgreSQL 資料庫叢集,然後重新建立並重新啟動複寫。

複寫槽僅託管於發佈者節點上。邏輯複寫案例中的 Aurora PostgreSQL 訂閱者節點沒有要捨棄的複寫槽。Aurora PostgreSQL 主要版本升級程序支援將訂閱者獨立升級至與發佈者節點不同的新主要 PostgreSQL 版本。不過,升級程序確實會中斷複寫程序,並干擾發佈者節點與訂閱者節點之間的 WAL 資料同步。在升級發佈者、訂閱者或兩者之後,您必須重新建立發佈者與訂閱者之間的邏輯複寫。下列程序說明如何判斷複寫是否已中斷,以及如何解決問題。

判斷邏輯複寫是否已中斷

您可以查詢發佈者節點或訂閱者節點,來判斷複寫程序是否已中斷,如下所示。

檢查發佈者節點
  • 使用 psql 連線到發佈者節點,然後查詢 pg_replication_slots 函數。請注意作用中資料欄中的值。通常,這會傳回 t (true),表明複寫作用中。如果查詢傳回 f (false),表示已停止複寫至訂閱者。

    SELECT slot_name,plugin,slot_type,active FROM pg_replication_slots; slot_name | plugin | slot_type | active -------------------------------------------+------------------+-----------+-------- pgl_labdb_docs_labcb4fa94_docs_lab3de412c | pglogical_output | logical | f (1 row)
檢查訂閱者節點

在訂閱者節點上,您可以採取三種不同的方式來檢查複寫的狀態。

  • 查看訂閱者節點上的 PostgreSQL 日誌,以找出失敗訊息。日誌會以包含結束代碼 1 的訊息識別失敗,如下所示。

    2022-07-06 16:17:03 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 14610) exited with exit code 1 2022-07-06 16:19:44 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 21783) exited with exit code 1
  • 查詢 pg_replication_origin 函數。使用 psql 連線至訂閱者節點上的資料庫,然後查詢 pg_replication_origin 函數,如下所示。

    SELECT * FROM pg_replication_origin; roident | roname ---------+-------- (0 rows)

    空白結果集表示複寫已中斷。通常,您會看到如下輸出。

    roident | roname ---------+---------------------------------------------------- 1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c (1 row)
  • 查詢 pglogical.show_subscription_status 函數,如下列範例所示。

    SELECT subscription_name,status,slot_name FROM pglogical.show_subscription_status(); subscription_name | status | slot_name ---====----------------+--------+------------------------------------- docs_lab_subscription | down | pgl_labdb_docs_labcb4fa94_docs_lab3de412c (1 row)

    此輸出表明複寫已中斷。其狀態為 down。通常,輸出會將狀態顯示為 replicating

如果您的邏輯複寫程序已中斷,您可以遵循下列步驟重新建立複寫。

重新建立發佈者與訂閱者節點之間的邏輯複寫

若要重新建立複寫,首先中斷訂閱者與發佈者節點的連線,然後重新建立訂閱,如下列步驟所述。

  1. 使用 psql 連線至訂閱者節點,如下所示。

    psql --host=222222222222.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
  2. 使用 pglogical.alter_subscription_disable 函數停用訂閱。

    SELECT pglogical.alter_subscription_disable('docs_lab_subscription',true); alter_subscription_disable ---------------------------- t (1 row)
  3. 透過查詢 pg_replication_origin 取得發佈者節點的識別符,如下所示。

    SELECT * FROM pg_replication_origin; roident | roname ---------+------------------------------------- 1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c (1 row)
  4. 使用上一個步驟的回應搭配 pg_replication_origin_create 命令,來指派訂閱可在重新建立時使用的識別符。

    SELECT pg_replication_origin_create('pgl_labdb_docs_labcb4fa94_docs_lab3de412c'); pg_replication_origin_create ------------------------------ 1 (1 row)
  5. 透過傳送訂閱的名稱來開啟訂閱,其狀態為 true,如下列範例所示。

    SELECT pglogical.alter_subscription_enable('docs_lab_subscription',true); alter_subscription_enable --------------------------- t (1 row)

檢查節點的狀態。其狀態應為 replicating,如這個範例所示。

SELECT subscription_name,status,slot_name FROM pglogical.show_subscription_status(); subscription_name | status | slot_name -------------------------------+-------------+------------------------------------- docs_lab_subscription | replicating | pgl_labdb_docs_lab98f517b_docs_lab3de412c (1 row)

檢查發佈者節點上訂閱者複寫槽的狀態。複寫槽的 active 資料欄應傳回 t (true),表示已重新建立複寫。

SELECT slot_name,plugin,slot_type,active FROM pg_replication_slots; slot_name | plugin | slot_type | active -------------------------------------------+------------------+-----------+-------- pgl_labdb_docs_lab98f517b_docs_lab3de412c | pglogical_output | logical | t (1 row)

管理 Aurora PostgreSQL 的邏輯複寫槽

在對充當邏輯複寫案例中發佈者節點的 Aurora PostgreSQL 資料庫叢集寫入器執行個體執行主要版本升級之前,您必須捨棄執行個體上的複寫槽。主要版本升級預先檢查程序會通知您,除非捨棄複寫槽,否則升級無法繼續進行。

若要識別已使用 pglogical 延伸模組建立的複寫槽,請登入每個資料庫並取得節點的名稱。查詢訂閱者節點時,您會在輸出中同時取得發佈者和訂閱者節點,如本範例所示。

SELECT * FROM pglogical.node; node_id | node_name ------------+------------------- 2182738256 | docs_lab_target 3410995529 | docs_lab_provider (2 rows)

您可以使用下列查詢,取得有關訂閱的詳細資訊。

SELECT sub_name,sub_slot_name,sub_target FROM pglogical.subscription; sub_name | sub_slot_name | sub_target ----------+--------------------------------+------------ docs_lab_subscription | pgl_labdb_docs_labcb4fa94_docs_lab3de412c | 2182738256 (1 row)

您現在可以捨棄訂閱,如下所示。

SELECT pglogical.drop_subscription(subscription_name := 'docs_lab_subscription'); drop_subscription ------------------- 1 (1 row)

捨棄訂閱之後,您可以刪除節點。

SELECT pglogical.drop_node(node_name := 'docs-lab-subscriber'); drop_node ----------- t (1 row)

您可以驗證節點是否不再存在,如下所示。

SELECT * FROM pglogical.node; node_id | node_name ---------+----------- (0 rows)

pglogical 延伸模組的參數參考

在資料表中,您可以尋找與 pglogical 延伸模組相關聯的參數。pglogical.conflict_log_levelpglogical.conflict_resolution 這類參數用來處理更新衝突。對從發佈者訂閱變更的相同資料表進行本機變更時,可能會出現衝突。在各種案例期間 (例如雙向複寫或從相同發佈者複寫多個訂閱者時),也會發生衝突。如需詳細資訊,請參閱使用 pglogical 進行 PostgreSQL 雙向複寫

參數 描述

pglogical.batch_inserts

可能情況下批次插入。依預設不會設定。變更為 '1' 以開啟、變更為 '0' 以關閉。

pglogical.conflict_log_level

設定用於記錄已解決衝突的日誌層級。支援的字串值為 debug5、debug4、debug3、debug2、debug1、info、notice、warning、error、log、fatal、panic。

pglogical.conflict_resolution

設定用來在衝突可解決時解決衝突的方法。支援的字串值為 error、apply_remote、keep_local、last_update_wins、first_update_wins。

pglogical.extra_connection_options

要新增到所有對等節點連線的連線選項。

pglogical.synchronous_commit

pglogical 特定的同步遞交值

pglogical.use_spi

使用 SPI (伺服器程式設計介面) 而不是低階 API 來套用變更。設為 '1' 以開啟、設為 '0' 以關閉。如需 SPI 的詳細資訊,請參閱 PostgreSQL 文件中的 Server Programming Interface (伺服器程式設計介面)。