從 PostgreSQL 資料庫串流資料

這個部分包含以下資訊:

  • Datastream 處理從來源 PostgreSQL 資料庫擷取資料的方式
  • Datastream 支援的 PostgreSQL 資料庫版本
  • 概略瞭解如何設定來源 PostgreSQL 資料庫,以便將資料從該資料庫串流至目的地
  • 使用 PostgreSQL 資料庫做為來源的已知限制

行為

來源 PostgreSQL 資料庫依賴邏輯解碼功能。邏輯解碼會公開所有已提交至資料庫的變更,並允許使用輸出外掛程式,以易於使用的格式取用及處理這些變更。Datastream 使用 pgoutput 外掛程式,這是 PostgreSQL 10 以上版本的標準 PostgreSQL 邏輯解碼外掛程式。

  • 您可以選取特定 PostgreSQL 來源的所有結構定義或特定結構定義,以及結構定義中的所有資料表或特定資料表。
  • 所有歷來資料都會複製。
  • 系統會複製所有資料操縱語言 (DML) 變更,例如指定資料庫和資料表中的插入、更新和刪除作業。
  • 系統只會複製已提交的變更。
  • 如果您在資料表上定義 REPLICA IDENTITY,Datastream 會將指定的資料欄視為主鍵。
  • 連線至主要執行個體時,Datastream 會定期將活動訊號訊息傳送至來源資料庫。因此,邏輯解碼訊息事件 (op:"m") 會直接插入 WAL 檔案。Datastream 必須收到這些訊息,才能確保來源可用性及計算新舊程度。使用唯讀備用資源做為來源時,您必須在外部設定心跳訊息。詳情請參閱「從唯讀備用資源進行複製」。如果其他複寫設定是從同一個來源資料庫讀取資料,建議您將這點納入考量。

版本

Datastream 支援 PostgreSQL 10 以上版本。

Datastream 支援下列類型的 PostgreSQL 資料庫:

  • 自行託管的 PostgreSQL
  • PostgreSQL 適用的 Cloud SQL
  • AlloyDB for PostgreSQL
  • AlloyDB Omni
  • PostgreSQL 適用的 Amazon RDS
  • Amazon Aurora PostgreSQL

免費方案

您可以使用免費方案,透過 Datastream 將資料從 AlloyDB for PostgreSQL 串流至 BigQuery,每個月最多可免費擷取 100 GiB 的變更資料擷取資料。詳情請參閱 Datastream 定價。

最佳做法

本節說明設定 PostgreSQL 來源以搭配 Datastream 使用時,建議採取的最佳做法。

使用多個串流,避免發生隊頭阻塞問題

如果是 PostgreSQL 來源,Datastream 會為整個串流使用單一邏輯複製運算單元。如果對單一高用量資料表進行大型交易或多次更新,可能會延遲同一資料串中所有其他資料表的資料複製作業。

為避免佇列前端封鎖,請為不同資料表集建立個別的串流。舉例來說,您可以為高容量資料表建立一個串流,為低容量資料表建立另一個串流。這樣可隔離高流失率資料表,避免延遲其他資料表的複製作業。

最佳化建議:找出寫入率極高的資料表 (INSERT/UPDATE/DELETE),並將這些資料表放在專屬的 Datastream 串流中,搭配獨立的複製時段。

避免長時間執行的交易

長時間執行的交易可能會導致 WAL 記錄累積。由於 WAL 是循序的,因此在長時間交易完成前,PostgreSQL 無法移除複製運算單元所需的舊 WAL 檔案。這會增加 WAL 磁碟用量。

此外,這可能會減緩邏輯解碼速度。這是因為大型交易會將變更溢出到磁碟,導致提交時需要耗費大量 I/O 資源重新組裝,進而阻礙後續所有交易的複製作業。建議:在來源資料庫中,設定 statement_timeout 和 idle_in_transaction_session_timeout 參數,避免長時間執行的交易。詳情請參閱 PostgreSQL 說明文件。

建立出版品時使用表格篩選功能

