环境介绍:
源端:sybase数据库,服务器字符集iso_1,数据字符集cp936;
replicat进程错误:
ERROR OGG-03517 Conversion from character set zhs16gbk of source column CYXM to character set UTF-8 of target column CYXM failed because the source column contains a character that is not available in the target character set.
解决心路历程:
一开始遇到这个问题,懵了,这是什么鬼,CYXM这个字段的字符转换错误?不对啊,logdump看了一下数据,再去源库看数据,没什么错呀。goldengate发什么疯,行吧,那我就根据前人的经验,使用SOURCECHARSET PASSTHRU这个参数。一重启,行啊,够给力的,进程不报错误了,数据库数据乱码了~呵呵哒。去看了官方介绍,原来SOURCECHARSET PASSTHRU这个参数是将我声明的源端字符集参数(ZHS16GBK)去掉,直接就将源端服务器字符集(ISO-8859-1)的数据插入进来,怪不得会乱码。看样子这个参数不能用。找了度娘好多次(目前还不会用Google),最后总结出现这个问题的原因可能是:
1. sybase的cp936字符集和oracle的zhs16gbk字符集是超集和子集的关系;
2. zhs16gbk 和 utf-8 字符转换存在编码问题。
故此,针对字符转换的问题,我是暂时没有解决方案了。但是突然想到,能不能跳过这个字符转换的错误呢?跑到Goldengate交流群上提问:
广州-tan() 11:28:33
请问各位,Goldengate的replicat进程设置了出现错误记录到discart文件中,但是,这次出现了一个OGG-03517的错误,它直接就Abend了,错误报告是这条记录的一个字段字符集转换错误,我检查了一下,应该是中文字符集超集与子集的原因 但是,目前Oracle的字符集对中文的支持就只能这样了,所以我想让它出现类似错误时,不Abend,先记录discard文件 可以实现吗? 随风() 11:30:24 可以 广州-tan() 11:30:34 请问怎么设置? PONG() 11:30:38 用这个参数应该可以 随风() 11:33:45 reperror(-03517,discard) 广州-tan() 11:35:46 @随风 可以写多个reperror参数吗 随风() 11:36:06 可以啊 广州-tan() 11:36:21 reperror(OGG-03517,discard) reperror(Default,discard) 这样写? 随风() 11:36:23 两个错误就写两个就行 随风() 11:36:59 reperror(-03517,discard) 就这个写法 广州-tan() 11:37:42 那两个错误,是写两个reperror,还是写一个reperror 随风() 11:37:53 两个 写上不同错误号就行 广州-tan() 11:38:16 恩,多谢 @随风 @PONG |
然后我就尝试使用REPERROR这个参数,想通过discard文件去捕获这个错误,不至于导致REPLICATE进程ABEND了,REPERROR的使用方式如下:
REPERROR {
(
{DEFAULT | DEFAULT2 | SQL_error | user_defined_error},
{ABEND |
DISCARD |
EXCEPTION |
IGNORE |
RETRYOP [MAXRETRIES n] |
TRANSABORT [, MAXRETRIES] [, DELAYSECS n | DELAYCSECS n] |
TRANSDISCARD |
TRANSEXCEPTION
}
) |
RESET } |
将prm文件加入REPERROR参数后,我兴高采烈的start replicat进程,呵呵哒,还是abend。然后又去上了度娘,发现,REPERROR是可以捕获错误,但是OGG的错误,是没法捕获的啊~~~~。然后我又是一顿搜啊,最后在oracle的官方文档找到:
REPLACEBADCHARValid For Extract and Replicat Description Use the Default ABORT Syntax REPLACEBADCHAR {ABORT | SKIP | ESCAPE | SUBSTITUTE string | NULL | SPACE} [FORCECHECK] [NOWARNING]
|
MY GOD,我好像看到了救星,行了,就用你了。
我在prm文件中加入:
REPLACEBADCHAR SKIP NOWARING
目的:当出现某些字段的字符转换错误时,跳过此条记录,并不发出WARING信息。
注意:虽然官方解释道:如果使用skip选项,可能会导致数据不一致。但是吧,我这边使用该参数后,进程不报错了,数据也一致。我也在奇怪为什么会这个样子。不过现在进程至少不会因为这种字符转换的问题abend了,全部表的数据也能实时同步了。但是以后还是需要注意字符转换错误的那个表,看看数据是否一致,如果一致,那就不用鸟了。如果不一致,那只能再次排查,寻求解决方案了。
by the way,至于我为什么使用NOWARING选项,我喜欢,我高兴!
直接解决方案(不想看我一大堆废话的人儿):
REPLACEBADCHAR SKIP NOWARING