GoldenGate HANDLECOLLISIONS参数使用说明
HANDLECOLLISIONS在官方文档上的说明:
使用HANDLECOLLISIONS和NOHANDLECOLLISIONS参数来控制在目标上应用SQL时,Replicat是否尝试解决重复记录和缺少记录的错误。
事实是, HANDLECOLLISIONS 经常被烂用。为了省事,许多运维人员,经常在目标端投递出问题时,直接在目标端进程上配置 HANDLECOLLISIONS,然后进程就会启动并继续执行,但这样做只会掩盖问题,并且随着时间的迁移,问题越积越深,最终发现目标端的数据与源端相差很远。
所以 HANDLECOLLISIONS 根据官方的建议,一般只应该用在初始化阶段的replicat进程。如果在其它时候使用 HANDLECOLLISIONS,这是非常不明智的做法,因为极有可能会造成数据不一致。
如果有这种情况,应该立即停止投递进程并删除HANDLECOLLISIONS参数,然后对源和目标端的数据进行对比后重新同步。
要使用 HANDLECOLLISIONS,还需要在源端进程和表的附加日志上做些工作,包括:
1.HANDLECOLLISIONS 只在有PK或唯一索引的表上有效,如果是没有唯一键的表,则可能造成重复记录。
2.在抽取进程使用LOGALLSUPCOLS参数,并针对表打开全字段附加日志,如果没有这样设置,当 HANDLECOLLISIONS 将update操作转换为insert操作时,可能会报ORA-1403错误。
3.如果表上有LOB字段,且存的内容超过缓冲区域(2 kb或4 kb)的大小,则 HANDLECOLLISIONS 会排除此LOB字段的处理,所以,如果有表包含有lob字段,且长度超过2Kb,则不应该使用 HANDLECOLLISIONS。
所以, HANDLECOLLISIONS 最好是在初始化时使用,且初始化追平之后就应该停止使用。下面基于一个示例来讲解:
如果在下午1点启动抽取进程,2点的时候,在确保没有1点之前开始且到2点还没有结束的事务,此时,使用SourceIsTable进行初始化。在初始化的过程中,系统上一般会有数据变化。
下午3点的时候初始化完成,现在在目标端使用 HANDLECOLLISIONS 参数,启动投递进程。此时,投递进程会从队列文件(增量数据)最开始的地方(1点)开始应用数据到目标端DB,理论上1-2点之间变化的数据在OGG增量数据和初始化数据中都有包含。比如,有人在1:15开始一个事务,1:30才结束,在OGG的extract增量数据及initial load中都会包含这个交易的数据。此时,因为有使用 HANDLECOLLISIONS ,所以replicat会根据冲突处理机制,自动处理这些重复数据,确保目标端数据一致。
一旦目标端replicat进程处理到初始化结束的时间点,即3点,则应该立即使用 SEND REPLICAT NOHANDLECOLLISIONS 去掉自动冲突解决机制,并将 HANDLECOLLISIONS 参数从replicat进程中删除。