2026년 07월 13일 | DBMS Error 가이드
이 글에서 다루는 내용
42P12 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
42P12 invalid database definition 는?
PostgreSQL 에러 코드 42P12는 invalid database definition으로, 데이터베이스를 생성하거나 변경할 때 잘못된 정의나 옵션이 사용되었을 때 발생합니다. 주로 CREATE DATABASE 또는 ALTER DATABASE 구문에서 허용되지 않는 파라미터 조합, 잘못된 인코딩 설정, 존재하지 않는 템플릿 데이터베이스를 참조하는 경우에 나타납니다. 이 에러는 데이터베이스 레벨의 정의 자체가 유효하지 않음을 의미하며, SQL 표준 클래스 42(Syntax Error or Access Rule Violation)에 속하는 에러입니다.
주요 발생 원인
1. 잘못된 인코딩(Encoding)과 로케일(Locale) 조합 사용
PostgreSQL에서 데이터베이스를 생성할 때 ENCODING, LC_COLLATE, LC_CTYPE 값은 서로 호환되어야 합니다. 예를 들어, UTF8 인코딩과 함께 운영체제에 설치되지 않은 로케일을 지정하거나, SQL_ASCII와 특정 로케일을 혼용하면 이 에러가 발생합니다. 특히 Windows 환경과 Linux 환경 간에 로케일 이름 형식이 다르기 때문에, 서버 마이그레이션 시 자주 발생하는 문제입니다.
2. 존재하지 않거나 사용 중인 템플릿 데이터베이스 지정
CREATE DATABASE 구문의 TEMPLATE 옵션에 존재하지 않는 데이터베이스 이름을 지정하거나, 현재 다른 세션이 접속 중인 데이터베이스를 템플릿으로 사용하려 할 때 에러가 발생합니다. PostgreSQL은 템플릿 데이터베이스를 복사하는 방식으로 새 데이터베이스를 생성하므로, 템플릿 데이터베이스에 활성 연결이 있으면 안 됩니다. template1 외의 사용자 정의 템플릿을 사용할 경우 이 조건을 특히 주의해야 합니다.
3. 허용되지 않는 옵션 파라미터 또는 값 범위 초과
CREATE DATABASE 또는 ALTER DATABASE 명령에서 지원되지 않는 옵션을 사용하거나, CONNECTION LIMIT에 음수(단, -1 제외) 또는 허용 범위를 벗어난 값을 지정하면 이 에러가 발생할 수 있습니다. PostgreSQL 버전마다 지원하는 데이터베이스 옵션이 다르므로, 버전 업그레이드 이후 기존 스크립트를 그대로 실행할 때 예상치 못하게 발생하기도 합니다. 또한 TABLESPACE로 존재하지 않는 테이블스페이스를 지정하는 경우도 이 범주에 해당합니다.
해결 방법
원인 1 해결: 인코딩과 로케일 확인 및 수정
먼저 서버에서 사용 가능한 로케일을 확인한 뒤, 호환 가능한 조합으로 데이터베이스를 생성합니다.
-- 잘못된 예시 (존재하지 않는 로케일 사용)
CREATE DATABASE mydb
ENCODING 'UTF8'
LC_COLLATE 'ko_KR.UTF-8' -- 운영체제에 해당 로케일이 없을 경우 에러
LC_CTYPE 'ko_KR.UTF-8';
-- 올바른 예시 1: 서버 기본 로케일 사용
CREATE DATABASE mydb
ENCODING 'UTF8'
LC_COLLATE 'en_US.UTF-8'
LC_CTYPE 'en_US.UTF-8'
TEMPLATE template0;
-- 올바른 예시 2: C 로케일 (가장 범용적)
CREATE DATABASE mydb_safe
ENCODING 'UTF8'
LC_COLLATE 'C'
LC_CTYPE 'C'
TEMPLATE template0;
-- 시스템에서 사용 가능한 로케일 목록 확인 (psql 외부 명령)
-- Linux: locale -a
-- PostgreSQL 내에서 설치된 로케일 관련 확인
SELECT pg_encoding_to_char(encoding), datcollate, datctype
FROM pg_database
WHERE datname = 'template0';
> 중요: 인코딩을 UTF8이 아닌 다른 값으로 변경할 때는 반드시 TEMPLATE template0을 사용해야 합니다. template1은 기본적으로 서버 인코딩을 따르기 때문입니다.
원인 2 해결: 템플릿 데이터베이스 연결 확인 및 정리
-- 특정 데이터베이스에 연결된 세션 확인
SELECT pid, usename, application_name, client_addr, state
FROM pg_stat_activity
WHERE datname = 'my_template_db';
-- 해당 세션 종료 (superuser 권한 필요)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'my_template_db'
AND pid <> pg_backend_pid();
-- 연결이 정리된 후 템플릿으로 데이터베이스 생성
CREATE DATABASE newdb
TEMPLATE my_template_db;
-- 존재하는 데이터베이스 목록 확인
SELECT datname, datistemplate, datallowconn
FROM pg_database
ORDER BY datname;
-- 사용자 정의 템플릿 등록 (해당 DB를 템플릿으로 사용 허용)
UPDATE pg_database
SET datistemplate = TRUE
WHERE datname = 'my_template_db';
원인 3 해결: 올바른 옵션 파라미터 사용
-- 잘못된 예시 (음수 CONNECTION LIMIT, 존재하지 않는 TABLESPACE)
CREATE DATABASE baddb
CONNECTION LIMIT -5 -- -1만 허용 (무제한), 그 외 음수는 에러
TABLESPACE nonexistent_ts; -- 존재하지 않는 테이블스페이스
-- 올바른 예시
CREATE DATABASE gooddb
OWNER myuser
ENCODING 'UTF8'
CONNECTION LIMIT 100 -- 최대 100개 연결 허용
TABLESPACE pg_default; -- 기본 테이블스페이스 사용
-- 기존 데이터베이스 속성 변경
ALTER DATABASE gooddb
CONNECTION LIMIT 200;
ALTER DATABASE gooddb
RENAME TO betterdb;
-- 존재하는 테이블스페이스 목록 확인
SELECT spcname, pg_tablespace_location(oid) AS location
FROM pg_tablespace;
-- 데이터베이스 현재 설정 확인
SELECT datname, datdba, encoding, datcollate, datctype,
datconnlimit, dattablespace
FROM pg_database
WHERE datname = 'gooddb';
예방 방법
1. 데이터베이스 생성 스크립트 표준화 및 사전 검증
운영 환경에 데이터베이스를 생성하기 전, 반드시 테스트 환경에서 동일한 스크립트를 검증하는 프로세스를 도입하세요. 특히 서버의 OS 로케일 목록(locale -a)을 사전에 확인하고, CI/CD 파이프라인에 데이터베이스 생성 스크립트 드라이런(dry-run) 단계를 포함하는 것이 좋습니다. 아래와 같이 생성 전 유효성을 체크하는 쿼리를 항상 수행하는 습관을 들이세요.
-- 데이터베이스 생성 전 사전 체크 쿼리
DO $$
BEGIN
-- 동일한 이름의 DB가 이미 있는지 확인
IF EXISTS (SELECT 1 FROM pg_database WHERE datname = 'target_db') THEN
RAISE NOTICE 'Database target_db already exists. Skipping creation.';
ELSE
-- 실제 생성은 DO 블록 외부에서 수행 (DDL은 트랜잭션 내 제한)
RAISE NOTICE 'Ready to create target_db.';
END IF;
END;
$$;
2. PostgreSQL 버전별 릴리즈 노트 숙지 및 옵션 관리
PostgreSQL은 메이저 버전마다 CREATE DATABASE 및 ALTER DATABASE에서 지원하는 옵션이 추가되거나 변경됩니다. 예를 들어, PostgreSQL 15부터 ICU_LOCALE, LOCALE_PROVIDER 등의 새로운 옵션이 추가되었으며, 이를 이전 버전에서 사용하면 에러가 발생합니다. 버전 업그레이드 시 공식 릴리즈 노트를 반드시 검토하고, 데이터베이스 생성/관리 스크립트를 버전에 맞게 관리하세요.
관련 에러
- 42601 (syntax_error): SQL 문법 자체가 잘못된 경우로,
CREATE DATABASE구문의 키워드 오타나 누락 시 발생합니다. - 42P01 (undefined_table): 존재하지 않는 객체를 참조할 때 발생하며, 없는 테이블스페이스나 역할(Role)을
OWNER로 지정할 때 연관될 수 있습니다. - 55006 (object_in_use): 데이터베이스가 다른 세션에서 사용 중일 때 발생하며, 템플릿으로 사용하려는 DB에 활성 연결이 있을 때 함께 확인해야 할 에러입니다.
- 3D000 (invalid_catalog_name): 존재하지 않는 데이터베이스에 연결을 시도할 때 발생하며, 템플릿 지정 오류와 혼동될 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.