2026년 09월 27일 | DBMS Error 가이드
이 글에서 다루는 내용
HV004 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
HV004 fdw invalid data type 는?
PostgreSQL 에러 코드 HV004 (fdw_invalid_data_type)는 Foreign Data Wrapper(FDW)를 통해 외부 데이터 소스에 접근할 때, 외부 테이블의 컬럼 데이터 타입이 PostgreSQL 내부적으로 처리할 수 없거나 FDW 드라이버가 지원하지 않는 타입일 경우 발생하는 에러입니다. 주로 외부 서버(Oracle, MySQL, MongoDB, CSV 파일 등)의 데이터 타입과 PostgreSQL의 데이터 타입 간의 매핑이 올바르지 않을 때 나타납니다. 이 에러는 CREATE FOREIGN TABLE 구문 작성 시점 또는 실제 쿼리 실행 시점 모두에서 발생할 수 있어 운영 환경에서 매우 주의가 필요합니다.
주요 발생 원인
1. 외부 테이블 정의 시 지원되지 않는 데이터 타입 사용
FDW 드라이버(예: oracle_fdw, mysql_fdw, file_fdw)는 PostgreSQL의 모든 데이터 타입을 지원하지 않습니다. 예를 들어 Oracle의 NUMBER(38,10) 타입이나 MySQL의 ENUM 타입을 별도의 변환 없이 그대로 PostgreSQL Foreign Table 컬럼 타입으로 정의하면 FDW 레이어에서 타입을 인식하지 못해 HV004 에러가 발생합니다. 특히 사용자 정의 타입(Custom Type)이나 도메인 타입(Domain Type)을 Foreign Table에 직접 사용하면 대부분의 FDW에서 이 에러가 발생합니다.
2. 원격 서버와 로컬 PostgreSQL 간의 데이터 타입 매핑 불일치
외부 데이터 소스의 컬럼 타입과 CREATE FOREIGN TABLE에서 선언한 PostgreSQL 타입이 서로 호환되지 않는 경우입니다. 예를 들어 MySQL 서버의 TINYINT(1) 컬럼을 PostgreSQL의 BOOLEAN으로 선언하거나, Oracle의 DATE 타입(날짜+시간 포함)을 PostgreSQL의 date(날짜만)로 선언하는 경우 FDW가 데이터를 변환하는 과정에서 타입 불일치를 감지하고 HV004를 발생시킵니다. 이 문제는 스키마 변경 후 FDW 테이블 정의를 갱신하지 않았을 때도 빈번하게 발생합니다.
3. FDW 확장 버전과 PostgreSQL 버전 간의 호환성 문제
FDW 드라이버 자체의 버전이 현재 PostgreSQL 버전에서 특정 데이터 타입을 올바르게 처리하지 못하는 경우입니다. PostgreSQL 메이저 업그레이드(예: 14 → 16) 이후 FDW 확장을 함께 업그레이드하지 않으면, 새로운 내장 타입(예: jsonb, uuid, pg_lsn)에 대한 처리 루틴이 없어 HV004가 발생할 수 있습니다. 오래된 postgres_fdw 또는 서드파티 FDW 버전을 그대로 사용하는 환경에서 특히 자주 목격됩니다.
해결 방법
원인 1 해결: 지원 가능한 기본 데이터 타입으로 변환
FDW가 지원하지 않는 타입 대신 호환 가능한 기본 타입을 사용하고, 필요하다면 뷰(View)나 함수로 변환 레이어를 추가합니다.
-- 문제가 되는 Foreign Table 정의 (사용자 정의 타입 사용 - 에러 발생)
CREATE FOREIGN TABLE orders_foreign (
order_id INTEGER,
status order_status_enum, -- 사용자 정의 타입 → HV004 발생
amount NUMERIC(38,10)
)
SERVER remote_mysql_server
OPTIONS (dbname 'shop', table_name 'orders');
-- 해결: TEXT 또는 기본 타입으로 대체
CREATE FOREIGN TABLE orders_foreign (
order_id INTEGER,
status TEXT, -- 사용자 정의 타입 대신 TEXT 사용
amount NUMERIC(15,4) -- 적절한 precision으로 조정
)
SERVER remote_mysql_server
OPTIONS (dbname 'shop', table_name 'orders');
-- 뷰를 통해 타입 캐스팅 처리
CREATE VIEW orders_view AS
SELECT
order_id,
status::order_status_enum AS status, -- 뷰 레벨에서 캐스팅
amount
FROM orders_foreign;
원인 2 해결: 타입 매핑 재검토 및 Foreign Table 재정의
원격 서버의 실제 타입과 로컬 정의를 정확히 맞추거나, 더 넓은 범위의 타입으로 선언합니다.
-- 기존 잘못된 Foreign Table 삭제
DROP FOREIGN TABLE IF EXISTS employees_foreign;
-- Oracle DATE 타입을 PostgreSQL TIMESTAMP로 올바르게 매핑
CREATE FOREIGN TABLE employees_foreign (
emp_id INTEGER,
emp_name VARCHAR(100),
hire_date TIMESTAMP, -- Oracle DATE는 시간 포함 → TIMESTAMP 사용
salary NUMERIC(10,2),
is_active SMALLINT -- MySQL TINYINT(1)은 SMALLINT로 매핑
)
SERVER oracle_remote_server
OPTIONS (schema 'HR', table 'EMPLOYEES');
-- 실제 데이터 접근 테스트
SELECT emp_id, emp_name, hire_date::DATE AS hire_date_only
FROM employees_foreign
WHERE is_active = 1
LIMIT 10;
-- 타입 호환성 확인 쿼리
SELECT
column_name,
data_type,
character_maximum_length,
numeric_precision
FROM information_schema.columns
WHERE table_name = 'employees_foreign'
ORDER BY ordinal_position;
원인 3 해결: FDW 확장 업그레이드 및 재설치
-- 현재 설치된 FDW 확장 버전 확인
SELECT name, default_version, installed_version
FROM pg_available_extensions
WHERE name LIKE '%fdw%';
-- FDW 확장 업그레이드
ALTER EXTENSION postgres_fdw UPDATE;
ALTER EXTENSION oracle_fdw UPDATE;
-- 업그레이드 후 버전 재확인
SELECT extname, extversion
FROM pg_extension
WHERE extname LIKE '%fdw%';
-- Foreign Server 연결 상태 확인
SELECT
fs.srvname AS server_name,
fs.srvtype AS server_type,
fs.srvversion AS server_version,
fw.fdwname AS fdw_name
FROM pg_foreign_server fs
JOIN pg_foreign_data_wrapper fw ON fs.srvfdw = fw.oid;
-- JSONB 타입 사용 시 postgres_fdw에서의 올바른 처리 예시
CREATE FOREIGN TABLE json_data_foreign (
id BIGINT,
payload TEXT, -- JSONB 대신 TEXT로 받아서 로컬에서 캐스팅
created_at TIMESTAMP WITH TIME ZONE
)
SERVER remote_pg_server
OPTIONS (schema_name 'public', table_name 'json_data');
-- 로컬에서 JSONB로 캐스팅하는 뷰 생성
CREATE OR REPLACE VIEW json_data_view AS
SELECT
id,
payload::JSONB AS payload,
created_at
FROM json_data_foreign;
예방 방법
1. Foreign Table 생성 전 타입 호환성 매트릭스 검증 프로세스 수립
FDW별로 지원하는 데이터 타입 목록을 사전에 문서화하고, CREATE FOREIGN TABLE 작성 전에 반드시 해당 FDW의 공식 문서에서 타입 매핑 표를 확인하는 절차를 팀 내 표준으로 정착시켜야 합니다. 아울러 아래와 같은 검증 스크립트를 CI/CD 파이프라인에 포함시켜 배포 전 자동으로 타입 호환성을 체크하는 체계를 구축하는 것이 실무에서 매우 효과적입니다.
-- Foreign Table 컬럼 타입 검증 쿼리 (배포 전 점검용)
SELECT
ft.foreign_table_name,
ft.column_name,
ft.data_type,
CASE
WHEN ft.data_type IN ('USER-DEFINED', 'ARRAY') THEN '⚠ FDW 비호환 가능성 있음'
WHEN ft.data_type = 'jsonb' THEN '⚠ FDW 버전 확인 필요'
ELSE '✓ 일반적으로 호환'
END AS compatibility_check
FROM information_schema.columns ft
WHERE ft.table_schema = 'public'
AND ft.table_name IN (
SELECT foreign_table_name
FROM information_schema.foreign_tables
)
ORDER BY ft.foreign_table_name, ft.ordinal_position;
2. 원격 서버 스키마 변경 시 Foreign Table 자동 동기화 모니터링 구축
원격 데이터베이스의 스키마가 변경되면 로컬의 Foreign Table 정의와 불일치가 발생하여 HV004를 비롯한 다양한 FDW 에러가 생깁니다. postgres_fdw의 경우 IMPORT FOREIGN SCHEMA 명령을 정기적으로 실행하여 원격 스키마와 동기화하는 배치 작업을 운영하고, 원격 서버의 DDL 변경 이벤트를 PostgreSQL의 이벤트 트리거나 외부 모니터링 도구(pgWatch, Datadog)로 감지하는 알림 체계를 갖추는 것이 필수입니다.
-- IMPORT FOREIGN SCHEMA로 원격 스키마 자동 동기화
IMPORT FOREIGN SCHEMA public
LIMIT TO (orders, customers, products)
FROM SERVER remote_pg_server
INTO local_fdw_schema;
관련 에러
- HV000 (fdw_error): FDW 관련 일반 에러의 최상위 코드로, HV004 발생 시 함께 로그에 기록되는 경우가 많습니다.
- HV005 (fdw_invalid_data_type_descriptors): 데이터 타입 자체가 아닌 타입 설명자(precision, scale, length 등)가 잘못된 경우 발생하며 HV004와 혼동하기 쉽습니다.
- HV021 (fdw_inconsistent_descriptor_information): 외부 테이블의 컬럼 수나 순서가 원격 테이블과 맞지 않을 때 발생하는 에러로, 스키마 변경 후 자주 동반됩니다.
- HV002 (fdw_dynamic_parameter_value_needed): FDW OPTIONS에 필수 파라미터 값이 누락되었을 때 발생하며, Foreign Table 재정의 시 함께 확인해야 합니다.
- 42804 (datatype_mismatch): FDW 레이어를 벗어나 PostgreSQL 엔진 레벨에서 타입 불일치가 감지될 때 발생하는 에러로, HV004와 유사한 상황에서 함께 나타날 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.