手動衝突偵測與解決方法

瞭解如何使用特定參數手動設定「衝突偵測與解決 (CDR)」。主動 - 主動組態需要衝突偵測和解決,Oracle GoldenGate 必須在多個包含相同資料集的資料庫之間維持資料同步。

Oracle GoldenGate CDR 功能簡介

Oracle GoldenGate 衝突偵測與解決 (CDR) 有兩個部分:衝突偵測與解決衝突。開始解決衝突之前,請務必先調查並完成偵測衝突。

Oracle GoldenGate 衝突偵測與解決 (CDR) 提供下列基本衝突解決常式:

若要使用衝突偵測與解決 (CDR),目標資料庫必須位於 Windows、Linux 或 UNIX 系統上。NonStop 平台上的資料庫不支援此功能。

CDR 支援純量資料類型,例如:

這表示這些資料欄類型可以與 COMPARECOLS 參數搭配使用,以及作為 RESOLVECONFLICT 參數之 USEMIN 和 USEMAX 選項中的解析資料欄。RESOLVECONFLICT 的 USEDELTA 選項只能使用 NUMERIC 資料欄。對於 USEMAX、USEMIN,僅支援 TIMESTAMP 和 NUMBER。

當 Replicat 以 BATCHSQL 模式運作時,不會執行衝突解決。如果 BATCHSQL 模式發生衝突,Replicat 會回復為 GROUPTRANSOPS 模式,然後回復為單一交易模式。這三種模式都有衝突偵測。

設定 Oracle GoldenGate 參數檔以解決衝突

需要下列參數,才能支援衝突偵測和解決。

  1. 使用 Replicat 參數檔中 MAP 參數的 COMPARECOLS 選項,指定要在 Replicat WHERE 子句中與之前值搭配使用的資料欄。之前的值會與目標資料庫中目前的值進行比較,以偵測更新和刪除衝突。(依預設,Replicat 只會使用 WHERE 子句中的主索引鍵;這可能不足以偵測衝突)。

  2. 使用 MAP 參數的 RESOLVECONFLICT 選項,為不同的作業和衝突類型指定衝突解決常式。您可以在 MAP 敘述句中多次使用 RESOLVECONFLICT,為不同的衝突類型指定不同的解析。不過,您無法在相同類型的衝突中多次使用 RESOLVECONFLICT。在所有資料庫上使用相同的衝突解決程序,這樣相同的衝突就會產生相同的最終結果。一個衝突解決方法可能無法針對可能發生的每個衝突運作。您可能需要建立數個能夠以邏輯優先順序呼叫的常式,以便將失敗風險降至最低。

備註:當資料表具有主索引鍵和其他唯一索引或唯一索引鍵時,應考慮其他事項。COMPARECOLS 和 RESOLVECONFLICT 參數隨附的自動化常式需要一致的方式來唯一識別每個資料列。若無法一致地識別資料列,衝突解決期間將會發生錯誤。在這些情況下,應停用其他唯一索引鍵,或者您可以使用 SQLEXEC 功能來處理發生的錯誤並解決衝突。

如需這些參數的詳細資訊,請參閱Oracle GoldenGate 的參數與函數參照。請參閱 CDR 範例 1:所有與 USEMAX、OVERWRITE、DISCARD 衝突類型的範例,瞭解這些參數的詳細資訊。

將必要資料欄值設為可供擷取

若要使用 CDR,必須記錄下列資料欄值,讓 Extract 能夠將它們寫入歷程檔。

如需有關這些參數和命令的詳細資訊,請參閱 Oracle GoldenGate 的參數和函數參照。請參閱 CDR 範例 1:所有衝突類型與 USEMAX、OVERWRITE、DISCARD 上的範例,瞭解這些參數如何與 CDR 搭配運作的詳細資訊。

檢視 CDR 統計資料

CDR 功能提供下列檢視衝突解決結果的方法。

以下是您可以用來檢視 CDR 統計資料的不同技術。

報告檔

Replicat 會將 CDR 統計資料寫入報表檔案:

