PostgreSQL HV021 오류 원인과 해결 방법 완벽 가이드

HV021
2026년 07월 23일 | DBMS Error 가이드

이 글에서 다루는 내용

HV021 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

HV021 fdw inconsistent descriptor information 는?

PostgreSQL에서 HV021 에러는 Foreign Data Wrapper(FDW) 가 원격 서버의 테이블 또는 뷰의 컬럼 정보(descriptor)를 로컬 정의와 비교했을 때 불일치가 발생할 때 나타납니다. 즉, 로컬 PostgreSQL 인스턴스의 외부 테이블(Foreign Table) 스키마 정의와 실제 원격 데이터 소스의 스키마가 서로 맞지 않는 상황에서 발생합니다. 이 에러는 주로 원격 테이블의 구조가 변경되었음에도 불구하고 로컬의 Foreign Table 정의가 갱신되지 않았을 때, 혹은 FDW 드라이버가 메타데이터를 올바르게 전달하지 못했을 때 발생합니다.


주요 발생 원인

  • 원격 테이블 스키마 변경 후 Foreign Table 미갱신

가장 빈번하게 발생하는 원인입니다. 원격 PostgreSQL, MySQL, Oracle 등의 데이터베이스에서 컬럼이 추가되거나 삭제되거나 데이터 타입이 변경된 경우, 로컬의 Foreign Table 정의는 자동으로 동기화되지 않습니다. 이 불일치 상태에서 FDW가 쿼리를 실행하려 하면 descriptor 정보가 맞지 않아 HV021 에러가 발생합니다.

  • FDW 드라이버 버전 불일치 또는 버그

사용 중인 FDW 확장(예: postgres_fdw, mysql_fdw, oracle_fdw 등)의 버전이 PostgreSQL 서버 버전과 호환되지 않거나, 특정 버전에서 알려진 버그가 있을 경우 컬럼 descriptor를 잘못 해석할 수 있습니다. 특히 메이저 버전 업그레이드 후 FDW 확장을 재컴파일하지 않았거나 업데이트하지 않은 경우 이 문제가 자주 나타납니다.

  • Foreign Table 컬럼 순서 또는 데이터 타입 불일치

로컬 Foreign Table을 수동으로 정의할 때 컬럼 순서나 데이터 타입을 원격 테이블과 다르게 지정한 경우에도 이 에러가 발생합니다. PostgreSQL FDW는 컬럼 이름뿐만 아니라 순서와 타입에도 민감하게 반응하기 때문에, 단순한 순서 오류만으로도 descriptor 불일치가 유발될 수 있습니다.


해결 방법

원인 1: Foreign Table 재정의 (스키마 재동기화)

원격 테이블의 스키마 변경 이후 로컬 Foreign Table을 삭제하고 다시 생성하는 것이 가장 확실한 방법입니다.

-- 기존 Foreign Table 삭제
DROP FOREIGN TABLE IF EXISTS public.remote_orders;

-- 원격 테이블 스키마에 맞게 재생성
CREATE FOREIGN TABLE public.remote_orders (
    order_id    BIGINT NOT NULL,
    customer_id BIGINT NOT NULL,
    order_date  TIMESTAMP WITHOUT TIME ZONE,
    status      VARCHAR(50),
    total_amount NUMERIC(15, 2)
)
SERVER remote_pg_server
OPTIONS (schema_name 'public', table_name 'orders');

postgres_fdw를 사용하는 경우, IMPORT FOREIGN SCHEMA를 활용하면 원격 스키마를 자동으로 가져올 수 있어 수동 오류를 줄일 수 있습니다.

-- 기존 Foreign Table을 포함한 스키마 정리
DROP SCHEMA IF EXISTS remote_schema CASCADE;
CREATE SCHEMA remote_schema;

-- 원격 스키마 자동 임포트 (postgres_fdw 전용)
IMPORT FOREIGN SCHEMA public
    LIMIT TO (orders, customers, products)
    FROM SERVER remote_pg_server
    INTO remote_schema;

-- 임포트된 테이블 확인
SELECT foreign_table_name, column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'remote_schema'
ORDER BY foreign_table_name, ordinal_position;

원인 2: FDW 확장 업데이트 및 재설치

FDW 확장 버전을 확인하고 최신 버전으로 업데이트합니다.

-- 현재 설치된 확장 버전 확인
SELECT name, default_version, installed_version
FROM pg_available_extensions
WHERE name IN ('postgres_fdw', 'mysql_fdw', 'oracle_fdw', 'file_fdw');

-- 확장 업데이트 (가능한 경우)
ALTER EXTENSION postgres_fdw UPDATE;

-- 확장 재설치가 필요한 경우
DROP EXTENSION postgres_fdw CASCADE;
CREATE EXTENSION postgres_fdw;

-- Foreign Server 재생성 예시
CREATE SERVER remote_pg_server
    FOREIGN DATA WRAPPER postgres_fdw
    OPTIONS (host 'remote-db.example.com', port '5432', dbname 'production');