如果只複製少數資料表的變更,請務必建立只包含這些資料表的 PUBLICATION。如果發布作業的範圍僅限特定資料表,PostgreSQL 只會有效保留複製運算單元中這些資料表的變更。這有助於縮減複寫時段的大小,並提升邏輯解碼效能。

主動管理複製運算單元

Datastream 會在 PostgreSQL 主要執行個體上使用邏輯複製運算單元,確保 WAL 檔案會保留到 Datastream 確認已處理完畢為止。如果串流失敗、暫停或刪除,但未捨棄複寫時段,PostgreSQL 會無限期保留 WAL 檔案。這可能會導致資料庫伺服器磁碟空間不足,進而造成生產中斷。

建議:在來源 PostgreSQL 伺服器上設定有效率的警報,並監控 WAL 磁碟用量。

正確設定副本身分

REPLICA IDENTITY 設定會告知 PostgreSQL 要將哪些資料寫入 WAL,以供 UPDATE 和 DELETE 事件使用,讓 Datastream 識別哪些資料列已變更。

如果您使用 BigQuery 做為目的地,請避免將 REPLICA IDENTITY 設為 FULL。Datastream 會將記錄的資料欄做為 BigQuery MERGE 作業的邏輯鍵。如果 REPLICA IDENTITY 設為 FULL,且資料表有超過 16 個資料欄,就會超出 BigQuery 在 MERGE 作業中主鍵的 16 個資料欄限制,導致串流中斷。

建議 (依偏好順序):

  1. 最佳做法:使用主鍵。根據預設,REPLICA IDENTITY DEFAULT 會自動且有效率地使用現有的主鍵。
  2. 良好:如果沒有主鍵,請建立UNIQUE NOT NULL 索引並設定 REPLICA IDENTITY USING INDEX INDEX_NAME。
  3. 最不建議:只在沒有專屬 ID 的表格上使用 REPLICA IDENTITY FULL 設定。如果複製到 BigQuery,請注意對效能的影響、16 欄的限制,以及主鍵支援的資料類型限制。

從唯讀副本進行複製

Datastream 支援從 PostgreSQL 唯讀副本執行個體複製資料,但僅限 PostgreSQL 16 以上版本。

如要從唯讀備用資源複製,請在主要執行個體上執行下列設定步驟:

  1. 在主要執行個體上建立發布內容:Datastream 連線至唯讀備用資源時,必須在主要執行個體上建立發布內容,定義要複製的資料。
  2. 設定 WAL 心跳訊號:Datastream 的檢查點機制會定期傳送 WAL 心跳訊號訊息。連線至主要執行個體時,Datastream 會處理這些心跳訊號的產生作業。不過,如果是唯讀備用資源,這些心跳信號必須從外部產生。

如要設定定期心跳訊號,其中一種方法是在 PostgreSQL 中使用 pg_cron 擴充功能建立 cron 工作:

SELECT cron.schedule_in_database(
    'datastream-heartbeat',             -- Job name
    '* * * * *',                        -- Every minute
   $$SELECT pg_logical_emit_message(true, 'datastream', 'cdc heartbeat')$$,
    'DATABASE_NAME',              -- Change this to your database name
    'USERNAME',                   -- Username to run as
    true                                -- Enabled
);

更改下列內容:

  • DATABASE_NAME:要產生心跳訊號的資料庫名稱。
  • USERNAME:要以哪個使用者的身分執行工作。一般為 postgres。

已知限制

