Tibero 5 JDBC-590743 문자셋 변환 오류 점검 방법
Tibero 5에서 Java 애플리케이션으로 INSERT를 수행할 때 JDBC-590743: Character set conversion failed: invalid input 오류가 발생한다면, 우선 DB 문자셋과 JDBC 클라이언트 인코딩, 실제 입력 문자열에 DB 문자셋으로 변환할 수 없는 문자가 포함되어 있는지를 함께 확인해야 한다.
JDBC-590743은 문자열을 Tibero 서버 문자셋으로 변환하는 과정에서 유효하지 않은 입력이 들어왔을 때 발생할 수 있다.특히 Tibero 5 환경에서 DB 문자셋이
MSWIN949, EUC-KR, KSC5601 계열인데 애플리케이션이 UTF-8 데이터를 넣는 경우 자주 확인된다.한글 자체보다 이모지, 특수기호, 깨진 바이트, 잘못 디코딩된 파일 데이터, 외부 시스템에서 넘어온 비정상 문자열이 원인이 되는 경우가 많다.
해결은 DB 문자셋 확인, JDBC 드라이버 확인, 입력 데이터 재현, 문제 문자 제거 또는 DB 문자셋 정책 재검토 순서로 진행하는 것이 안전하다.
개요
제시된 오류 메시지는 다음과 같다.
java.sql.SQLException: JDBC-590743:
Character set conversion failed: invalid input. - 57133
이 오류는 SQL 문법 오류라기보다는 INSERT 대상 문자열이 Tibero 내부 문자셋으로 변환되는 과정에서 실패했다는 의미로 보는 것이 맞다. 즉, 테이블 구조나 컬럼 길이 문제만 확인해서는 원인을 찾기 어렵고, 문자열이 어떤 인코딩으로 생성되었고 DB가 어떤 문자셋을 사용하는지를 같이 봐야 한다.
운영 환경에서는 오류가 발생한 SQL 한 줄만 보는 것보다, 입력값이 만들어진 경로를 추적하는 것이 중요하다. 화면 입력값인지, 파일 업로드 데이터인지, 다른 DB에서 이관한 값인지, 외부 API 응답인지에 따라 원인 지점이 달라진다.
환경
| DBMS | Tibero 5 |
|---|---|
| 발생 작업 | Java 애플리케이션 또는 JDBC 기반 프로그램에서 INSERT 수행 |
| 오류 메시지 | JDBC-590743: Character set conversion failed: invalid input. - 57133 |
| 주요 의심 구간 | DB 문자셋, JDBC 드라이버, JVM 인코딩, 입력 파일 인코딩, 외부 시스템 문자열 |
Tibero 5는 오래 운영된 시스템에서 많이 사용되므로, DB 문자셋이 UTF-8이 아닌 한글 완성형 계열로 구성된 경우가 있다. 이 상태에서 Java 애플리케이션이 UTF-8 기준 문자열을 그대로 전달하면 일부 문자는 DB 문자셋으로 변환되지 못할 수 있다.
증상
대표적인 증상은 INSERT 또는 PreparedStatement 실행 시점에 예외가 발생하는 것이다. 같은 SQL 구조라도 입력값에 따라 정상 수행되거나 실패할 수 있다.
PreparedStatement pstmt = conn.prepareStatement(
"insert into sample_table (id, memo) values (?, ?)"
);
pstmt.setInt(1, 1);
pstmt.setString(2, inputText);
pstmt.executeUpdate();
위 코드에서 inputText 값이 단순 영문, 숫자, 일반 한글일 때는 성공하지만 특정 특수문자나 이모지, 복사해 온 문자가 포함될 때만 실패한다면 문자셋 변환 오류 가능성이 높다.
이 경우 컬럼 길이를 늘려도 해결되지 않는다.
길이 문제가 아니라 문자 표현 가능 범위 문제이기 때문이다.
1차 점검
먼저 Tibero 서버의 문자셋을 확인한다. 운영 중인 Tibero 5 환경에서는 아래 조회 중 사용 가능한 뷰를 기준으로 확인하면 된다.
-- DB 문자셋 확인 예시 1
select *
from nls_database_parameters
where parameter like '%CHARACTERSET%';
-- DB 문자셋 확인 예시 2
select *
from v$nls_parameters
where parameter like '%CHARACTERSET%';
여기서 NLS_CHARACTERSET 값이 UTF8 또는 AL32UTF8 계열인지, 아니면 MSWIN949, EUC-KR, KSC5601 계열인지 확인한다.
| 확인 항목 | 점검 내용 |
|---|---|
| DB 문자셋 | 서버가 저장 가능한 문자 범위를 확인한다. |
| JDBC 드라이버 버전 | Tibero 5 서버와 호환되는 JDBC 드라이버인지 확인한다. |
| JVM 인코딩 | file.encoding, 애플리케이션 서버 인코딩, 배치 실행 환경을 확인한다. |
| 입력 데이터 출처 | 파일, API, 화면, 타 DB 이관 등 문자열 생성 경로를 확인한다. |
| 문제 값 재현 | 실패한 row의 실제 문자열을 분리해 최소 재현 데이터를 만든다. |
다음으로 동일한 SQL에 정상 문자열과 실패 문자열을 각각 넣어 본다. SQL 구조가 같고 특정 데이터에서만 실패한다면 DB 오브젝트 문제보다는 입력 문자열 문제일 가능성이 높다.
심화 분석
JDBC-590743의 핵심은 “어떤 문자 또는 바이트가 변환되지 못했는가”를 찾는 것이다. Java의 String은 내부적으로 유니코드 문자열이지만, DB로 전달되는 과정에서는 JDBC 드라이버와 서버 문자셋 사이에서 변환이 발생한다.
따라서 애플리케이션에서 보이는 문자열이 정상처럼 보여도, 실제로는 잘못 디코딩된 문자나 DB 문자셋으로 표현할 수 없는 문자가 포함되어 있을 수 있다.
-- 문제가 되는 값을 작게 나누어 재현
insert into sample_table (memo) values ('정상 한글');
insert into sample_table (memo) values ('특수문자 테스트');
insert into sample_table (memo) values ('문제 의심 문자열을 여기 넣고 확인');
Java 쪽에서는 실패한 문자열의 코드 포인트를 출력해 문제 문자를 찾을 수 있다.
String value = inputText;
value.codePoints().forEach(cp -> {
System.out.printf("U+%04X : %s%n", cp, new String(Character.toChars(cp)));
});
특히 다음 문자가 포함되어 있으면 우선 의심해 볼 수 있다.
- 이모지 또는 4바이트 유니코드 문자
- 일부 확장 한자 또는 특수 기호
- 워드 문서나 웹에서 복사한 스마트 따옴표
- 눈에 보이지 않는 제어 문자
- 비정상 surrogate pair가 포함된 문자열
- UTF-8 파일을 EUC-KR로 잘못 읽어 생성된 깨진 문자열
같은 테이블, 같은 컬럼, 같은 SQL이라도 입력값 하나 때문에 재현 여부가 달라질 수 있다.
그래서 실패 row를 확보하고 문제 문자를 찾는 과정이 가장 중요하다.
복구
복구 방향은 크게 세 가지다. 첫째, 입력값에서 DB 문자셋으로 저장할 수 없는 문자를 제거하거나 대체한다. 둘째, 파일이나 외부 연동 데이터의 인코딩을 올바르게 읽도록 수정한다. 셋째, 장기적으로 DB 문자셋 정책을 UTF-8 기반으로 전환할 수 있는지 검토한다.
| 상황 | 조치 방향 |
|---|---|
| 특정 특수문자만 실패 | 문제 문자를 제거하거나 허용 가능한 문자로 치환한다. |
| 파일 업로드 후 실패 | 파일의 실제 인코딩과 Java에서 읽는 인코딩을 일치시킨다. |
| 외부 API 데이터 실패 | 수신 데이터의 charset 헤더와 실제 바이트 인코딩을 확인한다. |
| 이관 데이터에서 반복 발생 | 이관 전 문자 정제 절차를 추가하고 실패 row를 별도 적재한다. |
| 이모지 저장 필요 | 현재 DB 문자셋에서 지원 가능한지 확인하고 UTF-8 전환을 검토한다. |
Java에서 파일을 읽는 경우에는 기본 인코딩에 의존하지 말고 명시적으로 인코딩을 지정하는 것이 좋다.
-- 잘못된 접근 예시
-- 실행 OS나 JVM 옵션에 따라 기본 인코딩이 달라질 수 있다.
new InputStreamReader(inputStream);
-- 명시적 인코딩 지정 예시
new InputStreamReader(inputStream, StandardCharsets.UTF_8);
다만 DB 문자셋이 MSWIN949 계열인데 애플리케이션에서 UTF-8로 정상 처리한 문자열을 전달하더라도, 해당 문자가 MSWIN949로 표현 불가능하다면 여전히 실패할 수 있다. 이 경우에는 애플리케이션에서 사전 필터링을 해야 한다.
Charset targetCharset = Charset.forName("MS949");
CharsetEncoder encoder = targetCharset.newEncoder();
if (!encoder.canEncode(inputText)) {
throw new IllegalArgumentException("DB 문자셋으로 저장할 수 없는 문자가 포함되어 있습니다.");
}
JDBC 드라이버와 서버 버전 확인
Tibero 5 환경에서는 JDBC 드라이버 버전도 함께 확인해야 한다. 서버 버전과 맞지 않는 드라이버를 사용하거나, 오래된 드라이버에 문자셋 처리 관련 문제가 있는 경우 비슷한 증상이 발생할 수 있다.
-- 애플리케이션 배포 파일에서 확인할 항목
tibero5-jdbc.jar
tibero6-jdbc.jar
tbJDBC.jar
-- 점검 포인트
1. Tibero 5 서버에 맞는 JDBC 드라이버인지 확인
2. 운영 서버와 개발 서버의 JDBC jar가 동일한지 확인
3. WAS lib, 애플리케이션 lib에 중복 jar가 있는지 확인
4. 패치 권고 버전이 있는지 벤더 지원 채널로 확인
JDBC jar가 여러 경로에 중복 배치되어 있으면 개발자가 의도한 드라이버가 아니라 다른 버전의 드라이버가 로딩될 수 있다. 이 경우 로컬에서는 정상인데 운영에서만 오류가 나는 현상이 나타날 수 있다.
재발 방지
문자셋 오류는 한 번 수정해도 데이터 유입 경로가 여러 개라면 반복될 수 있다. 따라서 단순히 문제가 된 문자열 하나를 고치는 데서 끝내지 말고, 입력 단계에서 검증하는 구조를 추가하는 것이 좋다.
- DB 문자셋을 기준으로 저장 가능한 문자 범위를 문서화한다.
- 사용자 입력, 파일 업로드, API 수신 구간에 문자 검증 로직을 둔다.
- 배치 프로그램은 파일 인코딩을 명시적으로 지정한다.
- 실패 row는 버리지 말고 별도 로그 테이블이나 파일로 분리한다.
- JDBC 드라이버 버전을 서버 버전과 맞춰 관리한다.
- 운영과 개발 환경의 JVM 옵션, WAS 인코딩, JDBC jar 경로를 동일하게 맞춘다.
특히 Tibero 5처럼 오래된 운영 시스템에서는 UTF-8 데이터가 외부에서 유입되는 경로가 늘어나면서 문자셋 변환 오류가 뒤늦게 드러나는 경우가 많다.
정리
Tibero 5에서 INSERT 시 발생하는 JDBC-590743: Character set conversion failed: invalid input 오류는 대체로 SQL 문법 문제가 아니라 문자셋 변환 실패 문제로 접근해야 한다.
우선 DB의 NLS_CHARACTERSET을 확인하고, JDBC 드라이버 버전과 애플리케이션 입력 데이터의 실제 인코딩을 점검해야 한다. 이후 실패한 문자열을 최소 단위로 재현해 DB 문자셋으로 표현할 수 없는 문자를 찾는 것이 핵심이다.
단기적으로는 문제 문자를 제거하거나 치환하고, 파일·API·배치 입력 구간의 인코딩을 명확히 지정해야 한다. 장기적으로 이모지나 다양한 유니코드 문자를 저장해야 하는 업무라면 DB 문자셋 정책 자체를 재검토하는 것이 필요하다.
'지식 공유 > DBMS' 카테고리의 다른 글
| PostgreSQL VACUUM FULL 후 relfrozenxid age가 1로 줄어드는 이유 (0) | 2026.07.02 |
|---|---|
| oracle to postgresql ORA-00943 오류, Oracle 테이블 대소문자와 스키마 확인 방법 (0) | 2026.06.28 |
| PostgreSQL invalid page in block 오류 원인과 복구 대응 방법 (0) | 2026.06.28 |
| PostgreSQL archive_mode on과 always 차이, 운영 환경별 선택 기준 (0) | 2026.06.28 |
| 오라클 테이블 Block Corrupt로 인한 백업 실패 조치 정리 (0) | 2026.06.24 |
