2026년 06월 15일 | DBMS Error 가이드
이 글에서 다루는 내용
22P05 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
22P05 untranslatable character 는?
PostgreSQL 에러 코드 22P05 (untranslatable character)는 데이터베이스 서버가 특정 문자를 현재 설정된 클라이언트 인코딩 또는 서버 인코딩으로 변환할 수 없을 때 발생합니다. 쉽게 말해, 입력된 문자열 안에 현재 인코딩 체계에서 표현이 불가능한 문자가 포함되어 있다는 의미입니다. 예를 들어 데이터베이스가 LATIN1 인코딩으로 설정되어 있는데, UTF-8 기반의 한글, 이모지, 또는 특수 유니코드 문자를 저장하려 할 때 이 에러가 빈번하게 발생합니다.
주요 발생 원인
- 서버 인코딩과 클라이언트 인코딩 불일치
가장 흔한 원인입니다. 데이터베이스 서버가 LATIN1 혹은 SQL_ASCII로 설정되어 있는 상태에서, 애플리케이션이나 클라이언트가 UTF-8 문자(한글, 중국어, 이모지 등)를 전송할 경우 PostgreSQL은 해당 문자를 서버 인코딩으로 변환하지 못합니다. 이 불일치는 레거시 시스템에서 신규 애플리케이션을 연결하거나, 마이그레이션 작업 중에 특히 자주 나타납니다.
- 데이터 마이그레이션 또는 ETL 과정에서의 인코딩 오염
외부 시스템(Oracle, MySQL, CSV 파일 등)에서 데이터를 가져올 때 원본 데이터의 인코딩이 명확하지 않거나 혼합되어 있는 경우가 많습니다. 예를 들어 EUC-KR로 저장된 파일을 UTF-8로 처리하거나, Windows-1252 인코딩의 특수문자가 포함된 CSV를 COPY 명령으로 적재할 때 이 에러가 발생합니다. 이런 경우 데이터 자체를 정제하거나 변환하지 않으면 반복적으로 에러가 재현됩니다.
SQL_ASCII인코딩 데이터베이스에 멀티바이트 문자 삽입 시도
SQL_ASCII는 PostgreSQL에서 인코딩 변환을 수행하지 않는 특수 설정으로, 실질적으로 어떤 바이트도 허용하지만 변환 자체는 거부합니다. 클라이언트가 UTF-8로 연결하고 SQL_ASCII 데이터베이스에 멀티바이트 문자를 삽입하려 하면, 서버는 변환 불가 에러를 발생시킵니다. 이 설정은 레거시 시스템 호환성을 위해 사용되는 경우가 많아, 신규 개발자가 원인을 파악하기 어려운 경우가 많습니다.
해결 방법
원인 1 해결: 인코딩 확인 및 클라이언트 인코딩 명시적 설정
먼저 현재 데이터베이스와 세션 인코딩을 확인합니다.
-- 데이터베이스 인코딩 확인
SELECT datname, pg_encoding_to_char(encoding) AS encoding
FROM pg_database
WHERE datname = current_database();
-- 현재 세션의 클라이언트 인코딩 확인
SHOW client_encoding;
-- 클라이언트 인코딩을 UTF-8로 명시적 설정
SET client_encoding = 'UTF8';
-- 또는 연결 시 파라미터로 지정 (psql 예시)
-- psql "host=localhost dbname=mydb user=myuser options='-c client_encoding=UTF8'"
만약 데이터베이스 자체의 인코딩을 변경해야 한다면, 새 데이터베이스를 생성해야 합니다 (인코딩은 생성 후 변경 불가).
-- UTF-8 인코딩으로 새 데이터베이스 생성
CREATE DATABASE mydb_utf8
ENCODING 'UTF8'
LC_COLLATE = 'ko_KR.UTF-8'
LC_CTYPE = 'ko_KR.UTF-8'
TEMPLATE = template0;
원인 2 해결: 마이그레이션 시 인코딩 변환 처리
ETL 또는 COPY 작업 시 인코딩을 명시하고, 문제 문자를 사전에 필터링합니다.
-- COPY 명령 시 인코딩 명시
COPY my_table (col1, col2)
FROM '/data/import.csv'
WITH (FORMAT csv, HEADER true, ENCODING 'UTF8');
-- 특정 인코딩 변환 함수를 사용한 데이터 정제
-- convert_from: 바이트 배열을 지정 인코딩으로 해석하여 텍스트로 변환
SELECT convert_from(
'\xc7\xd1\xb1\xdb'::bytea, -- EUC-KR 바이트
'EUC_KR'
) AS converted_text;
-- 변환 불가 문자를 포함한 행 탐색 (regexp로 비ASCII 문자 감지)
SELECT id, content
FROM my_table
WHERE content ~ '[^\x00-\x7F]' -- 비ASCII 문자 포함 행 찾기
AND length(content) != octet_length(content); -- 멀티바이트 문자 감지
원인 3 해결: SQL_ASCII 데이터베이스 대응
SQL_ASCII 환경에서는 클라이언트 인코딩을 SQL_ASCII로 맞추거나, 장기적으로 UTF-8 데이터베이스로 마이그레이션하는 것이 바람직합니다.
-- 임시 방편: 클라이언트 인코딩을 SQL_ASCII로 맞춤 (권장하지 않음)
SET client_encoding = 'SQL_ASCII';
-- 문제 있는 문자열에서 비ASCII 문자 제거 (데이터 정제용)
UPDATE my_table
SET content = regexp_replace(content, '[^\x00-\x7F]', '', 'g')
WHERE content ~ '[^\x00-\x7F]';
-- UTF-8로 마이그레이션을 위한 데이터 덤프 (인코딩 명시)
-- pg_dump -h localhost -U myuser -d mydb --encoding=UTF8 -f mydb_utf8.sql
-- 변환 가능 여부 사전 테스트
DO $$
BEGIN
PERFORM convert('한글 테스트'::bytea, 'UTF8', 'LATIN1');
RAISE NOTICE '변환 성공';
EXCEPTION WHEN untranslatable_character THEN
RAISE NOTICE '변환 불가 문자 감지됨: %', SQLERRM;
END;
$$;
예방 방법
- 데이터베이스 생성 시 처음부터 UTF-8 인코딩 표준화
모든 신규 데이터베이스는 반드시 UTF-8 인코딩으로 생성하는 것을 조직 내 표준으로 정립하세요. UTF-8은 전 세계 모든 언어와 이모지를 포함한 유니코드 문자를 지원하므로, 인코딩 관련 에러의 90% 이상을 예방할 수 있습니다. 애플리케이션 연결 설정에도 client_encoding=UTF8을 명시적으로 지정하여 세션마다 인코딩이 보장되도록 하세요.
- 데이터 입력 전 인코딩 유효성 검증 로직 구현
외부 데이터를 수신하거나 사용자 입력을 처리하는 모든 지점에서 인코딩 검증을 선행하세요. 애플리케이션 레벨에서 Python의 chardet, Java의 juniversalchardet 같은 라이브러리로 인코딩을 감지하고 UTF-8로 변환한 뒤 데이터베이스에 적재하는 파이프라인을 구축하는 것이 이상적입니다. 또한 PostgreSQL의 pg_verifybackup, check_function_bodies 등과 함께 정기적인 데이터 품질 점검을 스케줄링하는 것을 권장합니다.
관련 에러
- 22021 (character_not_in_repertoire): 현재 인코딩의 문자 레퍼토리에 없는 문자를 사용했을 때 발생하며, 22P05와 유사하지만 변환 단계가 아닌 문자 집합 검증 단계에서 발생한다는 차이가 있습니다.
- 22000 (data_exception): 인코딩 관련 데이터 예외의 상위 카테고리로, 22P05는 이 카테고리 하위에 속합니다.
- 42601 (syntax_error): 인코딩 오류로 인해 SQL 파서가 문자열을 올바르게 해석하지 못할 경우 간접적으로 발생할 수 있습니다.
- 08P01 (protocol_violation): 클라이언트-서버 간 인코딩 협상이 프로토콜 수준에서 실패했을 때 나타날 수 있으며, 인코딩 관련 연결 문제 진단 시 함께 확인해야 합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.