Oracle ORA-65040 오류 원인과 해결 방법 완벽 가이드

ORA-65040
2026년 10월 14일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-65040 operation not allowed from within a pluggable database 는?

ORA-65040 에러는 Oracle Multitenant 아키텍처 환경에서 PDB(Pluggable Database) 내부에 접속한 상태로 CDB(Container Database) 레벨에서만 허용되는 작업을 시도할 때 발생합니다. 예를 들어 PDB 세션에서 다른 PDB를 생성하거나, CDB 전체에 영향을 미치는 파라미터를 변경하거나, CDB 루트 컨테이너에서만 실행 가능한 DDL 또는 관리 명령어를 실행할 때 이 에러가 나타납니다. Oracle 12c 이상의 멀티테넌트 환경이 보편화되면서 DBA들이 자주 마주치는 에러 중 하나이며, 현재 접속 컨테이너가 어디인지 정확히 파악하지 못한 채 작업할 때 주로 발생합니다.


주요 발생 원인

  • PDB 세션에서 CDB 전용 명령어 실행

Oracle Multitenant 구조에서는 CDB$ROOT(루트 컨테이너)에서만 실행 가능한 명령어들이 명확하게 분리되어 있습니다. PDB에 접속한 상태에서 CREATE PLUGGABLE DATABASE, DROP PLUGGABLE DATABASE, ALTER PLUGGABLE DATABASE ... UNPLUG 등의 명령어를 실행하면 ORA-65040 에러가 발생합니다. 특히 신규 DBA들이 PDB와 CDB의 역할 구분을 명확히 이해하지 못한 채 작업하다 이 에러를 자주 경험합니다.

  • CDB 레벨 파라미터 또는 시스템 설정 변경 시도

ALTER SYSTEM SET 명령어를 통해 일부 파라미터를 변경할 때, 해당 파라미터가 CDB 전체 혹은 루트 컨테이너에서만 설정 가능한 경우 PDB 세션에서는 ORA-65040 에러가 발생합니다. 예를 들어 enable_pluggable_database, db_recovery_file_dest 등 CDB 수준의 파라미터를 PDB 내에서 변경하려 하면 이 에러가 트리거됩니다. 파라미터의 CON_ID 적용 범위를 사전에 확인하는 습관이 중요합니다.

  • Common User/Role 생성 또는 변경 시도

Oracle Multitenant에서 C## 접두어를 사용하는 공통 사용자(Common User) 또는 공통 역할(Common Role)은 반드시 CDB$ROOT에서 생성 및 관리해야 합니다. PDB 세션에서 CREATE USER C##ADMIN IDENTIFIED BY password 또는 GRANT ... TO C##USER CONTAINER=ALL 같은 구문을 실행하면 ORA-65040 에러가 발생합니다. 공통 사용자는 CDB 전체를 아우르는 계정이기 때문에 루트 컨테이너에서만 조작이 허용됩니다.


해결 방법

현재 접속 컨테이너 확인

먼저 현재 어느 컨테이너에 접속해 있는지 확인합니다.

-- 현재 접속 컨테이너 확인
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') AS current_container,
       SYS_CONTEXT('USERENV', 'CON_ID')   AS current_con_id
FROM DUAL;

-- 또는 간단하게
SHOW CON_NAME;

해결책 1: CDB$ROOT로 전환 후 작업

PDB 세션에서 CDB 전용 작업이 필요하다면 ALTER SESSION SET CONTAINER 명령어로 루트 컨테이너로 전환합니다.

-- CDB$ROOT로 컨테이너 전환
ALTER SESSION SET CONTAINER = CDB$ROOT;

-- 전환 확인
SHOW CON_NAME;

-- 이제 PDB 관련 CDB 작업 가능
CREATE PLUGGABLE DATABASE pdb_new
  ADMIN USER pdb_admin IDENTIFIED BY "Admin1234#"
  FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/CDB1/pdbseed/',
                       '/u01/app/oracle/oradata/CDB1/pdb_new/');

-- 또는 기존 PDB 언플러그
ALTER PLUGGABLE DATABASE pdb_old CLOSE IMMEDIATE;
ALTER PLUGGABLE DATABASE pdb_old UNPLUG INTO '/backup/pdb_old.xml';

해결책 2: CDB 레벨 파라미터 변경

CDB$ROOT로 전환 후 시스템 파라미터를 변경합니다.

-- CDB$ROOT로 이동
ALTER SESSION SET CONTAINER = CDB$ROOT;

