2026년 10월 14일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-65049 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-65049 creation of local user, role or profile is not allowed in CDB$ROOT 는?
ORA-65049 에러는 Oracle Multitenant 아키텍처(CDB/PDB 구조)에서 CDB$ROOT 컨테이너에 로컬 사용자(Local User), 로컬 롤(Local Role), 또는 로컬 프로파일(Local Profile)을 생성하려 할 때 발생하는 에러입니다. Oracle 12c 이후 도입된 멀티테넌트 환경에서는 CDB$ROOT는 공통(Common) 오브젝트만 허용하며, 로컬 오브젝트는 반드시 개별 PDB(Pluggable Database) 내에서만 생성해야 합니다. 즉, 기존 Non-CDB 환경에서의 습관대로 CDB$ROOT에서 일반 사용자나 롤을 생성하려 하면 이 에러가 발생하게 됩니다.
주요 발생 원인
1. CDB 환경 인식 없이 CDB$ROOT에서 사용자 생성 시도
가장 흔한 원인으로, DBA가 현재 접속된 컨테이너가 CDB$ROOT임을 인지하지 못하고 일반 사용자를 CREATE USER 구문으로 생성하려 할 때 발생합니다. Oracle 12c 이전 Non-CDB 환경에 익숙한 DBA라면 특히 자주 겪는 상황이며, CDB$ROOT에서는 반드시 CONTAINER=ALL 옵션을 사용하는 공통(Common) 사용자(이름이 C##으로 시작해야 함)만 생성할 수 있습니다.
2. PDB에 접속하지 않고 롤(Role) 또는 프로파일(Profile) 생성 시도
CDB$ROOT에 접속한 상태에서 특정 애플리케이션에만 적용되어야 할 로컬 롤이나 프로파일을 생성할 때 이 에러가 발생합니다. CDB$ROOT에서는 CONTAINER=ALL 구문 없이 생성하는 롤/프로파일은 모두 로컬 오브젝트로 간주되어 에러가 발생하며, 반드시 대상 PDB로 세션을 전환(ALTER SESSION SET CONTAINER)한 후 생성해야 합니다.
3. 스크립트 자동화 또는 마이그레이션 중 컨테이너 전환 누락
Non-CDB에서 CDB 환경으로 데이터베이스를 마이그레이션하거나, 자동화 스크립트로 대량의 사용자/롤/프로파일을 생성할 때 컨테이너 전환 구문이 누락된 경우 발생합니다. 마이그레이션 스크립트가 Non-CDB 환경 기반으로 작성되어 있다면 CDB 환경에서는 그대로 실행할 수 없으며, 컨테이너 인식 로직을 반드시 추가해야 합니다.
해결 방법
해결 방법 1: 현재 컨테이너 확인 후 PDB로 전환하여 로컬 사용자 생성
먼저 현재 어떤 컨테이너에 접속해 있는지 확인합니다.
-- 현재 컨테이너 확인
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') AS current_container FROM DUAL;
-- 모든 PDB 목록 확인
SELECT CON_ID, NAME, OPEN_MODE FROM V$PDBS;
현재 CDB$ROOT에 있다면, 원하는 PDB로 세션을 전환한 후 사용자를 생성합니다.
-- 대상 PDB로 세션 전환
ALTER SESSION SET CONTAINER = ORCLPDB1;
-- PDB 내에서 로컬 사용자 생성 (정상 동작)
CREATE USER app_user IDENTIFIED BY "SecurePass123!"
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON users;
-- 권한 부여
GRANT CONNECT, RESOURCE TO app_user;
해결 방법 2: CDB 전체에 공통(Common) 사용자 생성
CDB$ROOT에서 반드시 생성해야 하는 경우라면, 공통 사용자(Common User)로 생성해야 합니다. 공통 사용자의 이름은 반드시 C##으로 시작해야 합니다.
-- CDB$ROOT에서 공통 사용자 생성 (C## 접두어 필수)
CREATE USER C##global_admin IDENTIFIED BY "AdminPass456!"
CONTAINER = ALL;
-- 공통 롤 부여
GRANT DBA TO C##global_admin CONTAINER = ALL;
-- 공통 롤 생성 방법
CREATE ROLE C##common_role CONTAINER = ALL;
GRANT CREATE SESSION TO C##common_role CONTAINER = ALL;
해결 방법 3: PDB에서 로컬 롤 및 프로파일 생성
-- 대상 PDB로 전환
ALTER SESSION SET CONTAINER = ORCLPDB1;
-- 로컬 롤 생성
CREATE ROLE app_read_role;
GRANT SELECT ANY TABLE TO app_read_role;
-- 로컬 프로파일 생성
CREATE PROFILE app_user_profile LIMIT
SESSIONS_PER_USER 3
CPU_PER_SESSION UNLIMITED
CPU_PER_CALL 3000
CONNECT_TIME 30
IDLE_TIME 10
FAILED_LOGIN_ATTEMPTS 5
PASSWORD_LIFE_TIME 90
PASSWORD_REUSE_TIME 365
PASSWORD_LOCK_TIME 1/24;
-- 생성된 프로파일을 사용자에게 적용
ALTER USER app_user PROFILE app_user_profile;
해결 방법 4: 마이그레이션 스크립트에 컨테이너 전환 로직 추가
-- 마이그레이션 스크립트 예시 (PDB 전환 포함)
DECLARE
v_pdb_name VARCHAR2(30) := 'ORCLPDB1';
BEGIN
-- 대상 PDB로 전환
EXECUTE IMMEDIATE 'ALTER SESSION SET CONTAINER = ' || v_pdb_name;
-- 사용자 생성 (이미 존재하면 무시)
BEGIN
EXECUTE IMMEDIATE
'CREATE USER migrated_user IDENTIFIED BY "MigPass789!"
DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -1920 THEN -- ORA-01920: user name conflicts
DBMS_OUTPUT.PUT_LINE('User already exists, skipping...');
ELSE
RAISE;
END IF;
END;
EXECUTE IMMEDIATE 'GRANT CONNECT, RESOURCE TO migrated_user';
DBMS_OUTPUT.PUT_LINE('Migration completed for: ' || v_pdb_name);
END;
/
예방 방법
1. DBA 세션 시작 시 항상 현재 컨테이너를 확인하는 습관화
모든 DDL 작업 전 현재 접속된 컨테이너를 확인하는 것을 DBA 표준 운영 절차(SOP)에 포함시켜야 합니다. SQL*Plus 프롬프트에 컨테이너 이름을 표시하도록 설정하거나, 로그인 트리거를 활용하여 DBA가 현재 위치를 항상 인식할 수 있도록 환경을 구성하는 것이 좋습니다.
-- SQL*Plus 프롬프트에 컨테이너 표시 설정
SET SQLPROMPT "_USER'@'_CONNECT_IDENTIFIER CDB:&&_CONNECT_IDENTIFIER> "
-- 또는 로그인 후 항상 확인하는 별칭 설정 (glogin.sql에 추가)
-- SELECT SYS_CONTEXT('USERENV','CON_NAME') FROM DUAL;
2. CDB/PDB 환경에 맞는 스크립트 템플릿 표준화
팀 내에서 사용하는 사용자/롤/프로파일 생성 스크립트를 CDB 환경에 맞게 표준 템플릿화하여 관리해야 합니다. 모든 스크립트 상단에 컨테이너 확인 및 전환 로직을 포함하고, CI/CD 파이프라인이나 형상관리 시스템에 스크립트 사전 검증(Pre-validation) 단계를 추가하여 CDB$ROOT에서 로컬 오브젝트 생성을 시도하는 구문이 포함된 스크립트가 실행되지 않도록 차단하는 것이 중요합니다.
관련 에러
- ORA-65048: CDB$ROOT에서 공통 사용자/롤에 허용되지 않는 작업을 수행할 때 발생하는 에러입니다.
- ORA-65050: Common User나 Role을 생성할 때 이름에
C##접두어가 없을 경우 발생합니다 (common user or role name must begin with C##또는 유사 메시지). - ORA-01031: 사용자 생성에 필요한 권한이 없을 때 발생하며, CDB 환경에서는 공통 사용자 생성 시
CREATE USER권한을CONTAINER=ALL로 부여받아야 합니다. - ORA-65040: PDB가 닫혀 있는 상태에서 해당 PDB에 접근하거나 작업을 수행하려 할 때 발생할 수 있으므로, PDB OPEN 여부를 먼저 확인해야 합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.