為什麼 AWS DMS 任務中的來源篩選條件無法正常運作?

上次更新日期:2022 年 7 月 29 日

我已在 AWS Database Migration Service (AWS DMS) 任務上設定原始碼篩選條件,但無法正常運作。如何疑難排解 AWS DMS 任務上的來源篩選條件問題?

簡短描述

AWS DMS 任務上的來源篩選條件可能無法如預期般運作的原因有多種。例如,您使用的引擎可能不支援使用來源篩選條件。或者,您可能會受到一個或多個功能限制的影響。

解決方案

檢查您的引擎是否支援來源篩選功能

雖然大多數 AWS DMS 來源都支援來源篩選,但是某些來源 (例如 MongoDB 或 Amazon DocumentDB) 不支援此功能。查看有關資料遷移來源的 AWS DMS 文件,以確認您使用的來源引擎是否存在此類限制。

檢閱 AWS DMS 來源篩選限制

有幾個與來源篩選相關聯的限制。檢閱這些限制以確認您是否正確使用此功能:

  • 篩選條件不會計算由右至左語言的資料欄。
  • 篩選條件無法套用至大型物件 (LOB) 資料欄。
  • 篩選條件只能套用至建立後未更新的不可變資料欄。如果您將來源篩選條件套用至可在建立之後更新的可變資料欄,則來源篩選條件可能無法如預期般運作。

疑難排解在完全負載期間停止運作的篩選條件

如果問題仍然存在,請檢查來源篩選在哪個階段停止運作。

如果篩選在完全負載期間無法運作,請依照下列步驟執行:

1.    確認映射規則中的任何區分大小寫規則都符合來源引擎。例如,依據預設,在 Oracle 和 DB2 中的物件名稱為大寫字母。同樣地,PostgreSQL 中的物件名稱是小寫字母。請確定您在篩選條件中使用的資料欄符合來源引擎所需的任何區分大小寫規則。

2.    使用日期資料類型進行篩選時,請檢查您使用的是 AWS DMS 所需的格式。例如,AWS DMS 使用日期格式 YYYY-MM-DD 和時間格式 YYYY-MM-DD HH:MM:SS 進行篩選。

3.    使用 SOURCE_UNLOAD 上的偵錯日誌記錄層級重現問題。然後,擷取 AWS DMS 在來源上執行的查詢以卸載資料。這是來源 Oracle 資料表上篩選問題的範例。

資料表詳細資訊:

CREATE TABLE DMS.FILTERS
( ID NUMBER(10) NOT NULL,
  ENTRY_DATE DATE,
  CONSTRAINT FILTERS_PK PRIMARY KEY (ID)
);

SQL> SELECT * FROM FILTERS;
  ID       ENTRY_DATE
---------- ---------
         1 01-JAN-22
         2 01-JUN-22
         3 01-JAN-21
         4 01-JUN-21
         5 01-JAN-20
         6 01-JUN-20

使用映射規則建立 AWS DMS 任務,以僅複寫 ENTRY_DATE 大於或等於 2022 年 1 月 1 日的資料列:

{
  "rules": [
    {
      "rule-type": "selection",
      "rule-id": "893662253",
      "rule-name": "893662253",
      "object-locator": {
        "schema-name": "DMS",
        "table-name": "FILTERS"
      },
      "rule-action": "include",
      "filters": [
        {
          "filter-type": "source",
          "column-name": "ENTRY_DATE",
          "filter-conditions": [
            {
              "filter-operator": "gte",
              "value": "01/01/2022"
            }
          ]
        }
      ]
    }
  ]
}

因此,不會複寫任何記錄,且任務記錄會顯示下列錯誤:

01786264: 2022-06-22T10:36:53 [SOURCE_UNLOAD   ]E:  ORA-01843: not a valid month  [1020417]  (oracle_endpoint_unload.c:171)

由於 SOURCE_UNLOAD 的偵錯日誌已開啟,因此任務日誌會顯示 AWS DMS 在來源資料庫上執行的確切查詢:

1786264: 2022-06-22T10:36:53 [SOURCE_UNLOAD   ]D:  Select statement for UNLOAD is 'SELECT "ID","ENTRY_DATE"  FROM "DMS"."FILTERS" WHERE ((("ENTRY_DATE" >= TO_DATE('0000-00-00','YYYY-MM-DD'))))'  (oracle_endpoint_utils.c:1979)

在日誌輸出中,您可以看到 AWS DMS 在來源資料庫上執行此查詢:

SELECT "ID","ENTRY_DATE"  FROM "DMS"."FILTERS" WHERE ((("ENTRY_DATE" >= TO_DATE('0000-00-00','YYYY-MM-DD'))));

