手動衝突偵測與解決方法
瞭解如何使用特定參數手動設定「衝突偵測與解決 (CDR)」。主動 - 主動組態需要衝突偵測和解決,Oracle GoldenGate 必須在多個包含相同資料集的資料庫之間維持資料同步。
Oracle GoldenGate CDR 功能簡介
Oracle GoldenGate 衝突偵測與解決 (CDR) 有兩個部分:衝突偵測與解決衝突。開始解決衝突之前,請務必先調查並完成偵測衝突。
Oracle GoldenGate 衝突偵測與解決 (CDR) 提供下列基本衝突解決常式:
-
解決
INSERT的唯一性衝突。 -
當資料列存在時,解決
UPDATE的「找不到資料」衝突,但一或多個資料欄的先前影像與資料庫中的目前值不同。 -
當資料列不存在時,解決
UPDATE的「找不到資料」衝突。 -
當資料列存在時,解決
DELETE的「找不到資料」衝突,但一或多個資料欄的先前影像與資料庫中的目前值不同。 -
當資料列不存在時,解決
DELETE的「找不到資料」衝突。
若要使用衝突偵測與解決 (CDR),目標資料庫必須位於 Windows、Linux 或 UNIX 系統上。NonStop 平台上的資料庫不支援此功能。
CDR 支援純量資料類型,例如:
-
NUMERIC -
BOOLEAN -
DATE -
TIMESTAMP -
CHAR/NCHAR -
VARCHAR/ NVARCHAR
這表示這些資料欄類型可以與 COMPARECOLS 參數搭配使用,以及作為 RESOLVECONFLICT 參數之 USEMIN 和 USEMAX 選項中的解析資料欄。RESOLVECONFLICT 的 USEDELTA 選項只能使用 NUMERIC 資料欄。對於 USEMAX、USEMIN,僅支援 TIMESTAMP 和 NUMBER。
當 Replicat 以 BATCHSQL 模式運作時,不會執行衝突解決。如果 BATCHSQL 模式發生衝突,Replicat 會回復為 GROUPTRANSOPS 模式,然後回復為單一交易模式。這三種模式都有衝突偵測。
設定 Oracle GoldenGate 參數檔以解決衝突
需要下列參數,才能支援衝突偵測和解決。
-
使用 Replicat 參數檔中
MAP參數的COMPARECOLS選項,指定要在 ReplicatWHERE子句中與之前值搭配使用的資料欄。之前的值會與目標資料庫中目前的值進行比較,以偵測更新和刪除衝突。(依預設,Replicat 只會使用WHERE子句中的主索引鍵;這可能不足以偵測衝突)。 -
使用
MAP參數的RESOLVECONFLICT選項,為不同的作業和衝突類型指定衝突解決常式。您可以在MAP敘述句中多次使用RESOLVECONFLICT,為不同的衝突類型指定不同的解析。不過,您無法在相同類型的衝突中多次使用RESOLVECONFLICT。在所有資料庫上使用相同的衝突解決程序,這樣相同的衝突就會產生相同的最終結果。一個衝突解決方法可能無法針對可能發生的每個衝突運作。您可能需要建立數個能夠以邏輯優先順序呼叫的常式,以便將失敗風險降至最低。
備註:當資料表具有主索引鍵和其他唯一索引或唯一索引鍵時,應考慮其他事項。COMPARECOLS 和 RESOLVECONFLICT 參數隨附的自動化常式需要一致的方式來唯一識別每個資料列。若無法一致地識別資料列,衝突解決期間將會發生錯誤。在這些情況下,應停用其他唯一索引鍵,或者您可以使用 SQLEXEC 功能來處理發生的錯誤並解決衝突。
如需這些參數的詳細資訊,請參閱Oracle GoldenGate 的參數與函數參照。請參閱 CDR 範例 1:所有與 USEMAX、OVERWRITE、DISCARD 衝突類型的範例,瞭解這些參數的詳細資訊。
將必要資料欄值設為可供擷取
若要使用 CDR,必須記錄下列資料欄值,讓 Extract 能夠將它們寫入歷程檔。
-
每筆記錄的全部前置影像。某些資料庫在日誌記錄中未提供之前的映像檔,必須設定成使用補充日誌記錄。對於大多數支援的資料庫,您可以將
ADD TRANDATA命令用於此用途。 -
使用
LOGALLSUPCOLS參數可確保將排程資料欄之前和之後的完整影像寫入歷程檔。排程資料欄是主索引鍵、唯一索引以及外來索引鍵資料欄。LOGALLSUPCOLS會讓 Extract 在歷程檔記錄中包括UPDATE作業的先前影像,以及UPDATE和DELETE作業之所有補充記錄資料欄的先前影像。
如需有關這些參數和命令的詳細資訊,請參閱 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 參數 (視情況而定)。
-
偵測到 Replicat 的衝突數目
-
Replicat 解析的解析數
-
Replicat 無法解析的解析數
若要擷取這些統計資料,請使用 @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 陳述式:
-
根據
COMPARECOLS,使用 ReplicatWHERE子句中歷程檔記錄之所有資料欄的前置影像進行更新和刪除。 -
根據
DEFAULT,使用所有資料欄作為所有衝突類型的資料欄群組,因此解析會套用至所有資料欄。 -
對於
INSERTROWEXISTS衝突,請使用USEMAX解析:如果資料列在插入期間存在,請使用last_mod_time資料欄作為解析資料欄,以決定哪一個是較大的值:歷程檔中的值或資料庫中的值。如果追蹤中的值大於,請套用記錄,但將插入變更為更新。如果資料庫值較高,則忽略記錄。 -
對於
UPDATEROWEXISTS衝突,請使用USEMAX解決方法:如果更新期間有資料列,請使用last_mod_time資料欄作為解決資料欄:如果歷程檔中的值大於此值,請套用更新。 -
如果您使用
USEMIN或USEMAX,且值完全相同,則不會觸發RESOLVECONFLICT,且會忽略內送資料列。如果您使用USEMINEQ或USEMAXEQ,且值完全相同,則會觸發解析度。 -
對於
DELETEROWEXISTS衝突,請使用OVERWRITE解決方法:如果刪除作業期間有資料列存在,請套用刪除。 -
對於
UPDATEROWMISSING衝突,請使用OVERWRITE解析:如果更新期間沒有該列,請將更新變更為插入並加以套用。 -
對於
DELETROWMISSING衝突,請使用DISCARD解決方法:如果刪除作業期間沒有資料列,請捨棄歷程檔記錄。注意:除了
USEMAX之外,您也可以使用USEMAXEQ解析來套用>=條件。如需詳細資訊,請參閱Oracle GoldenGate 的參數與函數參照。
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' |
|
| 目標資料庫映像檔 | 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 會傳回無資料發現錯誤,因為目標中的
|
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' |
因為先前值與目前值之間的差異,所以不會發現資料錯誤。 |
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,但非索引鍵資料欄不同,請根據資料欄使用兩種不同的解析:
-
根據
delta_res_method解析,使用salary資料欄的USEDELTA解析邏輯,以便將值的變更新增至資料欄的目前值。 -
根據
DEFAULT,使用last_mod_time資料欄作為解析資料欄,使用表格中所有其他資料欄 (預設資料欄群組) 的USEMAX解析邏輯。每當修改資料列時,此資料欄都會以目前的時間更新;歷程檔中此資料欄的值會與目標中的值進行比較。如果歷程檔記錄中的last_mod_time值大於目標資料庫中目前的值last_mod_time,則對name、phone、address、balance、comment和last_mod_time所做的變更會套用至目標。
根據 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 | 附註 |
|---|---|---|
| 歷程檔中的影像之前 | |
|
| 尾端影像之後 | |
last_mod_time='9/1/10 5:00 是 USEMAX 解析資料欄的後方影像。由於有一個後視圖,這將用於確定解析度。 |
| 目標資料庫映像檔 | |
|
Replicat 所套用的起始 UPDATE,可偵測衝突 |
SQL 連結變數︰ |
此 SQL 會傳回無資料找到的錯誤,因為 salary 和 last_mod_time 的值不同。(comment 和 balance 的值也不同,但不會比較這些資料欄。) |
Replicat 套用的 UPDATE 可使用 USEDELTA 解決 salary 的衝突。 |
SQL 連結變數︰ |
根據 |
Replicat 套用的 UPDATE,使用 USEMAX 解決預設資料欄的衝突。 |
SQL 連結變數︰ |
根據 請注意,此處未設定 |
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 對帳單描述
-
若為
UPDATEROWEXISTS衝突,其中目標資料列存在於UPDATE,但非索引鍵資料欄不同,請根據資料欄使用兩種不同的解析:-
根據
delta_res_method解析,使用salary和balance資料欄的USEDELTA解析邏輯,將每個值的變更新增至每個資料欄的目前值。 -
根據
max_res_method解析,使用address和last_mod_time資料欄的USEMAX解析邏輯。last_mod_time資料欄是解析資料欄。每當修改資料列時,此資料欄都會以目前的時間更新;歷程檔中此資料欄的值會與目標中的值進行比較。如果歷程檔記錄中的last_mod_time值大於目標資料庫中目前的last_mod_time值,則對address和last_mod_time所做的變更會套用至目標;否則會忽略這些變更,以利於目標值。 -
對於
DEFAULT,使用表格中其餘資料欄 (phone和comment) 的IGNORE解析邏輯 (預設資料欄群組)。Replicat 一律會忽略對這些資料欄所做的變更。
-
-
根據
COMPARECOLS,使用除comment資料欄以外的所有資料欄作為UPDATE作業衝突偵測的比較資料欄。註解將不會用於WHERE子句中以進行更新,但將會使用歷程檔記錄中具有之前影像的所有其他資料欄。注意:除了USEMAX之外,您也可以使用USEMAXEQ解析來套用>=條件。如需詳細資訊,請參閱Oracle GoldenGate 的參數與函數參照。
錯誤處理
如需處理異常狀況表格的錯誤範例,請參閱設定 Oracle GoldenGate 參數檔以進行錯誤處理。
表 16 UPDATEROWEXISTS with USEDELTA,USEMAX,IGNORE
| 影像 | SQL | 附註 |
|---|---|---|
| 歷程檔中的影像之前 | |
|
| 尾端影像之後 | |
|
| 目標資料庫映像檔 | |
|
Replicat 所套用的起始 UPDATE,可偵測衝突 |
SQL 連結變數︰ |
此 SQL 會傳回無資料找到的錯誤,因為 address、salary、balance 及 last_mod_time 資料欄的值不同。 |
Replicat 套用的 UPDATE 可使用 USEDELTA 解決 salary 的衝突。 |
SQL 連結變數︰ |
對於 salary,有 100 的差異,但 balance 的值沒有變更,因此更新 SQL 中不需要變更。根據 USEDELTA,歷程檔中 salary 的後 (200) 影像和前 (100) 影像之間的差異 (差異) 會加到目標中 salary 的目前值 (600)。結果為 700。 |
Replicat 套用 UPDATE,以解決 USEMAX 的衝突。 |
SQL 連結變數︰ |
由於歷程檔記錄中的 請注意,此處未設定 |
IGNORE 的 Replicat 已套用 UPDATE。 |
SQL 連結變數︰ |
為 DEFAULT 資料欄群組 (phone 和 comment) 指定 IGNORE,因此不會套用解析 SQL。 |
設定 Oracle GoldenGate 參數檔以進行錯誤處理
手動 CDR 應與錯誤處理一起使用,以擷取已解決且無法解決 CDR 的錯誤。
-
在下列其他錯誤處理參數之前,會先執行衝突解決:
HANDLECOLLSIONS、INSERTMISSINGUPDATES和REPERROR。使用REPERROR參數來指派規則,以處理無法由 CDR 解決的錯誤,或您不想透過 CDR 處理的錯誤。可能適合讓REPERROR處理一些錯誤,而 CDR 處理其他錯誤;但是,如果將REPERROR和 CDR 設定為處理相同的衝突,則優先採用 CDR。INSERTMISSINGUPDATES和HANDLECOLLISIONS參數也可用來處理一些 CDR 未處理的錯誤。請參閱Oracle GoldenGate 的參數和函數參照,瞭解這些參數的詳細資訊。 -
(選用) 建立例外情況表。當例外表格與
MAP統計資料一起使用時,Replicat 會將產生衝突 (已解決或未解決) 的每個作業傳送至要對應至例外表格的例外MAP陳述式。如果 Replicat 要處理UPDATE和DELETE衝突,請省略此表格上的主索引鍵;否則可能會發生完整性限制條件錯誤。異常狀況表格至少應該包含與目標表格相同的資料欄。這些資料列將包含 Replicat 套用至目標 (或嘗試套用) 的每個資料列影像。
此外,您可以定義其他資料欄來擷取有助於將資料置於交易相關資訊環境的其他資訊。Oracle GoldenGate 提供了透過例外
MAP敘述句擷取此資訊的工具。這類資料欄可以是 (但不限於) 下列項目:-
軌跡記錄的先前影像。這是一組重複的目標資料欄,名稱如 col1 _before、col2 _before 等。
-
目標資料欄的目前值。這也是一組重複的目標資料欄,名稱如 col1 _current、col2 _current 等。
-
目標表格的名稱
-
衝突的時戳
-
作業類型
-
資料庫錯誤編號
-
(選擇性) 資料庫錯誤訊息
-
是否已解決衝突
-
-
建立例外
MAP陳述式,以將例外資料對應至例外表格。例外MAP陳述式包含:-
(必要)
INSERTALLRECORDS選項。此參數會將所有對應的作業轉換成INSERT,以便將所有資料欄值對應至異常狀況表格。 -
(必要)
EXCEPTIONSONLY選項。此參數會導致 Replicat 對應產生錯誤的作業,但不會對應成功的作業。 -
(選擇性)
COLMAP子句。如果異常狀況表格中資料欄的名稱和定義與來源表格的名稱和定義相同,而且異常狀況表格只包含那些資料欄,則不需要COLMAP。不過,如果有任何名稱或定義不同,或您想以其他資料填入的異常狀況表格中有額外的資料欄,請使用COLMAP子句來對應所有資料欄。
-
將額外資料對應至例外表格的工具
下列是您可以在 COLMAP 子句中用來填入額外資料欄的一些工具:
-
如果來源資料欄的名稱和定義與異常狀況表格中目標資料欄的名稱和定義相同,您可以使用
USEDEFAULTS關鍵字,而不是明確的對應名稱。否則,您必須對應COLMAP子句中的那些資料欄,例如:COLMAP (exceptions_col1 = col1, [...]) -
若要將來源資料列的先前影像對應至異常狀況表格中的資料欄,請使用
@BEFORE轉換函數,此函數會從歷程檔記錄擷取資料欄的前一個影像。此範例顯示@BEFORE用法。COLMAP (USEDEFAULTS, exceptions_col1 = @BEFORE (source_col1), & exceptions_col2 = @BEFORE (source_col2), [...]) -
若要將目標資料列的目前影像對應至例外表格中的資料欄,請使用
SQLEXEC查詢來擷取影像,然後使用COLMAP子句中的 'queryID.column ' 語法將查詢結果對應至例外表格中的資料欄,如下列範例所示:COLMAP (USEDEFAULTS, name_current = *queryID*.*name*, phone_current = *queryID*.*phone*, [...]) -
若要對應時戳、資料庫錯誤以及其他環境資訊,請使用適當的 Oracle GoldenGate 資料欄轉換函數。例如,下列項目會在執行時對應目前的時間戳記。
res_date = @DATENOW ()
請參閱範例例外對應與例外表格中的其他資料欄,瞭解如何在例外 MAP 陳述式中的 COLMAP 子句中結合這些功能,以植入詳細的例外表格。
請參閱Oracle GoldenGate 的參數和函數參照,瞭解這些範例中顯示的參數和資料欄轉換函數的用法和語法。
僅含來源與目標資料欄的範例例外對應
以下為範例參數檔,其中顯示開始 CDR 範例中所使用之來源和目標表格的錯誤處理和簡單例外對應。此範例會對應來源和目標資料欄,但沒有額外的資料欄。基於下列原因,此範例中的 MAP 陳述式例外不需要 COLMAP 子句:
-
名稱和定義中的來源和目標異常狀況資料欄相同。
-
異常狀況表格中沒有其他資料欄。注意:此範例會故意離開 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 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)
;
一旦您確信常式在所有狀況下都能如預期般運作,您就可以減少記錄到例外表格的資料量,以減少解決常式的負荷。