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

3D000
2026년 07월 02일 | DBMS Error 가이드

이 글에서 다루는 내용

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

3D000 invalid catalog name 는?

PostgreSQL 에러 코드 3D000 invalid_catalog_name은 클라이언트가 존재하지 않거나 잘못된 이름의 데이터베이스(카탈로그)에 접속을 시도할 때 발생하는 에러입니다. PostgreSQL에서 “카탈로그(catalog)”란 데이터베이스 자체를 의미하며, 접속 대상 데이터베이스 이름이 서버에 존재하지 않을 경우 연결 단계에서 즉시 이 에러가 발생합니다. 주로 애플리케이션의 데이터베이스 접속 설정 오류, 오타, 또는 데이터베이스가 삭제된 상황에서 자주 목격되는 에러입니다.


주요 발생 원인

1. 존재하지 않는 데이터베이스 이름으로 접속 시도

가장 흔한 원인으로, 접속하려는 데이터베이스 이름이 PostgreSQL 서버에 실제로 존재하지 않는 경우입니다. 오타나 대소문자 혼동(PostgreSQL 데이터베이스 이름은 기본적으로 소문자로 처리됨), 혹은 개발/스테이징/운영 환경 간의 설정 혼동으로 인해 발생할 수 있습니다. 예를 들어 myapp_prod에 접속해야 하는데 myApp_Prodmyapp-prod처럼 잘못된 이름을 사용하면 이 에러가 발생합니다.

2. 데이터베이스가 삭제되었거나 아직 생성되지 않은 상태

운영 중인 서비스에서 실수로 DROP DATABASE 명령이 실행되었거나, 새로운 환경 구성 시 데이터베이스 생성 스크립트가 실행되지 않은 경우에도 이 에러가 발생합니다. CI/CD 파이프라인 또는 마이그레이션 스크립트에서 데이터베이스 생성 단계가 누락되었을 때 특히 자주 발생하며, 애플리케이션 배포 직후 전체 서비스 장애로 이어질 수 있어 매우 위험한 상황입니다.

3. 애플리케이션 설정 파일 또는 환경 변수 오류

Spring Boot, Django, Rails 등 프레임워크의 데이터베이스 설정 파일(application.yml, settings.py, database.yml 등)이나 PGDATABASE 환경 변수에 잘못된 데이터베이스 이름이 지정된 경우입니다. 특히 컨테이너 환경(Docker, Kubernetes)에서는 환경 변수 주입 오류로 인해 빈 문자열이나 플레이스홀더 값이 그대로 전달되는 경우가 빈번하여, 실제 운영 환경에서 예기치 못한 장애를 유발하기도 합니다.


해결 방법

원인 1: 존재하는 데이터베이스 목록 확인

우선 현재 PostgreSQL 서버에 존재하는 데이터베이스 목록을 확인합니다.

-- psql 메타 명령어로 데이터베이스 목록 확인
\l

-- 또는 SQL 쿼리로 직접 확인
SELECT datname, datdba, encoding, datcollate, datctype
FROM pg_database
WHERE datistemplate = false
ORDER BY datname;

접속하려는 데이터베이스 이름이 목록에 없다면, 이름 오타 여부를 확인하거나 아래와 같이 데이터베이스를 새로 생성합니다.

-- 데이터베이스 생성 (존재하지 않을 경우)
CREATE DATABASE myapp_prod
    WITH OWNER = myapp_user
    ENCODING = 'UTF8'
    LC_COLLATE = 'ko_KR.UTF-8'
    LC_CTYPE = 'ko_KR.UTF-8'
    TEMPLATE = template0;

-- 생성 확인
SELECT datname FROM pg_database WHERE datname = 'myapp_prod';

원인 2: 삭제된 데이터베이스 복구 또는 재생성

데이터베이스가 실수로 삭제된 경우, 백업에서 복구하는 것이 최우선입니다.

-- pg_dump로 생성된 백업 파일로 복구 (shell 명령어)
-- createdb myapp_prod
-- pg_restore -d myapp_prod -U postgres /backup/myapp_prod_backup.dump

-- 복구 후 데이터베이스 존재 여부 확인
SELECT datname, pg_size_pretty(pg_database_size(datname)) AS size
FROM pg_database
WHERE datname = 'myapp_prod';