Total CDR conflicts        7
    CDR resolutions succeeded       6
    CDR resolutions failed          1
    CDR INSERTROWEXISTS conflicts   1
    CDR UPDATEROWEXISTS conflicts   4
    CDR UPDATEROWMISSING conflicts
    CDR DELETEROWEXISTS conflicts      1
    CDR DELETEROWMISSING conflicts     1

命令行

您可以使用 STATS REPLICAT 命令搭配 REPORTCDR 選項,從命令行檢視 CDR 統計資料:

STATS REPLICAT *group*, REPORTCDR

資料欄轉換函數

您可以擷取下列 CDR 統計資料並將其對應至異常狀況表格,或用於接受資料欄轉換函數輸入的其他 Oracle GoldenGate 參數 (視情況而定)。

若要擷取這些統計資料,請使用 @GETENV column-conversion 函數搭配 STATS 或 DELTASTATS 資訊類型。結果是以目前的 Replicat 階段作業為基礎。如果 Replicat 停止並重新啟動,就會重設統計資料。

您可以針對特定表格或一組萬用字元表格傳回這些統計資料:

@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_CONFLICTS')
@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_RESOLUTIONS_SUCCEEDED')
@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_RESOLUTIONS_FAILED')

您可以針對 Replicat 參數檔中所有 MAP 敘述句中的所有表格傳回這些統計資料:

@GETENV ('STATS','CDR_CONFLICTS')
@GETENV ('STATS','CDR_RESOLUTIONS_SUCCEEDED')
@GETENV ('STATS','CDR_RESOLUTIONS_FAILED')

上述範例中的 'STATS' 資訊類型可以由 'DELTASTATS' 取代,以傳回自上次執行 'DELTASTATS' 之後所要求的計數。如需有關 @GETENV 的詳細資訊,請參閱 @GETENV

CDR 範例 1:USEMAX、OVERWRITE、DISCARD 的所有衝突類型

此範例使用 USEMAX、OVERWRITE 和 DISCARD 解析來解析所有衝突類型。

用於此範例的表格

這些範例假設有相同的 Oracle 資料庫。

CREATE TABLE hr.emp_tgt(
    name varchar2(30) primary key,
    phone varchar2(10),
    address varchar2(100),
    salary number,
    balance number,
    comment varchar2(100),
    last_mod_time timestamp);

在來源資料庫中,會補充記錄所有資料欄:

ADD TRANDATA hr.emp_src, COLS (name, phone, address, salary, balance, comment, last_mod_time);

含衝突解決方式規格的 MAP 陳述式

MAP fin.src, TARGET fin.tgt,
    COMPARECOLS (ON UPDATE ALL, ON DELETE ALL),
    RESOLVECONFLICT (UPDATEROWEXISTS, (DEFAULT, USEMAX (last_mod_time)),
    RESOLVECONFLICT (INSERTROWEXISTS, (DEFAULT, USEMAX (last_mod_time)),
    RESOLVECONFLICT (DELETEROWEXISTS, (DEFAULT, OVERWRITE)),
    RESOLVECONFLICT (UPDATEROWMISSING, (DEFAULT, OVERWRITE)),
    RESOLVECONFLICT (DELETEROWMISSING, (DEFAULT, DISCARD)),
    );

MAP 對帳單描述

以下說明 MAP 陳述式:

INSERTROWEXISTS 與 USEMAX 解析度

在此範例中,USEMAX 解析會以記錄在歷程檔和資料庫中的前後影像來說明。它顯示如何解析插入,其中列存在於來源與目標中,但部分或所有列值不同。

表 10 INSERTROWEXISTS 與 USEMAX 解決衝突

影像 SQL 附註
歷程檔中的影像之前
None (row was inserted on the source).
無
尾端影像之後
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00'

last_mod_time='9/1/10 3:00 是解析資料欄的後方影像。由於有一個後視圖,這將用於確定解析度。

目標資料庫映像檔
name='Mary' phone='111111' address='Ralston' salary=200 balance=500 comment='aaa' last_mod_time='9/1/10 1:00'
last_mod_time='9/1/10 1:00 是目標中與歷程檔中解析資料欄值進行比較之解析資料欄的目前影像。
Replicat 所套用的起始 INSERT,可偵測衝突

SQL 連結變數︰

1)'Mary' 2)'1234567890' 3)'Oracle Pkwy' 4)100 5)100 6)NULL 7)'9/1/10 3:00'
此 SQL 傳回 'Mary' 的唯一性衝突。
Replicat 套用 UPDATE 以解決衝突

