OGG的REP进程对主键列加1的处理

本文是转载,原文作者震总,他是Oracle database, OGG,HVR方面的资深工程师。

问题说明

对于表的主键列进行更新时,如果更新语句为set x=x+n或者更新过程中涉及到主键值的偏移,这种事务在源端可以正常执行,因为更新操作是在同一个语句中完成的。而对于HVR目标端来说,可能会把源端的一个更新语句转换为多个更新语句如:

目标端在执行上面的语句时会触发主键约束而报错:

ORA-00001: unique constraint (WZTEST.SYS_C005212) violated

Goldengate处理方式

Oracle 11.2.0.2之前可以使用HANDLETPKUPDATE参数来解决,报错问题。

不过这个参数的使用有一个限制条件,就是对应表的主键要修改成deferrable状态。

alter table WZTEST.TB

  drop constraint SYS_C005213 cascade;

alter table WZTEST.TB

  add primary key (ID)

  deferrable;

这只是一种临时的解决办法,当主键表太多时就不太适用了。

 

参数HANDLETPKUPDATE的使用方式

replicat reppart

setenv ( NLS_LANG =  "AMERICAN_AMERICA.ZHS16GBK" )

 

assumetargetdefs

userid goldengate, password oracleoracle

DBOPTIONS DEFERREFCONST, SUPPRESSTRIGGERS

gettruncates

ALLOWNOOPUPDATES

ddl include mapped

 

discardfile ./dirrpt/reppart.dsc, purge, megabytes 5000

 

MAP WZTEST.*,            target  WZTEST.*, HANDLETPKUPDATE;

 

通过10046跟踪可以得到goldengate应用进程在执行对pkupdate前后会执行下面的两个语句。执行更新操作前它会把constraint设置为deferred状态,更新完成之后,再设置成immediate状态。

 

alter session set constraint = deferred

 

UPDATE /*+ RESTRICT_ALL_REF_CONS */ "WZTEST"."TB" SET "ID" = :a1 WHERE "ID" = :b0 AND rowid <> :rid

 

alter session set constraint = immediate

 

 

Oracle 11.2.0.3中的处理方式

Oracle11.2.0.3的存储过程DBMS_XSTREAM_GG.ENABLE_TDUP_WORKSPACE可以解决这个问题,使用这个存储过程不再需要对表的主键状态进行修改,也不需要在Goldengate的参数文件中使用handletpkupdate参数。

 

这个存储过程是数据库自带的,即使没有部署Goldengate 数据库中也有这个存储过程。

 

通过10046可以看到goldengate的应用进程中显示了调用了dbms_xstream_gg.enable_tdup_workspacedbms_xstream_gg.disable_tdup_workspace两个存储过程。

 

begin dbms_xstream_gg.enable_tdup_workspace; end;

update …

begin dbms_xstream_gg.disable_tdup_workspace; end;

 

这两个存储过程在数据库中是加密的,具体的实现,不得而知。

 

参考文档:

GoldenGate REPLICAT abend ORA-00001: unique constraint violated on transient PKUpdate in 11.2.0.4 (Doc ID 1928263.1)

Usage of Handletpkupdate requires specific defer settings on table (Doc ID 1303231.1)

Oracle® GoldenGate Windows and UNIX Reference Guide 11g Release 2 Patch Set 1 (11.2.1.0.1)

你可能感兴趣的:(OGG的REP进程对主键列加1的处理)