-- 만약 백업이 없고 재생성이 필요한 경우
CREATE DATABASE myapp_prod OWNER myapp_user;

-- 필요한 익스텐션 재설치
\c myapp_prod
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgcrypto";

원인 3: 환경 변수 및 설정 파일 검증

접속 전에 환경 변수와 설정값을 검증하는 방법입니다.

-- psql에서 현재 접속 정보 확인
SELECT current_database(), current_user, version();

-- 접속 시도 전 데이터베이스 존재 여부를 확인하는 함수 생성
-- (관리용 postgres DB에서 실행)
CREATE OR REPLACE FUNCTION check_database_exists(db_name TEXT)
RETURNS BOOLEAN AS $$
BEGIN
    RETURN EXISTS (
        SELECT 1 FROM pg_database WHERE datname = db_name
    );
END;
$$ LANGUAGE plpgsql;

-- 사용 예시
SELECT check_database_exists('myapp_prod');
-- 결과: t (true) 또는 f (false)
-- 접속 문자열(DSN) 형식 확인
-- 올바른 형식: postgresql://username:password@host:port/database_name
-- 잘못된 예: postgresql://user:pass@localhost:5432/  (데이터베이스 이름 누락)
-- 잘못된 예: postgresql://user:pass@localhost:5432/My App  (공백 포함)

-- pg_hba.conf 관련 접속 권한 확인
SELECT pg_hba_file_rules();

예방 방법

1. 데이터베이스 초기화 스크립트에 존재 여부 확인 로직 추가

CI/CD 파이프라인 또는 애플리케이션 배포 스크립트에 데이터베이스 존재 여부를 사전 확인하는 로직을 반드시 포함시키는 것이 좋습니다. 아래와 같은 멱등성(idempotent)을 보장하는 스크립트를 활용하면 중복 생성 오류 없이 안전하게 데이터베이스를 준비할 수 있습니다.

-- PostgreSQL 9.x 이하 호환 방식: shell script에서 활용
-- psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname='myapp_prod'" | grep -q 1 || createdb myapp_prod

-- PostgreSQL에서 직접 실행 가능한 DO 블록 활용
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT FROM pg_database WHERE datname = 'myapp_prod'
    ) THEN
        PERFORM dblink_exec(
            'dbname=postgres',
            'CREATE DATABASE myapp_prod OWNER myapp_user'
        );
        RAISE NOTICE 'Database myapp_prod created successfully.';
    ELSE
        RAISE NOTICE 'Database myapp_prod already exists. Skipping.';
    END IF;
END
$$;

2. 모니터링 및 알림 체계 구축

데이터베이스 접속 실패 이벤트를 실시간으로 감지하고 알림을 받을 수 있는 모니터링 체계를 구축해야 합니다. PostgreSQL 로그에서 3D000 에러를 필터링하거나, Prometheus + pg_stat_statements, Datadog, CloudWatch 등의 모니터링 툴을 활용하여 연결 실패 임계값 초과 시 즉시 알림이 발송되도록 설정하는 것이 Best Practice입니다.

-- pg_stat_activity를 활용한 접속 실패 모니터링
SELECT client_addr, usename, application_name, state, wait_event_type, wait_event
FROM pg_stat_activity
WHERE state = 'active'
ORDER BY query_start DESC;

-- PostgreSQL 로그 설정 권장 (postgresql.conf)
-- log_connections = on
-- log_disconnections = on
-- log_min_error_statement = error

관련 에러

  • 28000 invalid_authorization_specification: 잘못된 사용자 이름으로 접속 시도 시 발생하며, 3D000과 함께 접속 실패의 대표적인 원인입니다.
  • 28P01 invalid_password: 올바른 데이터베이스 이름이지만 비밀번호가 틀린 경우 발생합니다.
  • 08006 connection_failure: 네트워크 또는 서버 자체의 문제로 접속이 실패할 때 발생하며, 3D000과 증상이 유사하여 혼동할 수 있습니다.
  • 42P04 duplicate_database: CREATE DATABASE 실행 시 이미 동일한 이름의 데이터베이스가 존재할 때 발생하는 에러로, 예방 스크립트 작성 시 함께 고려해야 합니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기