SQL 連結變數︰

1)'1234567890' 2)'Oracle Pkwy' 3)100 4)100 5)NULL 6)'9/1/10 3:00' 7)'Mary' 8)'9/1/10 3:00'
由於為 INSERTROWEXISTS 指定了 USEMAX,Replicat 會將插入轉換成更新,並且會將歷程檔記錄中的 last_mod_time 值與資料庫中的值做比較。記錄中的值較大,因此歷程檔中資料欄的後續影像會套用至目標。

使用 USEMAX 解析的 UPDATEROWEXISTS

在此範例中,USEMAX 解析會以記錄在歷程檔和資料庫中的前後影像來說明。它顯示如何解析來源與目標中資料列存在但部分或所有資料列值不同之處的更新。

表 11 UPDATEROWEXISTS 與 USEMAX 解決衝突

影像 SQL 附註
歷程檔中的影像之前
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00'
last_mod_time='9/1/10 3:00 是解析資料欄的前一個影像。
尾端影像之後
phone='222222' address='Holly' last_mod_time='9/1/10 5:00'
last_mod_time='9/1/10 5:00 是解析資料欄的後方影像。由於有一個後視圖,這將用於確定解析度。
目標資料庫映像檔
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=600 comment='com' last_mod_time='9/1/10 6:00'
last_mod_time='9/1/10 6:00 是目標中與歷程檔中解析資料欄值進行比較之解析資料欄的目前影像。
Replicat 所套用的起始 UPDATE,可偵測衝突

SQL 連結變數︰

1)'222222' 2)'Holly' 3)'9/1/10 5:00' 4)'Mary' 5)'1234567890' 6)'Oracle Pkwy' 7)100 8)100 9)NULL 10)'9/1/10 3:00'

此 SQL 會傳回無資料發現錯誤,因為目標中的 balance、comment 和 last_mod_time 值不同。

COMPARECOLS 敘述句設為 ALL,因此所有資料欄都會用於 WHERE 子句中。

Replicat 套用 UPDATE 以解決衝突

SQL 連結變數︰

1)'Mary' 2)'222222' 3)'Holly' 4)100 5)100 6)NULL 7)'9/1/10 5:00' 8)'Mary' 9)'9/1/10 5:00'
因為歷程檔記錄中 last_mod_time 的後續值小於資料庫中目前的值,所以會保留資料庫值。Replicat 會以包含主索引鍵加上設為小於 9/1/10 5:00 之 last_mod_time 值的 WHERE 子句套用作業。沒有符合此條件的資料列,因此陳述式會因「找不到資料」錯誤而失敗,但 Replicat 會忽略錯誤,因為如果不符合條件,USEMAX 解析預期會失敗。

以 OVERWRITE 解析度更新

在此範例中,OVERWRITE 解析會以記錄在歷程檔和資料庫中的前後影像來說明。其中顯示如何解決遺漏目標資料列的情況。邏輯解析與使用的邏輯解析是覆寫目標中的資料列,讓兩個資料庫再次同步。

表 12 更新與 OVERWRITE 解析度發生衝突

影像 SQL 附註
歷程檔中的影像之前
name='Jane' phone='333' address='Oracle Pkwy' salary=200 balance=200 comment=NULL last_mod_time='9/1/10 7:00'
無
尾端影像之後
phone='4444' address='Holly' last_mod_time='9/1/10 8:00'
 
目標資料庫映像檔
None (row for Jane is missing)
 
Replicat 所套用的起始 UPDATE,可偵測衝突

SQL 連結變數︰

1)'4444' 2)'Holly' 3)'9/1/10 8:00' 4)'Jane' 5)'333' 6)'Oracle Pkwy' 7)200 8)200 9)NULL 10)'9/1/10 7:00'
此 SQL 會傳回未找到資料的錯誤。COMPARECOLS 敘述句設為 ALL,因此所有資料欄都會用於 WHERE 子句中。
Replicat 套用 INSERT 以解決衝突

SQL 連結變數︰

