從 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_timeoutidle_in_transaction_session_timeout 參數,避免長時間執行的交易。詳情請參閱 PostgreSQL 說明文件

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

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

主動管理複製運算單元

Datastream 會在 PostgreSQL 主要執行個體上使用邏輯複製運算單元,確保 WAL 檔案會保留到 Datastream 確認已處理完畢為止。如果資料流失敗、暫停或刪除,但未捨棄複製運算單元,PostgreSQL 會無限期保留 WAL 檔案。這可能會填滿資料庫伺服器磁碟,導致正式版服務中斷。

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

正確設定副本身分

REPLICA IDENTITY 設定會告知 PostgreSQL 要將哪些資料寫入 WAL,以供 UPDATEDELETE 事件使用,讓 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 個資料表。
  • 如果資料表超過 5 億列,除非符合下列條件,否則無法回填資料:
    1. 資料表具有唯一的 B 樹狀結構索引。
    2. 索引不包含下列類型的資料欄:DOUBLEFLOATMONEYREALJSONJSONBBYTEATXIDXML複合資料類型幾何資料類型
    3. 索引的任何資料欄都不得為可為空值。
    4. 索引的所有資料欄都依遞增順序排列,或索引的所有資料欄都依遞減順序排列。
    5. 串流中包含索引的所有資料欄。
  • 沒有主鍵的資料表必須有 REPLICA IDENTITY,否則只有 INSERT 事件會複製到目的地。
  • 如果資料表有主鍵,REPLICA IDENTITY 就不能設為 FULLNOTHING。必須設為 DEFAULT
  • 系統無法自動偵測來源結構定義的所有變更,因此可能會發生資料損毀情形。下列結構定義變更可能會導致資料損毀,或無法處理下游事件:
    • 捨棄資料欄。
    • 在表格中間新增資料欄。
    • 變更資料欄的資料類型。
    • 重新排序資料欄。
    • 捨棄資料表 (如果之後會重新建立資料表並新增資料,這項操作就非常重要)。
  • Datastream 不支援 geometric 資料類型的資料欄。
  • Datastream 不支援 range 資料類型的資料欄。
  • 資料串流不支援不支援的資料類型陣列、使用者定義的資料類型陣列 (包括 ENUM),或 DATETIMESTAMPTIMESTAMP WITH TIME ZONE 資料類型陣列。系統會忽略這類資料欄。
  • 2026 年 2 月 17 日前建立的串流:如果資料列在屬於資料表副本 ID 的資料欄中包含 TOAST 值,Datastream 就不支援複製該資料列的 UPDATE 事件。系統會捨棄這類事件。該日期之後建立的串流不適用這項例外狀況。
  • 如果資料列包含超過 2950 個巢狀物件的 JSONJSONB 值,Datastream 就不支援複製這類資料列。如果事件包含這類 JSONJSONB 值,系統就不會將事件複製到目的地資料庫。
  • Datastream 不支援複製在 NUMERIC (precision, scale) 資料欄中包含 NaN 值的資料列。這類資料欄中的值會替換為 NULL 值。
  • Datastream 不支援複製 hstore 資料類型的資料欄,這類資料欄中的值會替換為 NULL 值。
  • Datastream 不支援從 SQL_ASCII 編碼的來源資料庫複製非 ASCII 記錄,這類記錄會遭到捨棄。
  • Datastream 不支援複製定義資料列層級安全防護機制 (RLS) 政策的資料表。如要瞭解如何規避這項限制,請參閱「PostgreSQL 來源行為和限制」。
  • Datastream 不會擷取對產生的資料欄所做的變更。
  • 在資料庫上執行 PostgreSQL 主要版本升級時,Datastream 可能會停止運作或無法擷取任何新事件。建議您先捨棄複製運算單元,再升級資料庫,然後重新建立複製運算單元。如果串流失敗,請指定新的複製運算單元名稱來復原串流,並在需要資料一致性時執行回填。
  • 使用自動串流設定流程時,Datastream 不支援複製 PostgreSQL 系統資料表。如果您編輯透過自動流程建立的串流並新增系統資料表,Datastream 會自動忽略這些資料表,且不會複製其中的任何資料或變更。

後續步驟