AWS DMS 無法辨識映射規則中提供的日期,因為它與 AWS DMS 預期的日期格式不符。因此,請修改映射規則以匹配預期的日期格式:

{
                            "filter-operator": "gte",
                            "value": "2022-01-01"
                        }

疑難排解 CDC 期間停止運作的篩選條件

注意:只將篩選條件套用至建立後未更新的不可變資料欄。在可變更的資料欄上新增篩選條件可能會導致非預期的結果。

如果您在篩選中使用的資料欄是不可變的資料欄,則可能會注意到篩選問題只會在 CDC 階段發生。此外,這些問題可能只會發生在特定的 DML 陳述式中,例如 UPDATES 或 DELETES。在此場景中,請確定您已在來源資料表上啟用足夠的日誌記錄。請依照下列步驟配置其他日誌記錄,視您使用的引擎而定:

Oracle

Oracle 使用補充日誌記錄在資料表的資料欄上新增其他日誌。如果您要篩選的資料欄不是主索引鍵資料欄,請確定已針對該資料欄和主索引鍵資料欄啟動補充日誌記錄。

此範例會使用主索引鍵 ID 和資料欄 NAME 上的篩選條件,複寫名為 TEST.LOGGING 的資料表。執行類似下列的命令來建立日誌群組補充日誌記錄:

ALTER TABLE TEST.LOGGING ADD SUPPLEMENTAL LOG GROUP TEST_LOG_GROUP (ID, NAME) ALWAYS;

如果資料表中的所有資料欄都已新增補充日誌記錄 (例如本範例),則您不需要新增其他日誌記錄。

ALTER TABLE TableName ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;

PostgreSQL

PostgreSQL 會使用 REPLICA IDENTITY 屬性來設定資料表的日誌記錄層級。當 REPLICA IDENTITY 設定為預設值時,則 PostgreSQL 記錄在 WAL 日誌中的主索引鍵資料欄的舊值。但是,當您在篩選中使用非主索引鍵資料欄時,預設記錄層級可能不足以應對 DELETES。在此場景中,請根據 AWS DMS 任務所使用的外掛程式執行下列步驟:如果使用 test_decoding:

在資料表上將 REPLICA IDENTITY 設定為「完全」。如果未完成此步驟,則 AWS DMS 可能會將所有刪除內容傳送到目標資料表:

ALTER TABLE tablename REPLICA IDENTITY FULL;

如果使用 pglogical:

將資料表新增至複寫集合後,將 REPLICA IDENTITY 設定為「完全」。這是因為 pglogical 存在的限制會在 REPLICA IDENTITY 為「完全」時阻止將資料表新增至複寫集合。

ALTER TABLE tablename REPLICA IDENTITY FULL;

備註:在資料表上將 REPLICA IDENTITY 設定為「完全」會增加在來源資料庫上產生的 WAL 日誌數目。發生這種情況是因為所有資料欄都在 WAL 中記錄。

SQL Server

如果您使用 SQL Server,請檢查是否符合所有 AWS DMS CDC 先決條件,特別是下列日誌記錄要求:

  • 對於每個具有主索引鍵的資料表,執行此查詢以開啟 MS-CDC:

    備註:如果內部部署來源已使用 MS 複寫,請略過此步驟。此步驟對於雲端來源是必要的。

exec sys.sp_cdc_enable_table
@source_schema = N'schema_name',
@source_name = N'table_name',
@role_name = NULL,
@supports_net_changes = 1
GO
  • 執行此查詢以針對每個具有唯一索引鍵但沒有主索引鍵的資料表開啟 MS-CDC。

    備註:內部部署和雲端來源都需要此步驟。

  • exec sys.sp_cdc_enable_table
    @source_schema = N'schema_name',
    @source_name = N'table_name',
    @index_name = N'unique_index_name',
    @role_name = NULL,
    @supports_net_changes = 1
    GO
  • 執行此查詢以針對沒有主要或唯一金鑰的每個資料表開啟 MS-CDC。

    備註:內部部署和雲端來源都需要此步驟。

  • exec sys.sp_cdc_enable_table
    @source_schema = N'schema_name',
    @source_name = N'table_name',
    @role_name = NULL
    GO

    MySQL

    在 MySQL 中,binlog 中的資料列映像是由 binlog_row_image 系統變數控制的。AWS DMS 要求將 binlog_row_image 設定為完全,並將 binlog_format 設定為 ROW。這意味著 MySQL 記錄前映像和後映像中的所有資料欄。因此,請確保 binlog_row_image 在來源資料庫上設定為「完全」,以確認 binlog 中的最大日誌記錄層級。