1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00'
更新會轉換成插入,因為 OVERWRITE 為解析。如果可用,則會使用資料欄的後圖像;否則會使用前圖像。

具有 OVERWRITE 解析的 DELETEROWEXISTS

在此範例中,OVERWRITE 解析會以記錄在歷程檔和資料庫中的前後影像來說明。它顯示如何解決來源列已刪除但目標列存在的情況。在此情況下,OVERWRITE 解析會將刪除套用至目標。

表格 13 DELETEROWEXISTS 與 OVERWRITE 解決方法衝突

影像 SQL 附註
歷程檔中的影像之前
name='Mary' phone='222222' address='Holly' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 5:00'
無
尾端影像之後
None
無
目標資料庫映像檔
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=600 comment=com last_mod_time='9/1/10 7:00'
資料列存在於目標上,但 phone、address、balance、comment 和 last_mod_time 資料欄與歷程檔中的前一個影像不同。
Replicat 所套用的起始 DELETE,可偵測衝突

SQL 連結變數︰

1)'Mary' 2)'222222' 3)'Holly' 4)100 5)100d 6)NULL 7)'9/1/10 5:00'

COMPARECOLS 敘述句設為 ALL,因此所有資料欄都會用於 WHERE 子句中。

因為先前值與目前值之間的差異,所以不會發現資料錯誤。

Replicat 套用 DELETE 以解決衝突

SQL 連結變數︰

1)'Mary'
因為 OVERWRITE 是解析度。DELETE 只會使用主索引鍵套用 (以避免發生完整性錯誤)。

DELETEROWMISSING 搭配 DISCARD 解析度

在此範例中,DISCARD 解析會以記錄在歷程檔和資料庫中的前後影像來說明。其中顯示如何解決遺漏目標資料列的情況。如果是在來源上刪除,則目標資料列不存在 (仍需要刪除),因此解決方式是捨棄歷程檔中的 DELETE 作業。

表 14 DELETEROWMSING 與 DISCARD 解決衝突

影像 SQL 附註
歷程檔中的影像之前
name='Jane' phone='4444' address='Holly' salary=200 balance=200 comment=NULL last_mod_time='9/1/10 8:00'
無
尾端影像之後
None
無
目標資料庫映像檔
None (row missing)
無
Replicat 所套用的起始 DELETE,可偵測衝突

SQL 連結變數︰

1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00'
此 SQL 會傳回未找到資料的錯誤。COMPARECOLS 敘述句設為 ALL,因此所有資料欄都會用於 WHERE 子句中。
Replicat 套用以解決衝突的 SQL
None
由於 DISCARD 指定為 DELETEROWMISSING 的解析,因此從歷程檔刪除會移至捨棄檔案。

CDR 範例 2:使用 USEDELTA 和 USEMAX 的 UPDATEROWEXISTS

此範例會解析 UPDATE 上有目標資料列但非索引鍵資料欄不同的條件,並且使用兩種不同的解析類型來根據受影響的資料欄處理此條件。

用於此範例的表格

這些範例假設有相同的 Oracle 資料庫。

CREATE TABLE tgt(
    name varchar2(30) primary key,
    phone varchar2(10),
    address varchar2(100),
    salary number,
    balance number,
    comment varchar2(100),
    last_mod_time timestamp);

在來源資料庫中,會補充記錄所有資料欄:

ADD TRANDATA scott.src, COLS (name, phone, address, salary, balance, comment, last_mod_time);

MAP 對帳單

MAP fin.src, TARGET fin.tgt,
    COMPARECOLS
    (ON UPDATE KEYINCLUDING (address, phone, salary, last_mod_time),
    ON DELETE KEYINCLUDING (address, phone, salary, last_mod_time)),
    RESOLVECONFLICT (
    UPDATEROWEXISTS,
    (delta_res_method, USEDELTA, COLS (salary)),
    (DEFAULT, USEMAX (last_mod_time)));

MAP 對帳單描述

若為 UPDATEROWEXISTS 衝突,其中目標資料列存在於 UPDATE,但非索引鍵資料欄不同,請根據資料欄使用兩種不同的解析:

根據 COMPARECOLS,使用主索引鍵 (name column) 加上 address、phone、salary 和 last_mod_time 資料欄作為 UPDATE 和 DELETE 作業之衝突偵測的比較資料欄。(不會比較 balance 和 comment 資料欄。)

注意:除了 USEMAX 之外,您也可以使用 USEMAXEQ 解析來套用 >= 條件。如需詳細資訊,請參閱Oracle GoldenGate 的參數與函數參照。

錯誤處理

如需處理異常狀況表格的錯誤範例,請參閱設定 Oracle GoldenGate 參數檔以進行錯誤處理。

表 15 UPDATEROWEXISTS with USEDELTA and USEMAX

影像 SQL 附註
歷程檔中的影像之前
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00'

last_mod_time='9/1/10 3:00 是 USEMAX 解析之解析資料欄的前一個影像。

salary=100 是 USEDELTA 解析的先前影像。

尾端影像之後
phone='222222' address='Holly' salary=200 comment='new' last_mod_time='9/1/10 5:00'
last_mod_time='9/1/10 5:00 是 USEMAX 解析資料欄的後方影像。由於有一個後視圖,這將用於確定解析度。
目標資料庫映像檔
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=600 balance=600 comment='com' last_mod_time='9/1/10 4:00'

last_mod_time='9/1/10 4:00 是目標中與歷程檔中解析資料欄值進行比較之解析資料欄的目前影像。

salary=600 是 USEDELTA 解析之目標資料欄的目前影像。

Replicat 所套用的起始 UPDATE,可偵測衝突

SQL 連結變數︰

1)'222222' 2)'Holly' 3)200 4)'new' 5)'9/1/10 5:00' 6)'Mary' 7)'1234567890' 8)'Oracle Pkwy' 9)100 10)'9/1/10 3:00'
此 SQL 會傳回無資料找到的錯誤,因為 salary 和 last_mod_time 的值不同。(comment 和 balance 的值也不同,但不會比較這些資料欄。)
Replicat 套用的 UPDATE 可使用 USEDELTA 解決 salary 的衝突。

SQL 連結變數︰

1)200 2)100 3)'Mary'

根據 USEDELTA,歷程檔中 salary (200) 的後續影像與歷程檔中 salary (100) 的先前影像之間的差異會加到目標中 salary 的目前值 (600)。結果為 700。

600 + (200 - 100) = 700
Replicat 套用的 UPDATE,使用 USEMAX 解決預設資料欄的衝突。

SQL 連結變數︰

1)'222222' 2)'Holly' 3)'new' 4)'9/1/10 5:00' 5)'Mary' 6)'9/1/10 5:00'

根據 USEMAX,因為歷程檔記錄中 last_mod_time 的後續值大於資料庫中的目前值,所以會以歷程檔記錄中的後續值更新資料列。

請注意,此處未設定 salary 資料欄,因為該資料欄是以 USEDELTA 解析的 UPDATE 來解析。

CDR 範例 3:使用 USEDELTA、USEMAX 和 IGNORE 的 UPDATEROWEXISTS

此範例會解決 UPDATE 上有目標資料列但非索引鍵資料欄不同之處的衝突,並且使用三種不同的解決類型來根據受影響的資料欄處理此條件。

用於此範例的表格

這些範例假設有相同的 Oracle 資料庫。

CREATE TABLE tgt(
    name varchar2(30) primary key,
    phone varchar2(10),
    address varchar2(100),
    salary number,
    balance number,
    comment varchar2(100),
    last_mod_time timestamp);

在來源資料庫中,會補充記錄所有資料欄:

ADD TRANDATA scott.src, COLS (name, phone, address, salary, balance, comment, last_mod_time);

MAP 對帳單

MAP fin.src, TARGET fin.tgt,
    COMPARECOLS
    (ON UPDATE ALLEXCLUDING (comment)),
    RESOLVECONFLICT (
    UPDATEROWEXISTS,
    (delta_res_method, USEDELTA, COLS (salary, balance)),
    (max_res_method, USEMAX (last_mod_time), COLS (address, last_mod_time)),
    (DEFAULT, IGNORE));

MAP 對帳單描述

錯誤處理

如需處理異常狀況表格的錯誤範例,請參閱設定 Oracle GoldenGate 參數檔以進行錯誤處理。

