2026년 08월 12일 | DBMS Error 가이드
이 글에서 다루는 내용
2200D 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
2200D invalid escape octet 는?
PostgreSQL 에러 코드 2200D: invalid escape octet는 바이트 문자열(bytea) 또는 문자열 처리 과정에서 유효하지 않은 이스케이프 시퀀스를 포함한 옥텟(octet, 8비트 바이트) 값이 입력될 때 발생하는 에러입니다. 이 에러는 주로 LIKE 패턴 매칭, 정규 표현식, 또는 bytea 타입의 데이터를 삽입하거나 변환할 때 잘못된 이스케이프 문자가 사용된 경우에 발생합니다. 특히 레거시 시스템에서 마이그레이션하거나 외부 애플리케이션에서 원시 바이트 데이터를 PostgreSQL로 전송할 때 자주 마주치게 됩니다.
주요 발생 원인
1. bytea 타입에 잘못된 이스케이프 시퀀스 사용
bytea 데이터 타입은 이진 데이터를 저장하는 PostgreSQL 전용 타입으로, 이스케이프 표기법을 통해 바이트 값을 표현합니다. 전통적인 escape 형식에서는 \NNN(8진수) 또는 \\(백슬래시 자체)만 유효한 이스케이프 시퀀스이며, 그 외의 형식을 사용하면 2200D 에러가 발생합니다. 예를 들어 \x와 같이 헥사 표기를 escape 모드에서 사용하거나, 범위를 벗어난 8진수 값을 지정하면 이 에러가 트리거됩니다.
2. LIKE 또는 SIMILAR TO 패턴에서 잘못된 이스케이프 문자 지정
LIKE 연산자의 ESCAPE 절이나 SIMILAR TO에서 이스케이프 문자로 다중 바이트 문자 또는 유효하지 않은 옥텟 값을 지정할 때 이 에러가 발생할 수 있습니다. PostgreSQL은 이스케이프 문자로 정확히 하나의 유효한 문자를 요구하며, 이를 위반하면 파싱 단계에서 에러를 반환합니다. 특히 멀티바이트 인코딩 환경(UTF-8)에서 단일 바이트로 표현할 수 없는 문자를 이스케이프로 지정하려 할 때 문제가 됩니다.
3. 클라이언트 인코딩 불일치로 인한 잘못된 바이트 전송
애플리케이션 서버와 PostgreSQL 서버 간의 클라이언트 인코딩 설정이 맞지 않을 경우, 바이트 스트림이 PostgreSQL 파서에서 유효하지 않은 이스케이프 시퀀스로 해석될 수 있습니다. 예를 들어 애플리케이션이 Latin-1 인코딩으로 데이터를 전송하지만 PostgreSQL은 UTF-8로 해석하려 할 때, 특정 바이트 조합이 잘못된 이스케이프로 처리될 수 있습니다. 이는 마이그레이션 작업이나 다국어 지원 시스템에서 특히 빈번하게 나타납니다.
해결 방법
원인 1 해결: bytea 이스케이프 형식 수정
bytea_output 설정을 확인하고, 올바른 이스케이프 형식을 사용합니다. PostgreSQL 9.0 이후부터는 hex 형식이 기본값으로 권장됩니다.
-- 현재 bytea_output 설정 확인
SHOW bytea_output;
-- 잘못된 예: escape 모드에서 hex 표기 사용 (에러 발생)
-- SELECT E'\\xDEADBEEF'::bytea; -- 이렇게 하면 안 됨
-- 올바른 예 1: hex 형식 사용 (권장)
SELECT '\xDEADBEEF'::bytea;
-- 올바른 예 2: escape 형식에서 유효한 8진수 사용
SELECT E'\\001\\002\\003'::bytea;
-- 올바른 예 3: hex 형식으로 bytea 삽입
INSERT INTO binary_data (data_col)
VALUES ('\xCAFEBABE'::bytea);
-- 세션 레벨에서 bytea_output 설정 변경
SET bytea_output = 'hex';
-- 기존 escape 형식 데이터를 hex 형식으로 변환
SELECT encode(data_col, 'hex') FROM binary_data;
SELECT decode('DEADBEEF', 'hex')::bytea;
원인 2 해결: LIKE 패턴 이스케이프 문자 수정
LIKE 쿼리에서 이스케이프 문자를 올바르게 지정하거나 기본값을 사용합니다.
-- 잘못된 예: 다중 바이트 문자를 이스케이프로 지정
-- SELECT * FROM products WHERE name LIKE '%50!%%' ESCAPE '한'; -- 에러
-- 올바른 예: 단일 ASCII 문자를 이스케이프로 사용
SELECT * FROM products
WHERE name LIKE '%50!%%' ESCAPE '!';
-- 올바른 예: 기본 이스케이프 문자(\) 활용
SELECT * FROM products
WHERE name LIKE '%100\%%';
-- 퍼센트와 언더스코어를 리터럴로 검색하는 안전한 방법
SELECT * FROM products
WHERE name LIKE '%30\% off%' ESCAPE '\';
-- SIMILAR TO에서 올바른 이스케이프 사용
SELECT * FROM logs
WHERE message SIMILAR TO '%(error|warn)%' ESCAPE '!';
-- 이스케이프 없이 position 함수로 대체 (더 안전)
SELECT * FROM products
WHERE POSITION('%' IN name) > 0;
원인 3 해결: 클라이언트 인코딩 일치 확인
-- 현재 서버 인코딩 확인
SHOW server_encoding;
-- 현재 클라이언트 인코딩 확인
SHOW client_encoding;
-- 클라이언트 인코딩을 서버와 일치시키기
SET client_encoding = 'UTF8';
-- 데이터베이스별 인코딩 확인
SELECT datname, pg_encoding_to_char(encoding) AS encoding
FROM pg_database
WHERE datname = current_database();
-- 인코딩 문제가 있는 bytea 데이터 안전하게 변환
SELECT convert_from(
decode(encode(problem_col::text::bytea, 'hex'), 'hex'),
'LATIN1'
) FROM legacy_table;
-- 안전한 bytea 삽입을 위해 encode/decode 함수 활용
INSERT INTO safe_binary (data)
SELECT decode(encode(raw_data, 'base64'), 'base64')
FROM staging_table;
예방 방법
1. bytea 처리 시 항상 hex 형식과 encode/decode 함수 사용
신규 개발 시 bytea 데이터 처리에는 반드시 hex 형식을 기본으로 사용하고, 직접 이스케이프 시퀀스를 문자열로 조합하지 않는 방식을 코딩 표준으로 삼으세요. PostgreSQL의 encode(), decode() 함수를 활용하면 이스케이프 관련 에러를 원천적으로 방지할 수 있습니다. 또한 postgresql.conf 또는 ALTER DATABASE 명령으로 bytea_output = 'hex'를 전역으로 설정해 두면 애플리케이션 전체에서 일관성을 유지할 수 있습니다.
-- 데이터베이스 레벨에서 hex 형식 강제 설정
ALTER DATABASE mydb SET bytea_output = 'hex';
-- 애플리케이션에서 파라미터 바인딩 사용 (psycopg2 예시 주석)
-- cursor.execute("INSERT INTO t (b) VALUES (%s)", (psycopg2.Binary(data),))
2. LIKE 패턴 매칭 시 파라미터 바인딩과 입력값 검증 적용
사용자 입력을 직접 LIKE 패턴에 삽입하지 말고, 항상 ORM 또는 드라이버 레벨의 파라미터 바인딩을 사용하세요. 애플리케이션 레이어에서 이스케이프 문자 처리를 표준화하고, 정규식 기반의 입력값 검증으로 유효하지 않은 바이트 시퀀스가 쿼리에 포함되지 않도록 방어 코드를 작성해야 합니다.
-- 입력값의 특수문자를 미리 이스케이프 처리하는 함수 예시
CREATE OR REPLACE FUNCTION escape_like(text) RETURNS text AS $$
SELECT replace(replace(replace($1, '\', '\\'), '%', '\%'), '_', '\_');
$$ LANGUAGE SQL IMMUTABLE STRICT;
-- 사용 예
SELECT * FROM products
WHERE name LIKE '%' || escape_like(user_input) || '%';
관련 에러
- 22025
invalid_escape_sequence:LIKE패턴에서 이스케이프 시퀀스 자체가 잘못된 경우 발생하며,2200D와 유사하지만 대상이 옥텟(바이트)이 아닌 문자 시퀀스입니다. - 22021
character_not_in_repertoire: 지정된 인코딩에서 표현할 수 없는 문자를 삽입하려 할 때 발생합니다. - 22P05
untranslatable_character: 클라이언트 인코딩과 서버 인코딩 간 변환이 불가능한 문자가 있을 때 나타나며, 인코딩 불일치 시나리오에서2200D와 함께 등장할 수 있습니다. - 22000
data_exception: 위 에러들의 상위 카테고리로, 데이터 처리 전반에서 발생하는 예외를 포괄합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.