環境介紹:
源端:sybase數據庫,服務器字符集iso_1,數據字符集cp936;
目標端:oracle11g,字符集AL32UTF8。
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然後我就嘗試使用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的官方文檔找到:
Valid For
Extract and Replicat
Description
Use the REPLACEBADCHAR
parameter to control the response of the process when a valid code point does not exist for either the source or target character set when mapping character-type columns. By default, the check for invalid code points is only performed when the source and target databases have different character sets, and the default response is to abend. You can use the FORCECHECK
option to force the process to check for invalid code points when the source and target databases have the same character set. REPLACEBADCHAR
applies globally.
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