由引數檔案配置表對映重複引發的OGG-01154 ORA-00001

你好我是李白發表於2020-08-26

1.現象

2020-08-26T13:26:23.854+0800  WARNING OGG-01154  Oracle GoldenGate Delivery for Oracle, rp_czh.prm:  SQL error 1 mapping HR.TEST to HR.TEST OCI Error ORA-00001: unique constraint (HR.PK_TEST) violated (status = 1), SQL <INSERT INTO "HR"."TEST" ("ID","NAME") VALUES (:a0,:a1)>.
2020-08-26T13:26:23.854+0800  ERROR   OGG-01296  Oracle GoldenGate Delivery for Oracle, rp_czh.prm:  Error mapping from HR.TEST to HR.TEST.
2020-08-26T13:26:23.862+0800  ERROR   OGG-01668  Oracle GoldenGate Delivery for Oracle, rp_czh.prm:  PROCESS ABENDING.

2.排查

檢查discard檔案,檢查表資料,發現表中並沒有discard檔案中行資料,表也有主鍵。

排查引數設定,發現datapump程式parameter引數中對報錯表有兩行。

3.復現

3.1 搭建引數相同測試環境,對測試表建裡主鍵

CREATE TABLE TEST(ID NUMBER PRIMARY KEY,NAME VARCHAR2(20));

3.2 datapump引數檔案中寫

GGSCI (single) 21> view param dp_tar
extract dp_tar
setenv (NLS_LANG="AMERICAN_AMERICA.AL32UTF8")
CACHEMGR CACHESIZE 100MB
passthru
DYNAMICRESOLUTION
discardfile ./dirrpt/dp_tar.dsc,append, megabytes 100
rmthost db-oracle-node1, mgrport 7809, compress
rmttrail ./dirdat/rt
table hr.test;
table hr.test;

3.3 源端測試DML

HR@messay > insert into test values(10,'nihaoma');
HR@messay > commit;

3.4 目標端logdump查詢

# 其實此時由於目標端有主鍵,replicat程式已經由於ORA-00001報錯abending了,查詢目標庫也並沒有discard檔案中對應主鍵值得行。

# 透過logdump檢視佇列檔案中資料

Logdump 2 >ghdr on
Logdump 3 >detail on
Logdump 4 >detail data on   
Logdump 5 >usertoken on 
Logdump 6 >open ./rt000010
Logdump 10 >POSITION 4821
Reading forward from RBA 4821 
Logdump 11 >next
___________________________________________________________________ 
Hdr-Ind    :     E  (x45)     Partition  :     .  (x04)  
UndoFlag   :     .  (x00)     BeforeAfter:     A  (x41)  
RecLength  :    25  (x0019)   IO Time    : 2020/08/26 14:41:57.808.299   
IOType     :     5  (x05)     OrigNode   :   255  (xff) 
TransInd   :     .  (x00)     FormatType :     R  (x52) 
SyskeyLen  :     0  (x00)     Incomplete :     .  (x00) 
AuditRBA   :         13       AuditPos   : 38990352 
Continued  :     N  (x00)     RecCount   :     1  (x01) 
2020/08/26 14:41:57.808.299 Insert               Len    25 RBA 4821 
Name: HR.TEST 
After  Image:                                             Partition 4   G  b   
 0000 0006 0000 0002 3130 0001 000b 0000 0007 6e69 | ........10........ni  
 6861 6f6d 61                                      | haoma  
Column     0 (x0000), Len     6 (x0006)  
 0000 0002 3130                                    | ....10  
Column     1 (x0001), Len    11 (x000b)  
 0000 0007 6e69 6861 6f6d 61                       | ....nihaoma  
   