表 16 UPDATEROWEXISTS with USEDELTA,USEMAX,IGNORE

影像 SQL 附註
歷程檔中的影像之前
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00

last_mod_time='9/1/10 3:00 是 USEMAX 解析之解析資料欄的前一個影像。

salary=100 和 balance=100 是 USEDELTA 解析之前的影像。

尾端影像之後
phone='222222' address='Holly' salary=200 comment='new' last_mod_time='9/1/10 5:00'

last_mod_time='9/1/10 5:00 是 USEMAX 解析資料欄的後方影像。由於有一個後視圖,這將用於確定解析度。

salary=200 是 USEDELTA 解析唯一可用的影像之後。對於 balance,計算中將使用前面的影像。

目標資料庫映像檔
name='Mary' phone='1234567890' address='Ralston' salary=600 balance=600 comment='com' last_mod_time='9/1/10 4:00'

last_mod_time='9/1/10 4:00 是目標中解析資料欄的目前影像,其中歷程檔中的解析資料欄值會與 USEMAX 進行比較。

salary=600 和 balance=600 是 USEDELTA 目標資料欄的目前影像。

Replicat 所套用的起始 UPDATE,可偵測衝突

SQL 連結變數︰

1)'222222' 2)'Holly' 3)200 4)'new' 5)'9/1/10 5:00' 6)'Mary' 7)'1234567890' 8)'Oracle Pkwy' 9)100 10)100 11)'9/1/10 3:00'
此 SQL 會傳回無資料找到的錯誤,因為 address、salary、balance 及 last_mod_time 資料欄的值不同。
Replicat 套用的 UPDATE 可使用 USEDELTA 解決 salary 的衝突。

SQL 連結變數︰

1)200 2)100 3)'Mary'
對於 salary,有 100 的差異,但 balance 的值沒有變更,因此更新 SQL 中不需要變更。根據 USEDELTA,歷程檔中 salary 的後 (200) 影像和前 (100) 影像之間的差異 (差異) 會加到目標中 salary 的目前值 (600)。結果為 700。
Replicat 套用 UPDATE,以解決 USEMAX 的衝突。

SQL 連結變數︰

1)'Holly' 2)'9/1/10 5:00' 3)'Mary' 4)'9/1/10 5:00'

由於歷程檔記錄中的 last_mod_time 後面值大於資料庫中的目前值,因此該資料欄加上 address 資料欄會以歷程檔記錄中的後面值更新。

請注意,此處未設定 salary 資料欄,因為該資料欄是以 USEDELTA 解析的 UPDATE 來解析。

IGNORE 的 Replicat 已套用 UPDATE。

SQL 連結變數︰

1)'222222' 2)'new' 3)'Mary'
為 DEFAULT 資料欄群組 (phone 和 comment) 指定 IGNORE,因此不會套用解析 SQL。

設定 Oracle GoldenGate 參數檔以進行錯誤處理