-- User Mapping 재생성
CREATE USER MAPPING FOR current_user
    SERVER remote_pg_server
    OPTIONS (user 'fdw_user', password 'secure_password');

원인 3: 컬럼 정의 검증 및 수정

원격 테이블의 실제 컬럼 순서와 타입을 확인하고 로컬 정의와 비교합니다.

-- 원격 서버에서 실제 컬럼 정보 조회 (postgres_fdw 사용 시)
SELECT attname AS column_name,
       atttypid::regtype AS data_type,
       attnum AS column_order
FROM pg_attribute
WHERE attrelid = 'remote_schema.remote_orders'::regclass
  AND attnum > 0
  AND NOT attisdropped
ORDER BY attnum;

-- 로컬 Foreign Table 정의 확인
SELECT column_name, data_type, ordinal_position, udt_name
FROM information_schema.columns
WHERE table_schema = 'public'
  AND table_name = 'remote_orders'
ORDER BY ordinal_position;

-- 컬럼 타입이 불일치하는 경우 ALTER로 수정
ALTER FOREIGN TABLE public.remote_orders
    ALTER COLUMN total_amount TYPE NUMERIC(18, 4);

-- 누락된 컬럼 추가
ALTER FOREIGN TABLE public.remote_orders
    ADD COLUMN discount_rate NUMERIC(5, 2) OPTIONS (column_name 'discount_rate');

연결 테스트 및 디버깅

-- FDW 연결 상태 및 옵션 확인
SELECT srvname, srvtype, srvversion, srvoptions
FROM pg_foreign_server;

-- Foreign Table 옵션 확인
SELECT foreign_table_schema, foreign_table_name, ftoptions
FROM information_schema.foreign_tables;

-- 간단한 연결 테스트 쿼리 (LIMIT 1로 부하 최소화)
EXPLAIN (VERBOSE, ANALYZE) 
SELECT * FROM public.remote_orders LIMIT 1;

예방 방법

  • 원격 스키마 변경 시 자동 감지 및 알림 체계 구축

원격 데이터베이스의 DDL 변경이 발생하면 로컬 Foreign Table 정의도 반드시 함께 업데이트해야 합니다. 이를 위해 원격 서버에 DDL 감사 트리거를 설정하거나, CI/CD 파이프라인에 Foreign Table 스키마 검증 스텝을 포함시키는 것이 좋습니다. 아래와 같은 모니터링 쿼리를 정기적으로 실행하여 불일치를 사전에 감지하세요.

“`sql

— 정기 점검용: Foreign Table과 원격 테이블의 컬럼 수 비교 뷰 생성

CREATE OR REPLACE VIEW admin.fdw_schema_health_check AS

SELECT

ft.foreign_table_schema AS local_schema,

ft.foreign_table_name AS local_table,

COUNT(c.column_name) AS local_column_count,

ft.ftoptions AS remote_options

FROM information_schema.foreign_tables ft

JOIN information_schema.columns c

ON c.table_schema = ft.foreign_table_schema

AND c.table_name = ft.foreign_table_name

GROUP BY ft.foreign_table_schema, ft.foreign_table_name, ft.ftoptions

ORDER BY ft.foreign_table_schema, ft.foreign_table_name;

“`

  • IMPORT FOREIGN SCHEMA 사용 자동화 및 주기적 재동기화

수동으로 Foreign Table을 정의하는 대신 IMPORT FOREIGN SCHEMA를 활용하면 스키마 불일치 가능성을 대폭 줄일 수 있습니다. 이 명령을 정기적인 배치 작업(cron job, pg_cron 등)으로 스케줄링하여 원격 스키마 변경 사항을 자동으로 반영하세요.

“`sql

— pg_cron을 활용한 주기적 스키마 재동기화 예시

SELECT cron.schedule(

‘fdw-schema-sync’,

‘0 2 *’, — 매일 새벽 2시 실행

$$

DROP SCHEMA IF EXISTS remote_schema CASCADE;

CREATE SCHEMA remote_schema;

IMPORT FOREIGN SCHEMA public

FROM SERVER remote_pg_server

INTO remote_schema;

$$

);

“`


관련 에러

  • HV000 (fdw_error): FDW 관련 일반 오류. HV021이 특정 descriptor 불일치라면, HV000은 FDW 전반의 포괄적 에러입니다.
  • HV005 (fdw_column_name_not_found): Foreign Table의 컬럼 이름이 원격 소스에서 찾을 수 없을 때 발생하며, HV021과 함께 나타나는 경우가 많습니다.
  • HV002 (fdw_dynamic_parameter_value_needed): FDW 쿼리 실행 시 필요한 파라미터 값이 누락된 경우 발생합니다.
  • 08006 (connection_failure): FDW가 원격 서버에 연결 자체를 실패할 때 발생하며, descriptor 오류 전에 선행될 수 있습니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기