-- CDB 전체 적용 파라미터 변경
ALTER SYSTEM SET db_recovery_file_dest = '/u01/app/oracle/fast_recovery_area'
  SCOPE = BOTH;

-- 특정 PDB에만 적용하려면 CONTAINER 절 사용 (CDB$ROOT 세션에서)
ALTER SYSTEM SET pga_aggregate_target = 512M
  SCOPE = BOTH
  CONTAINER = PDB1;

-- 파라미터 적용 범위 확인
SELECT NAME, VALUE, CON_ID, ISPDB_MODIFIABLE
FROM   V$SYSTEM_PARAMETER
WHERE  NAME = 'pga_aggregate_target';

해결책 3: Common User/Role 생성 (CDB$ROOT에서)

-- CDB$ROOT로 전환
ALTER SESSION SET CONTAINER = CDB$ROOT;

-- 공통 사용자 생성 (C## 접두어 필수)
CREATE USER C##DBA_COMMON IDENTIFIED BY "CommonPass#2024"
  DEFAULT TABLESPACE USERS
  TEMPORARY TABLESPACE TEMP
  CONTAINER = ALL;

-- 공통 롤 생성
CREATE ROLE C##READONLY_ROLE CONTAINER = ALL;

-- 공통 사용자에게 권한 부여
GRANT C##READONLY_ROLE TO C##DBA_COMMON CONTAINER = ALL;
GRANT CREATE SESSION    TO C##DBA_COMMON CONTAINER = ALL;

-- 특정 PDB에서 로컬 사용자는 PDB 세션에서 생성 가능
ALTER SESSION SET CONTAINER = PDB1;

CREATE USER local_app_user IDENTIFIED BY "LocalPass#2024"
  DEFAULT TABLESPACE USERS;

GRANT CREATE SESSION, CREATE TABLE TO local_app_user;

해결책 4: sysdba 권한으로 직접 CDB에 접속

운영 환경에서는 OS 인증이나 sysdba 권한으로 CDB에 직접 접속하는 방식도 권장됩니다.

-- SQL*Plus에서 CDB에 직접 sysdba로 접속
-- (OS 레벨 명령어)
-- sqlplus / as sysdba

-- 접속 후 컨테이너 확인 및 전환
SHOW CON_NAME;
-- 결과: CDB$ROOT 이면 CDB 레벨 작업 바로 가능

-- 특정 PDB로 직접 접속하려면 서비스명 사용
-- sqlplus sys@PDB1 as sysdba

예방 방법

  • 작업 전 컨테이너 확인 스크립트를 표준화하세요

모든 DBA 작업 세션 시작 시 컨테이너 확인을 습관화하고, 팀 표준 시작 스크립트에 아래 쿼리를 포함시키면 실수를 크게 줄일 수 있습니다. SQL*Plus 환경이라면 login.sql에 자동 출력 구문을 추가해 두는 것이 좋습니다.

“`sql

— login.sql 또는 작업 시작 시 실행 권장

SET FEEDBACK OFF

SELECT ‘현재 접속 컨테이너: ‘ || SYS_CONTEXT(‘USERENV’,’CON_NAME’)

|| ‘ (CON_ID: ‘ || SYS_CONTEXT(‘USERENV’,’CON_ID’) || ‘)’ AS container_info

FROM DUAL;

SET FEEDBACK ON

“`

  • CDB/PDB 역할에 따른 계정 및 접속 정보를 분리하여 관리하세요

CDB 관리용 계정과 각 PDB 관리용 계정을 명확히 분리하고, 접속 문자열(TNS alias)도 CDB_ADMIN, PDB1_ADMIN, PDB2_ADMIN 식으로 구분해 두면 실수로 잘못된 컨테이너에서 작업하는 상황을 원천 차단할 수 있습니다. 또한 개발/운영 환경 모두 접속 스크립트에 SHOW CON_NAME을 넣어 두는 것이 Best Practice입니다.


관련 에러

  • ORA-65048: message received in non-CDB — CDB 전용 메시지가 일반 non-CDB 환경에서 수신될 때 발생합니다.
  • ORA-65096: invalid common user or role name — Common User/Role 이름에 C## 접두어가 없거나 형식이 잘못된 경우 발생합니다.
  • ORA-65049: creation of local UNDO tablespace not allowed in CDB$ROOT — 루트 컨테이너에서 로컬 UNDO 테이블스페이스를 생성하려 할 때 발생합니다.
  • ORA-65050: common privileges must be granted commonly — 공통 권한을 공통 방식(CONTAINER=ALL)이 아닌 방식으로 부여하려 할 때 발생합니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기