使用 Datastream 時,如果 PostgreSQL 資料庫是來源,則有下列已知限制:

  • 串流最多只能有 10,000 個資料表。
  • PostgreSQL 會嚴格拒絕 UTF-8 字串資料欄中的空值位元組 (0x00)。Datastream 不會移除 NULL 位元組。如果來源字串含有 0x00 空值位元組,插入批次作業就會失敗,並停止複製。 建議您先清除或取代來源資料庫中的 CHAR(0) 字元,再進行複製。
  • 您無法將 PostgreSQL 串流設定為從最新位置開始。
  • 如果資料表超過 5 億列,除非符合下列條件,否則無法回填:
    1. 資料表具有專屬的 B 樹狀結構索引。
    2. 索引不包含下列類型的資料欄:DOUBLE、FLOAT、MONEY、REAL、JSON、JSONB、BYTEA、TXID、XML、複合資料類型或幾何資料類型。
    3. 索引的任何資料欄都不得為可為空值。
    4. 索引的所有資料欄都依遞增順序排列,或索引的所有資料欄都依遞減順序排列。
    5. 串流中包含索引的所有資料欄。
  • 沒有主鍵的資料表必須有 REPLICA IDENTITY。否則,只有 INSERT 事件會複製到目的地。
  • 如果資料表有主鍵,REPLICA IDENTITY 就不能設為 FULL 或 NOTHING。必須設為 DEFAULT。
  • 系統無法自動偵測來源結構定義的所有變更,因此可能會發生資料損毀情形。下列結構定義變更可能會導致資料損毀,或無法處理下游事件:
    • 捨棄資料欄。
    • 在表格中間新增資料欄。
    • 變更資料欄的資料類型。
    • 重新排序資料欄。
    • 捨棄資料表 (如果之後會重新建立資料表並新增資料,這項操作就非常重要)。
  • 資料串流不支援 geometric 資料類型的資料欄,例如 BOX、CIRCLE、LINE、LSEG、PATH、POINT 和 POLYGON。這類資料欄會複製為 NULL。
  • Datastream 不支援 range 資料類型的資料欄。
  • Datastream 不支援不支援的資料類型陣列 (例如空間類型)、LTREE陣列、使用者定義的資料類型陣列 (包括 ENUM) 或 DATE、TIMESTAMP 或 TIMESTAMP WITH TIME ZONE 陣列 (TIMESTAMPTZ)。Datastream 會在複製期間忽略這類資料欄。
  • 2026 年 2 月 17 日前建立的串流:如果資料列在屬於資料表副本 ID 的資料欄中包含 TOAST 值,Datastream 就不支援複製該資料列的 UPDATE 事件。系統會捨棄這類事件。該日期之後建立的串流不適用這項例外狀況。
  • Datastream 不支援複製包含 JSON 或 JSONB 值的資料列,且這些值含有超過 2950 個巢狀物件。含有這類 JSON 或 JSONB 值的事件不會複製到目的地資料庫。
  • Datastream 不支援複製在 NUMERIC (precision, scale) 資料欄中包含 NaN 值的資料列。這類資料欄中的值會替換為 NULL 值。
  • Datastream 不支援複製 hstore 資料類型的資料欄。這類資料欄中的值會替換為 NULL 值。
  • Datastream 不支援從 SQL_ASCII 編碼的來源資料庫複製非 ASCII 記錄。這類記錄會遭到捨棄。
  • Datastream 不支援複製定義了資料列層級安全防護機制 (RLS) 政策的資料表。如要瞭解如何規避這項限制,請參閱「PostgreSQL 來源行為和限制」。
  • 對於使用超大屬性儲存技術 (TOAST) 的可變長度資料類型串流資料欄: 如果 UPDATE 作業期間,未變更的 TOAST 值從 WAL 記錄中捨棄, Datastream 會在來源資料庫中執行主動查詢,嘗試復原遺失的值。 因此,如果涉及快速、連續更新或插入後快速刪除,系統可能不會擷取中間變更。請注意,DELETE 作業不會觸發這項主動查詢作業。 使用 TOAST 的可變長度資料欄有這項限制,在使用僅限附加的寫入模式時特別重要,因為該模式會擷取所有中繼變更。
  • Datastream 不會擷取對產生的資料欄所做的變更。
  • 在資料庫上執行 PostgreSQL 主要版本升級時,Datastream 可能會停止運作或無法擷取任何新事件。建議您先捨棄複寫位置,再升級資料庫,然後重新建立複寫位置。如果串流失敗,請指定新的複製運算單元名稱來復原串流,並視需要執行回填作業,確保資料一致性。
  • 使用自動串流設定流程時,Datastream 不支援複製 PostgreSQL 系統資料表。如果您編輯使用自動流程建立的串流並新增系統資料表,Datastream 會自動忽略這些資料表,且不會複製其中的任何資料或變更。

後續步驟