Logdump 12 >next
___________________________________________________________________ 
Hdr-Ind    :     E  (x45)     Partition  :     .  (x04)  
UndoFlag   :     .  (x00)     BeforeAfter:     A  (x41)  
RecLength  :    25  (x0019)   IO Time    : 2020/08/26 14:41:57.808.299   
IOType     :     5  (x05)     OrigNode   :   255  (xff) 
TransInd   :     .  (x02)     FormatType :     R  (x52) 
SyskeyLen  :     0  (x00)     Incomplete :     .  (x00) 
AuditRBA   :         13       AuditPos   : 38990352 
Continued  :     N  (x00)     RecCount   :     1  (x01) 
2020/08/26 14:41:57.808.299 Insert               Len    25 RBA 4957 
Name: HR.TEST 
After  Image:                                             Partition 4   G  e   
 0000 0006 0000 0002 3130 0001 000b 0000 0007 6e69 | ........10........ni  
 6861 6f6d 61                                      | haoma  
Column     0 (x0000), Len     6 (x0006)  
 0000 0002 3130                                    | ....10  
Column     1 (x0001), Len    11 (x000b)  
 0000 0007 6e69 6861 6f6d 61                       | ....nihaoma

# 可以看到insert在trail檔案中一模一樣兩行資料,問題得到復現

4.解決

4.1 源端datapump先去重

修改datapump goldengate引數檔案,先去重。

4.2 replicat引數檔案修改引數reperror或加入HANDLECOLLISIONS

# 下面介紹兩種引數,這兩個引數實際測試均有特定使用場景

# 均可以達到部分效果。

reperror(1,ignore)
# 忽略ORA-00001報錯,也就是將trail檔案中insert雙份都忽略掉報錯的第二條資料
# 這個引數僅適用於表均含有主鍵唯一鍵,如果有表不包含主鍵唯一鍵,則由於不會報ORA-00001,資料將發生重複,需要謹慎。

HANDLECOLLISIONS

會自動處理重複資料或者update目標端沒有資料no data found,

# 下面就講解一下HANDLECOLLISIONS處理資料簡單邏輯
(1)當遇到重複資料會自動刪除目標端原有資料,然後將新資料insert:
Target,插入資料,造成資料重複:
HR@honor1 > insert into test values(12,'test');
HR@honor1 > commit;
Source:
HR@messay > insert into test values(12,'testtest');
HR@messay > commit;
Target:
HR@honor1 > select * from test;
                                      ID NAME
---------------------------------------- ----------------------------------------
                                      12 testtest
# 可以看到已經在目標端將舊值刪除,替換為新資料
(2)當update更新沒有值時,會自動insert:
Target,刪除資料,造成沒有該行資料:
HR@honor1 > delete from test where id=11;
HR@honor1 > commit;
Source:
HR@messay > update test set name='dwwwww' where id=11;
HR@messay > commit;
Target:
HR@honor1 > select * from test;
                                      ID NAME
---------------------------------------- ----------------------------------------
                                      11 dwwwww
# 可以看到已經將刪除的資料在目標端由update轉為insert操作。
(3)delete操作時,如果目標端沒有資料,將不報錯
Target:
HR@honor1 > delete test where id=12;
HR@honor1 > commit;
Source:
HR@messay > delete test where id=12;
HR@messay > commit;
Target:
GGSCI > info all
Program     Status      Group       Lag at Chkpt  Time Since Chkpt
MANAGER     RUNNING                                           
REPLICAT    RUNNING     RP_CZH      00:00:03      00:00:09
# 觀察discard檔案,上述三個操作均沒有記錄discard檔案。
# 需要注意以下兩點:
(1)在所有列沒有新增事務日誌,即ADD TRANDATA acct ALLCOLS或者資料庫alter table <tbl_name> add supplemental log data(all) columns可能造成update轉為
insert時缺失部分列資料,造成資料依然不一致。
(2)NOCOMPRESSUPDATES,源端extract引數,加入此引數,控制extract將所有列傳送到trail檔案中。
(3)FETCHOPTIONS FETCHPKUPDATECOLS,配置extract該選項,以便在逐漸更新時獲取到其他不可用的列,
取值是fetch時值,並不是pk更新時的值,所以可能因為延遲,引發資料完整性問題。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31439444/viewspace-2715003/,如需轉載,請註明出處,否則將追究法律責任。

相關文章