手動 CDR 應與錯誤處理一起使用,以擷取已解決且無法解決 CDR 的錯誤。

  1. 在下列其他錯誤處理參數之前,會先執行衝突解決:HANDLECOLLSIONS、INSERTMISSINGUPDATES 和 REPERROR。使用 REPERROR 參數來指派規則,以處理無法由 CDR 解決的錯誤,或您不想透過 CDR 處理的錯誤。可能適合讓 REPERROR 處理一些錯誤,而 CDR 處理其他錯誤;但是,如果將 REPERROR 和 CDR 設定為處理相同的衝突,則優先採用 CDR。INSERTMISSINGUPDATES 和 HANDLECOLLISIONS 參數也可用來處理一些 CDR 未處理的錯誤。請參閱Oracle GoldenGate 的參數和函數參照,瞭解這些參數的詳細資訊。

  2. (選用) 建立例外情況表。當例外表格與 MAP 統計資料一起使用時,Replicat 會將產生衝突 (已解決或未解決) 的每個作業傳送至要對應至例外表格的例外 MAP 陳述式。如果 Replicat 要處理 UPDATE 和 DELETE 衝突,請省略此表格上的主索引鍵;否則可能會發生完整性限制條件錯誤。

    異常狀況表格至少應該包含與目標表格相同的資料欄。這些資料列將包含 Replicat 套用至目標 (或嘗試套用) 的每個資料列影像。

    此外,您可以定義其他資料欄來擷取有助於將資料置於交易相關資訊環境的其他資訊。Oracle GoldenGate 提供了透過例外 MAP 敘述句擷取此資訊的工具。這類資料欄可以是 (但不限於) 下列項目:

    • 軌跡記錄的先前影像。這是一組重複的目標資料欄,名稱如 col1 _before、col2 _before 等。

    • 目標資料欄的目前值。這也是一組重複的目標資料欄,名稱如 col1 _current、col2 _current 等。

    • 目標表格的名稱

    • 衝突的時戳

    • 作業類型

    • 資料庫錯誤編號

    • (選擇性) 資料庫錯誤訊息

    • 是否已解決衝突

  3. 建立例外 MAP 陳述式,以將例外資料對應至例外表格。例外 MAP 陳述式包含:

    • (必要) INSERTALLRECORDS 選項。此參數會將所有對應的作業轉換成 INSERT,以便將所有資料欄值對應至異常狀況表格。

    • (必要) EXCEPTIONSONLY 選項。此參數會導致 Replicat 對應產生錯誤的作業,但不會對應成功的作業。

    • (選擇性) COLMAP 子句。如果異常狀況表格中資料欄的名稱和定義與來源表格的名稱和定義相同,而且異常狀況表格只包含那些資料欄,則不需要 COLMAP。不過,如果有任何名稱或定義不同,或您想以其他資料填入的異常狀況表格中有額外的資料欄,請使用 COLMAP 子句來對應所有資料欄。

將額外資料對應至例外表格的工具

下列是您可以在 COLMAP 子句中用來填入額外資料欄的一些工具:

請參閱範例例外對應與例外表格中的其他資料欄,瞭解如何在例外 MAP 陳述式中的 COLMAP 子句中結合這些功能,以植入詳細的例外表格。

請參閱Oracle GoldenGate 的參數和函數參照,瞭解這些範例中顯示的參數和資料欄轉換函數的用法和語法。

僅含來源與目標資料欄的範例例外對應

以下為範例參數檔,其中顯示開始 CDR 範例中所使用之來源和目標表格的錯誤處理和簡單例外對應。此範例會對應來源和目標資料欄,但沒有額外的資料欄。基於下列原因,此範例中的 MAP 陳述式例外不需要 COLMAP 子句:

    -- REPERROR error handling: DEFAULT represents all error types. DISCARD

    -- writes operations that could not be processed to a discard file.
REPERROR (DEFAULT, DISCARD)

    -- Specifies a discard file.
DISCARDFILE /users/ogg/discards/discards.dsc, PURGE

    -- The regular MAP statement with the CDR parameters
