OGG-01154 ORA-00001

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更新时的值,所以可能因为延迟,引发数据完整性问题。

 

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页