GoldenGate自身不提供异常处理的程序。在默认情况下,若Replicat进程遭遇操作故障都会导致其异常终止(ABEND),同时将会回滚事务到最近的检查点。在生产环境中这往往并不理想。当我们在做无缝的数据迁移时会用到HANDLECOLLISIONS和NOHANDLECOLLISIONS参数,这2个参数控制了Replicat是否会试图解决重复记录和缺失记录的错误,但这错误真的应该被忽略吗?这个问题只有熟悉应用的维护人员才能解答,我们需要做的是在出现这类错误后及时记录错误的相关信息。
这就要求我们在Replicat中配置相关的意外处理程序,该程序用以记录是哪个Replicat进程,是那些数据引起了错误的产生。
接下来我们会尝试建立不同的意外处理程序,用以捕获复制过程中Oracle出现的相关错误,但在这些故障发生后我们允许Replicat继续它的工作:
1. 首先我们要做的是创建用以记录错误相关信息的错误记录表: SQL> conn maclean/maclean Connected. SQL> create table exception_log 2 ( replicat_name varchar2(10), 3 table_name varchar2(100), 4 errno number, 5 dberrmsg varchar2(4000), 6 optype varchar2(20), 7 errtype varchar2(20), 8 logrba number, 9 logposition number, 10 committimestamp timestamp); Table created. SQL> alter table exception_log add primary key (logrba,logposition,committimestamp); Table altered. 以上意外处理记录表应建立于Goldengate管理员账户名下,可用以记录所有Replicat的意外数据。 2.修改各Replicat的参数文件添加相关的意外处理程序: GGSCI (rh3.oracle.com) 59> view params rep1 replicat rep1 userid maclean,password maclean ASSUMETARGETDEFS discardfile /s01/discard/rep1.log,append,megabytes 10 REPERROR (DEFAULT, EXCEPTION) REPERROR (DEFAULT2,ABEND) map defs.tbc, target defs.tbc; map defs.tbc, target maclean.exception_log, EXCEPTIONSONLY, INSERTALLRECORDS, COLMAP ( replicat_name = "rep1" , table_name = @GETENV ("GGHEADER", "TABLENAME") , errno = @GETENV ("LASTERR", "DBERRNUM") , dberrmsg = @GETENV ("LASTERR", "DBERRMSG") , optype = @GETENV ("LASTERR", "OPTYPE") , errtype = @GETENV ("LASTERR", "ERRTYPE") , logrba = @GETENV ("GGHEADER", "LOGRBA") , logposition = @GETENV ("GGHEADER", "LOGPOSITION") , committimestamp = @GETENV ("GGHEADER", "COMMITTIMESTAMP")); REPERROR参数用以控制Replicat进程如何响应映射过程中发生的错误 DEFAULT参数代表一种全局错误类型,即除去所有已明确指定的错误外的一切错误 DEFAULT2参数代表当DEFAULT错误以Exception方式响应时,所有MAP映射中未定义Exception部分出现的所有错误 3.停止并重启Replicat 进程 GGSCI (rh3.oracle.com) 60> stop rep1 Sending STOP request to REPLICAT REP1 ... Request processed. GGSCI (rh3.oracle.com) 61> start rep1 Sending START request to MANAGER ... REPLICAT REP1 starting 4.以上完成了对单表defs.tbc意外处理的配置,接着我们可以启动相关的应用了 5.通过某些手动篡改数据或不同步操作,可以很容易地触发意外处理而将相关错误信息记录到我们的exception_log表中,我们可以来查看 相关记录: SQL> col dberrmsg for a1; SQL> col table_name for a10; SQL> select * from exception_log; REPLICAT_NAME TABLE_NAME ERRNO D OPTYPE ERRTYPE LOGRBA LOGPOSITION COMMITTIMESTAMP ------------- ---------- ---------- - -------------------- -------------------- ---------- ----------- --------- rep1 DEFS.TBC 1403 PK UPDATE DB 231 59259920 23-DEC-10 1 rep1 DEFS.TBC 1403 PK UPDATE DB 231 59260812 23-DEC-10 1 rep1 DEFS.TBC 1403 PK UPDATE DB 231 94620688 23-DEC-10 1 rep1 DEFS.TBC 1403 PK UPDATE DB 231 94621580 23-DEC-10 1 rep1 DEFS.TBC 1403 PK UPDATE DB 231 94682640 23-DEC-10 1 rep1 DEFS.TBC 1403 PK UPDATE DB 231 94683532 23-DEC-10 1 6 rows selected 可以看到以上为基于主键更新时出现了1403 "no data found"的Oracle常规错误。 意外处理程序所能记录的相关信息还不于止此,我们还可以用它来记录如Update操作的前后数据镜像,这些信息可以在冲突解决时派上用场。