Goldengate没有例外处理机制,如果复制进程出错,就会Abend,并Rollbak事务到上一个Checkpoint.这在生产环境中是不理想的做法.
HANDLECOLLISIONS 和 NOHANDLECOLLISIONS 这两个参数用来控制复制进程是否尝试解决重复记录和丢失记录的错误.但是,这类错误仅仅是忽略是不行的.
需要有一个记录,记下有错误发生,哪个复制进程出错,是由什么数据引起的,这可以通过创建例外句柄来记录下这些信息,但不影响复制进程继续进行.
步骤
1.创建例外表:
create table ggs_admin.exceptions
( rep_name varchar2(8)
, table_name varchar2(61)
, errno number
, dberrmsg varchar2(4000)
, optype varchar2(20)
, errtype varchar2(20)
, logrba number
, logposition number
, committimestamp timestamp
);
ALTER TABLE ggs_admin.exceptions ADD (
CONSTRAINT PK_CTS
PRIMARY KEY
(logrba, logposition, committimestamp) USING INDEX PCTFREE 0 TABLESPACE MY_INDEXES);
表要创建在Goldengate的管理用户下,并且能记下所有复制进程的例外数据.
2.编写复制进程的采纳书文件,增加例外处理的宏代码
[oracle@linuxserver1 ggs]$ ggsci
GGSCI (linuxserver1) 1> edit params RTARGET1
-- This starts the macro
MACRO #exception_handler
BEGIN
, TARGET ggs_admin.exceptions
, COLMAP ( rep_name = "RTARGET1"
, 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"))
, INSERTALLRECORDS
, EXCEPTIONSONLY;
END;
-- This ends the macro
3.在复制进程的参数文件中增家MAP部分,对于每个表增加#exception_handler(),用REPERROR (-1, EXCEPTION)参数说明需要记录Oracle Error.
REPERROR (DEFAULT, EXCEPTION)
REPERROR (DEFAULT2, ABEND)
REPERROR (-1, EXCEPTION)
MAP SRC.ORDERS, TARGET TGT.ORDERS;
MAP SRC.ORDERS #exception_handler()
MAP SRC.ORDER_ITEMS, TARGET TGT.ORDER_ITEMS;
MAP SRC.ORDER_ITEMS #exception_handler()
MAP SRC.PRODUCTS, TARGET TGT.PRODUCTS;
MAP SRC.PRODUCTS #exception_handler()
REPERROR:控制复制进程在执行MAP语句时如何处理错误
DEFAULT:参数设置处理指定的错误以外,对错误的全局响应
Default2:参数指定要捕获可能会发生的所有的未想到的Error,并使进程Abend
4.停止并重启复制进程
GGSCI (linuxserver1) 3> stop REPLICAT RTARGET1
GGSCI (linuxserver1) 4> start replicat RTARGET1
info all