현상
Table Migrator 툴을 사용하여 Tibero to Tibero 데이터 마이그레이션을 수행하는 과정에서,
일부 테이블에서 JDBC-90651: Failed to convert given data 오류가 발생하며 마이그레이션이 실패하는 문제가 발생하였습니다.
참고
• 문제 발생 버전 : tibero7.2.1
•
migrator 로그 에러 발생 부분
ERROR[17:09:08,187][L0.TbDPLDataLoader0]DataLoaderManager.run()(273)
java.sql.SQLException: JDBC-90651:Failed to convert given data.
at com.m.internal.jdbc.err.MInternalError.newSQLException(Unknown Source)
at com.m.internal.jdbc.data.charset.CharsetMapper.stringToBytes(Unknown Source)
at com.m.internal.jdbc.data.DataTypeConverter.getDBEncodedBytes(Unknown Source)
at com.m.internal.jdbc.data.DataTypeConverter.fromString(Unknown Source)
at com.m.internal.jdbc.data.DataTypeConverter.castFromString(Unknown Source)
at com.m.internal.jdbc.dpl.binder.DPLStringBinder.bind(Unknown Source)
at com.m.internal.jdbc.dpl.MInternalDirPathStream.copyStream(Unknown Source)
at com.m.internal.jdbc.dpl.MInternalDirPathStream.loadStreamBatch(Unknown Source)
at com.m.migrator.loader.tb.TbDPLDataLoader.load(TbDPLDataLoader.java:373)
at com.m.migrator.loader.DataLoaderManager.run(DataLoaderManager.java:186)
SQL
복사
•
jdbc dbg log 일부
14:34:44.790 [L0.TbDPLDataLoader0] java.sql.SQLException: JDBC-90651:Failed to convert given data.
at com.m.internal.jdbc.err.MInternalError.newSQLException(MInternalError.java:596)
at com.m.internal.jdbc.data.charset.CharsetMapper.stringToBytes(CharsetMapper.java:256)
at com.m.internal.jdbc.data.DataTypeConverter.getDBEncodedBytes(DataTypeConverter.java:2106)
at com.m.internal.jdbc.data.DataTypeConverter.fromString(DataTypeConverter.java:1892)
at com.m.internal.jdbc.data.DataTypeConverter.castFromString(DataTypeConverter.java:1072)
at com.m.internal.jdbc.dpl.binder.DPLStringBinder.bind(DPLStringBinder.java:45)
at com.m.internal.jdbc.dpl.MInternalDirPathStream.copyStream(MInternalDirPathStream.java:225)
at com.m.internal.jdbc.dpl.MInternalDirPathStream.loadStreamBatch(MInternalDirPathStream.java:400)
at com.m.migrator.loader.tb.TbDPLDataLoader.load(TbDPLDataLoader.java:373)
at com.m.migrator.loader.DataLoaderManager.run(DataLoaderManager.java:186)
Caused by: java.sql.SQLException: JDBC-590742:Character set conversion failed: unknown character. - 65
at com.m.internal.jdbc.err.MInternalError.makeSQLException(MInternalError.java:483)
at com.m.internal.jdbc.err.MInternalError.newSQLException(MInternalError.java:566)
at com.m.internal.jdbc.err.MInternalError.newSQLException(MInternalError.java:585)
at com.m.internal.jdbc.data.charset.UTF8CharToByteConverter.convString(UTF8CharToByteConverter.java:151)
at com.m.internal.jdbc.data.charset.UTF8Encoder.stringToBytes(UTF8Encoder.java:102)
at com.m.internal.jdbc.data.charset.CharsetMapper.stringToBytes(CharsetMapper.java:253)
... 8 more
SQL
복사
원인
•
UTF16 to UTF8 변환 과정에서 invalid한 surrogate pair에 해당하는 값임에도 UTF-16으로 변환하며 JDBC-90651 오류가 발생하였습니다.
•
위 원인으로 JDBC에서 getString을 통해 String을 가져 오면서 이미 변화 과정에서 input으로 깨진 문자열이 들어오게 되어 migrator 에서 JDBC-90651 에러를 발생시킵니다.
해결
아래 패치를 적용하여 해결합니다. (적용 패치: 329001a_jdbc)
•
329001a_jdbc 패치는 UTF16 to UTF8 변환 과정 영역 처리 로직을 추가한
주의
티맥스티베로에서 제공하는 기술지원을 통해 패치를 적용합니다.
참고
[용어 설명]
1. Surrogate 영역 : 유니코드에서 보조 문자를 UTF-16으로 표현하기 위한 범위로 해당 영역은 단독으로 문자로 간주되지 않습니다. UTF-16 의 최대 표현 가능 수는 65536개로 이 이상의 문자를 나타내고자 Surrogate 영역을 사용하게 됩니다. 해당 영역은 High Surrogate 와 Low Surrogate 의 조합으로 만들어집니다. 두 영역이 모두 있고 정상적인 범위 내에 있어야만 유효(vaild) 하다고 간주됩니다.
2. High Surrogate : Surrogate 영역의 앞 부분(상위)입니다.
3. Low Surrogate : Surrogate 영역의 뒷 부분(하위)입니다.
4. Surrogate pair : High Surrogate + Low Surrogate 의 쌍을 나타냅니다. UTF-16에서 사용되는 인코딩 구조입니다.
5. subChar : 대체 문자로 인코딩 오류 또는 잘못된 부분이 있을 때 이 부분을 처리하기 위해 존재합니다.
6. Char : UTF-16에서 읽는 2바이트 단위 코드입니다.