MAP fin.src, TARGET fin.tgt, &
COMPARECOLS (ON UPDATE ALL, ON DELETE ALL), &
RESOLVECONFLICT (UPDATEROWEXISTS, (DEFAULT, USEMAX (last_mod_time)), &
RESOLVECONFLICT (INSERTROWEXISTS, (DEFAULT, USEMAX (last_mod_time)), &
RESOLVECONFLICT (DELETEROWEXISTS, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (UPDATEROWMISSING, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (DELETEROWMISSING, (DEFAULT, DISCARD)), &
);

    -- Starts the exceptions MAP statement by mapping the source table to the

    -- exceptions table.
MAP fin.src, TARGET fin.exception, &

    -- directs Replicat only to map operations that caused the error specified

    -- in REPERROR.
EXCEPTIONSONLY, &

    -- directs Replicat to convert all the exceptions to inserts into the

    -- exceptions table. This is why there cannot be a primary key constraint

    -- on the exceptions table.
INSERTALLRECORDS
;

含有例外表格中其他資料欄的範例例外對應

以下為範例參數檔,其中顯示 CDR 範例中使用的來源和目標表格的錯誤處理和複雜例外對應。在此範例中,例外表格的資料列與來源表格的資料列相同,但也有其他資料欄可擷取相關資訊環境資料。

注意:此範例會故意離開 Replicat 參數檔中需要的其他參數 (例如處理作業名稱和登入證明資料),以及指定之資料庫類型可能需要的任何選擇性參數。使用分行符號將參數陳述式分割成多行時,請在每一行的結尾使用 & 符號。

    -- REPERROR error handling: DEFAULT represents all error types. DISCARD
    -- writes operations that could not be processed to a discard file.
REPERROR (DEFAULT, DISCARD)
    -- Specifies the discard file.
DISCARDFILE /users/ogg/discards/discards.dsc, PURGE
    -- The regular MAP statement with the CDR parameters
MAP fin.src, TARGET fin.tgt, &
COMPARECOLS (ON UPDATE ALL, ON DELETE ALL), &
RESOLVECONFLICT (UPDATEROWEXISTS, (DEFAULT, USEMAX (last_mod_time))), &
RESOLVECONFLICT (INSERTROWEXISTS, (DEFAULT, USEMAX (last_mod_time)), &
RESOLVECONFLICT (DELETEROWEXISTS, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (UPDATEROWMISSING, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (DELETEROWMISSING, (DEFAULT, DISCARD))
);
    -- Starts the exceptions MAP statement by mapping the source table to the -- exceptions table.
MAP fin.src, TARGET fin.exception, &
    -- directs Replicat only to map operations that caused the error specified
    -- in REPERROR.
EXCEPTIONSONLY, &
    -- directs Replicat to convert all the exceptions to inserts into the
    -- exceptions table. This is why there cannot be a primary key constraint
    -- on the exceptions table.
INSERTALLRECORDS &
    -- SQLEXEC query to select the values from the target record before the
    -- Replicat statement is applied. These are mapped to the *_target
    -- columns later.
SQLEXEC (id qry, query 'select name, phone, address, salary, balance, & comment, last_mod_time from fin.tgt where name = :p1', PARAMS(p1 = name )), &
    -- Start of the column mapping, specifies use default column definitions.
COLMAP ( &
    -- USEDEFAULTS maps the source columns to the target exceptions columns
    -- that receive the after image that Replicat applied or tried to apply.
    -- In this case, USEDEFAULTS can be used because the names and definitions
    -- of the source and target exceptions columns are identical; otherwise
    -- the columns must be mapped explicitly in the COLMAP clause.
USEDEFAULTS, &
    -- captures the timestamp when the resolution was performed.
res_date = @DATENOW (), &
    -- captures and maps the DML operation type.
optype = @GETENV ('LASTERR', 'OPTYPE'), &
    -- captures and maps the database error number that was returned.
dberrnum = @GETENV ('LASTERR', 'DBERRNUM'), &
    -- captures and maps the database error that was returned.
dberrmsge = @GETENV ('LASTERR', 'DBERRMSG'), &
    -- captures and maps the name of the target table
tabname = @GETENV ('GGHEADER', 'TABLENAME'), &
    -- If the names and definitions of the source columns and the target
    -- exceptions columns were not identical, the columns would need to
    -- be mapped in the COLMAP clause instead of using USEDEFAULTS, as
    -- follows:
       -- name_after = name, &
       -- phone_after = phone, &
       -- address_after = address, &
       -- salary_after = salary, &
       -- balance_after = balance, &
       -- comment_after = comment, &
       -- last_mod_time_after = last_mod_time &
    -- maps the before image of each column from the trail to a column in the
    -- exceptions table.
name_before = @BEFORE (name), &
phone_before = @BEFORE (phone), &
address_before = @BEFORE (address), &
salary_before = @BEFORE (salary), &
balance_before = @BEFORE (balance), &
comment_before = @BEFORE (comment), &
last_mod_time_before = @BEFORE (last_mod_time), &
    -- maps the results of the SQLEXEC query to rows in the exceptions table
    -- to show the current image of the row in the target.
name_current = qry.name, &
phone_current = qry.phone, &
address_current = qry.address, &
salary_current = qry.salary, &
balance_current = qry.balance, &
comment_current = qry.comment, &
last_mod_time_current = qry.last_mod_time)
;

一旦您確信常式在所有狀況下都能如預期般運作,您就可以減少記錄到例外表格的資料量,以減少解決常式的負荷。