HANDLECOLLISIONS | NOHANDLECOLLISIONS
有效對象
Replicat
說明
在目標上套用 SQL 時,請使用 HANDLECOLLISIONS 和 NOHANDLECOLLISIONS 參數來控制 Replicat 是否嘗試解決重複記錄和遺漏記錄錯誤。在 Oracle GoldenGate 正在複製對這些表格所做的交易變更時,在初始載入來源表的資料載入目標表時,會發生這些錯誤,稱為衝突。當 Oracle GoldenGate 在載入完成後套用複製的變更時,HANDLECOLLISIONS 會為這些衝突提供含有錯誤處理邏輯的 Replicat。
您可以使用 HANDLECOLLISIONS 和 NOHANDLECOLLISIONS,方法如下:
-
您可以在參數檔的根層次指定
HANDLECOLLISIONS和NOHANDLECOLLISIONS,以全域方式啟用它們。參數檔中所有後續的MAP敘述句都會啟用一個參數,直到遇到 opposing 參數為止。 -
您可以在特定的
MAP參數內啟用HANDLECOLLISIONS或NOHANDLECOLLISIONS,以啟用或停用該來源 - 目標對應的錯誤處理。
前述方法可以合併。您可以指定全域衝突處理規則,然後在 MAP 敘述句中以不同的衝突處理規則覆寫該規則。MAP 規格一律會覆寫全域規格。
注意:整合式 Replicat 的錯誤處理不適用於 HANDLECOLLISIONS。Oracle 建議您使用精確的建立方法,而不是使用 HANDLECOLLISIONS。
HowHANDLECOLLISIONSWorks
下列範例說明 HANDLECOLLISIONS 的運作方式:
-
當 Replicat 遇到 Oracle GoldenGate 作為索引鍵使用之資料欄的更新時,處理方式如下:
-
如果目標中找不到具有舊關鍵碼的資料列,則系統會將追蹤中的變更記錄轉換成插入。
-
如果目標中存在具有新索引鍵的資料列,Replicat 會刪除具有舊索引鍵的資料列 (如果更新已順利執行,就不會存在),然後以新索引鍵更新資料列作為重疊,其中歷程檔值會取代目前值。
此邏輯要求預設或強制將表格中的所有資料欄 (不只是變更的資料欄) 記錄至交易日誌,例如針對 Oracle 資料庫使用
ADD TRANDATA的COLS選項。請參閱避免遺漏資料欄值的可能解決方案。 -
-
Replicat 發生重複記錄錯誤時,歷程檔中的變更記錄會覆寫初始載入所套用的靜態記錄。相較於忽略重複記錄錯誤,從作業角度來看,此變更更安全。
-
含有
HANDLECOLLISIONS的 Replicat 不會捨棄歷程檔中的變更記錄,即使更新或刪除作業不會影響來源中的索引鍵資料欄,且 Replicat 在目標中發生遺漏記錄錯誤。在來源系統上變更記錄,然後在起始載入處理程序擷取表格資料之前刪除記錄,就會發生這些錯誤。舉例而言:
-
應用程式會更新來源 table1 中的記錄 A。
-
擷取會擷取更新。
-
應用程式會刪除來源 table1 中的記錄 A。
-
擷取會擷取刪除。
-
Oracle GoldenGate 會從來源 table1 擷取起始載入資料,但不擷取記錄 A。
-
Oracle GoldenGate 會套用初始載入 (不含記錄 A)。
-
Replicat 嘗試套用記錄 A 的更新。
-
資料庫傳回「遺漏記錄」錯誤。
-
Replicat 會嘗試套用刪除記錄 A。
-
資料庫傳回「遺漏記錄」錯誤。
在初始載入期間擷取的交易變更套用至目標表格之後,停用 HANDLECOLLISIONS,讓 Replicat 不會自動處理後續的錯誤。初始同步化後產生的錯誤表示異常情況,應由可決定解決方式的人員評估。例如,遺漏記錄錯誤可能表示來源系統上存在的記錄不慎從目標系統中刪除。
您可以透過下列方式關閉 HANDLECOLLISIONS:
-
停止 Replicat 並將
HANDLECOLLISIONS自 Replicat 參數檔移除 (可能會導致目標延遲)。或者,您可以編輯參數檔,在要停用錯誤處理的MAP敘述句之前新增NOHANDLECOLLISIONS。 -
Replicat 執行時,請執行 GGSCI,然後對要影響的表格使用
SEND REPLICAT命令搭配NOHANDLECOLLISIONS選項。注意:如果使用
SEND REPLICAT,請確定要將HANDLECOLLISIONS自參數檔中移除,或在啟動另一個 Replicat 執行之前新增NOHANDLECOLLISIONS參數,如此HANDLECOLLISIONS就不會再次啟用。
避免遺漏資料欄值的可能解決方式
當資料庫預設不會記錄來源表格的所有資料欄值時,如果目標表格在 Replicat 嘗試將主要索引鍵更新轉換成插入時有 NOT NULL 限制條件,就會發生錯誤。您可以透過下列方式解決此情況:
-
HANDLECOLLISIONS要求表格在目標表格上有 NOTNULL主索引鍵或 NOTNULL唯一限制條件。 -
使用 Extract 參數檔中的
NOCOMPRESSUPDATES參數,將表格的所有資料欄傳送至歷程檔,並設定資料庫以記錄所有資料欄值。依照預設,「擷取」只會寫入主索引鍵和變更至歷程檔的資料欄。這是最安全的方法,因為它會在執行作業時寫入目前的值,而且不需要擷取。 -
使用
FETCHOPTIONS參數搭配 Extract 參數檔中的FETCHPKUPDATECOLS選項。此組態會導致 Extract 在來源上更新索引鍵資料欄時擷取無法使用的資料欄。擷取是目前的值,不一定是特定更新時的值,因此可能會發生資料完整性問題。請參閱"[FETCHOPTIONS](fetchoptions.html#GUID-DB7BCF87-E3E8-48CF-868A-A56F6D0B6A07)",瞭解處理失敗擷取的詳細資訊和其他擷取選項。
如果資料庫預設包含所有資料欄,則 HANDLECOLLISIONS 必須使用 NOCOMPRESSUPDATES 和 NOCOMPRESSDELETES 才能正常運作。如果資料庫不支援 NOCOMPRESSDELETES,您必須使用 FETCHOPTIONS MISSINGCOLS。
如需有關 Oracle GoldenGate 起始載入方法的詳細資訊,請參閱關於使用起始載入擷取建立。
預設
NOHANDLECOLLISIONS
語法
HANDLECOLLISIONS | NOHANDLECOLLISIONS [_ALLOWPKMISSINGROWCOLLISIONS]
[THREADS (<threadID>[, <threadID>][, ...][, <thread_range>[, <thread_range>][, ...])]
HANDLECOLLISIONS
啟用碰撞處理。
_ALLOWPKMISSINGROWCOLLISIONS
如果對應的目標資料列不存在,請使用 HANDLECOLLISIONS 搭配 _ALLOWPKMISSINGROWCOLLISIONS 來略過主索引鍵 UPDATE 作業。
注意:略過作業可能會導致資料損毀。請參閱本主題中的「說明」。
NOHANDLECOLLISIONS
關閉碰撞處理。
THREADS (<threadID>[, <threadID>][, ...][, <thread_range>[, <thread_range>][, ...])
對指定的執行緒啟用 HANDLECOLLISIONS。在參數檔根層次的全域 HANDLECOLLISIONS 敘述句中使用時,指定繫線的 HANDLECOLLISIONS 都會啟用,無論這些繫線在哪個 MAP 敘述句中。在 MAP 陳述式的 HANDLECOLLISIONS 子句中使用時,只有該 MAP 陳述式會啟用 HANDLECOLLISIONS。
threadID[, threadID][, …]
指定繫線 ID 或以逗號分隔的繫線清單,格式為 threadID, threadID, threadID。
thread_range[, thread_range][, …]
以 threadIDlow-threadIDhigh 格式或以逗號分隔的範圍清單 (格式為 threadIDlow-threadIDhigh,threadIDlow-threadIDhigh) 來指定繫線範圍。
可以結合這些格式,例如 threadID、threadID、threadIDlow-threadIDhigh。
範例
範例 1
此範例會為參數檔中的所有 MAP 敘述句啟用 HANDLECOLLISIONS。
HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
MAP hr.dep, TARGET hr.dep;
MAP hr.country, TARGET hr.country;
範例 2
此範例會在部分 MAP 敘述句啟用 HANDLECOLLISIONS,同時停用其他敘述句。
HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
NOHANDLECOLLISIONS
MAP hr.dep, TARGET hr.dep;
MAP hr.country, TARGET hr.country;
範例 3
此範例顯示 MAP 陳述式內 HANDLECOLLISIONS 的基本用法。
MAP dbo.tcust, TARGET dbo.tcust, HANDLECOLLISIONS;
範例 4
此範例顯示全域使用和 MAP 層級的組合。MAP 規格會覆寫指定表格的全域規格。
HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
MAP hr.dep, TARGET hr.dep, NOHANDLECOLLISIONS;
MAP hr.country, TARGET hr.country, NOHANDLECOLLISIONS;
範例 5
在下列範例中,所有 MAP 陳述式都會全域啟用 HANDLECOLLISIONS,除了第一個 MAP 陳述式中的預設執行緒 0 與第二個 MAP 陳述式中的執行緒 3 之外。
HANDLECOLLISIONS
MAP fin.*, TARGET fin.*;
MAP sales.*, TARGET sales.*;
MAP orders.*, TARGET orders.*;
MAP scott.cust, TARGET scott.cust, NOHANDLECOLLISIONS;
MAP amy.cust, TARGET amy.cust, THREAD(3), NOHANDLECOLLISIONS;
範例 6
在此範例中,已全域啟用 HANDLECOLLISIONS,但已針對執行緒 3 關閉。其餘的執行緒 1、2 與 4 將處理衝突。
HANDLECOLLISIONS
NOHANDLECOLLISIONS THREAD(3)
MAP scott.emplyees, TARGET scott.employees, THREADRANGE(1,4, OID);
MAP scott.inventory, TARGET scott.inventory, THREADRANGE(1,4, OID);
MAP scott.cust, TARGET scott.cust, THREADRANGE(1,4, OID);
範例 7
在此範例中,已全域啟用 HANDLECOLLISIONS,然後全域停用執行緒 5 到 7 的執行緒。在第一個 map 敘述句中,所有繫線都會處理衝突,因為 HANDLECOLLISIONS 參數未指定繫線或範圍。在第二個 map 敘述句中,只有執行緒 4、8 與 9 會處理衝突,因為全域 NOHANDLECOLLISIONS 會套用至執行緒 5-7。
HANDLECOLLISIONS
NOHANDLECOLLISIONS THREADRANGE(5-7)
MAP scott.cust, TARGET scott.cust, THREADRANGE(4,9,OID), HANDLECOLLISIONS;
MAP scott.offices, TARGET scott.offices, THREADRANGE(4,9,OID);
MAP scott.emp, TARGET scott.emp, THREADRANGE(4,9,OID);
MAP scott.ord, TARGET scott.ord, THREADRANGE(4,9,OID);
MAP acct.*, TARGET acct.*;
MAP admin.*, TARGET admin.*;