2026년 10월 18일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-65164 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-65164 cannot refresh this PDB because it has been modified locally 는?
ORA-65164 에러는 Oracle Multitenant 환경에서 PDB(Pluggable Database)를 새로 고침(Refresh)하려 할 때, 해당 PDB 내에 로컬에서 수행된 변경 사항이 존재하는 경우 발생합니다. Refreshable PDB는 CDB Root 또는 원본 PDB로부터 정기적으로 동기화되어야 하는데, 로컬 변경이 감지되면 Oracle은 데이터 무결성 보호를 위해 Refresh 작업을 차단합니다. 주로 테스트 환경이나 클론 PDB를 운영하면서 의도치 않게 로컬 DDL 또는 DML을 수행한 경우에 자주 마주치는 에러입니다.
주요 발생 원인
- Refreshable PDB에서 로컬 DDL/DML 수행
Refreshable PDB는 읽기 전용(READ ONLY) 또는 제한된 모드로 운영되어야 하지만, 실수로 해당 PDB를 READ WRITE 모드로 열고 테이블 생성, 데이터 삽입 등의 작업을 수행한 경우 이 에러가 발생합니다. Oracle은 내부적으로 PDB의 SCN 및 변경 플래그를 추적하며, 로컬 변경이 탐지되면 이후 Refresh 시도 시 ORA-65164를 반환합니다. 이는 가장 흔한 원인으로, 개발자나 DBA가 PDB의 Refresh 정책을 인지하지 못한 채 작업했을 때 빈번히 발생합니다.
- PDB Refresh 모드 설정 후 잘못된 OPEN 모드 적용
PDB를 REFRESH MODE EVERY N MINUTES 또는 REFRESH MODE MANUAL로 생성한 이후, 운영 중에 ALTER PLUGGABLE DATABASE OPEN READ WRITE를 실행하여 쓰기 가능 상태로 전환한 경우가 있습니다. Refreshable PDB는 반드시 READ ONLY 상태이거나 CLOSE 상태에서만 Refresh가 가능한데, READ WRITE로 열린 상태에서 발생한 변경 이력이 Refresh를 방해합니다. 자동화 스크립트나 잘못된 운영 절차로 인해 의도치 않게 OPEN 모드가 바뀌는 경우가 많습니다.
- 불완전한 PDB Clone 또는 Link 설정 후 동기화 시도
원본 PDB(Source PDB)와 복제 PDB(Refreshable Clone PDB) 간의 DB Link 설정이 올바르지 않거나, 클론 생성 직후 초기화 작업(예: 임시 테이블 생성, 통계 수집 등)이 Refreshable PDB 내에서 수행된 경우 Refresh가 실패할 수 있습니다. 특히 자동화 프로비저닝 파이프라인에서 클론 생성 후 후처리(post-clone script)가 Refreshable PDB 컨텍스트에서 실행되는 경우 이 문제가 발생합니다. 클론 PDB가 Refreshable인지 여부를 스크립트가 인지하지 못하면 예기치 않은 변경이 축적될 수 있습니다.
해결 방법
방법 1: 현재 PDB의 로컬 변경 이력 확인
먼저 어떤 변경이 발생했는지 확인합니다.
-- CDB$ROOT에서 실행
SELECT CON_ID, NAME, OPEN_MODE, REFRESH_MODE, REFRESH_INTERVAL
FROM V$PDBS
WHERE NAME = 'YOUR_PDB_NAME';
-- PDB 내부에서 변경된 오브젝트 조회
ALTER SESSION SET CONTAINER = YOUR_PDB_NAME;
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS, LAST_DDL_TIME
FROM DBA_OBJECTS
WHERE LAST_DDL_TIME >= (SELECT CREATION_TIME FROM V$DATABASE)
ORDER BY LAST_DDL_TIME DESC;
방법 2: 로컬 변경 사항 롤백 후 Refresh 재시도
로컬에서 생성된 오브젝트를 제거하고 Refresh를 수행합니다.
-- PDB 내 잘못 생성된 테이블 삭제 예시
ALTER SESSION SET CONTAINER = YOUR_PDB_NAME;
DROP TABLE temp_test_table PURGE;
DROP TABLE unwanted_data PURGE;
-- PDB를 닫고 READ ONLY로 재오픈
ALTER PLUGGABLE DATABASE YOUR_PDB_NAME CLOSE IMMEDIATE;
ALTER PLUGGABLE DATABASE YOUR_PDB_NAME OPEN READ ONLY;
-- Refresh 수행 (CDB$ROOT에서 실행)
ALTER SESSION SET CONTAINER = CDB$ROOT;
ALTER PLUGGABLE DATABASE YOUR_PDB_NAME REFRESH;
방법 3: PDB를 Refresh 불가 상태로 전환 후 재구성
로컬 변경을 유지해야 하는 상황이라면, Refreshable 모드를 해제하고 새로운 클론을 생성하는 방법을 사용합니다.
-- Refresh 모드 해제 (LOCAL 변경을 영구 적용)
ALTER SESSION SET CONTAINER = CDB$ROOT;
ALTER PLUGGABLE DATABASE YOUR_PDB_NAME
REFRESH MODE NONE;
-- 상태 확인
SELECT NAME, REFRESH_MODE, REFRESH_INTERVAL
FROM V$PDBS
WHERE NAME = 'YOUR_PDB_NAME';
-- 필요한 경우, 원본 PDB로부터 새로운 Refreshable 클론 재생성
CREATE PLUGGABLE DATABASE NEW_REFRESH_PDB
FROM SOURCE_PDB@source_db_link
REFRESH MODE EVERY 60 MINUTES;
ALTER PLUGGABLE DATABASE NEW_REFRESH_PDB OPEN READ ONLY;
방법 4: 강제 Refresh (데이터 손실 감수 시)
로컬 변경 사항을 무시하고 강제로 원본과 동기화할 경우 아래와 같이 수행합니다. 단, 로컬 데이터는 모두 손실됩니다.
-- FORCE 옵션으로 Refresh 강제 수행
ALTER SESSION SET CONTAINER = CDB$ROOT;
ALTER PLUGGABLE DATABASE YOUR_PDB_NAME CLOSE IMMEDIATE;
-- Refresh 전 현재 상태 스냅샷 (선택적 백업)
-- RMAN을 이용한 백업 수행 권장
ALTER PLUGGABLE DATABASE YOUR_PDB_NAME OPEN READ ONLY;
ALTER PLUGGABLE DATABASE YOUR_PDB_NAME REFRESH;
-- 성공 여부 확인
SELECT NAME, OPEN_MODE, REFRESH_MODE
FROM V$PDBS
WHERE NAME = 'YOUR_PDB_NAME';
예방 방법
- Refreshable PDB에 대한 OPEN 모드 정책 자동화 및 감사 적용
Refreshable PDB가 READ WRITE 모드로 열리는 것을 방지하기 위해 DDL Trigger 또는 Oracle Audit Policy를 설정하여 불법적인 OPEN 모드 변경을 사전에 탐지합니다. 또한 정기적인 스크립트를 통해 모든 Refreshable PDB의 OPEN_MODE와 REFRESH_MODE를 모니터링하고, READ WRITE로 전환된 PDB가 감지되면 즉시 알림이 가도록 구성하는 것이 Best Practice입니다.
“`sql
— Refreshable PDB 상태 정기 모니터링 쿼리 (Cron 또는 DBMS_SCHEDULER로 실행)
SELECT NAME, OPEN_MODE, REFRESH_MODE, REFRESH_INTERVAL,
CASE WHEN OPEN_MODE = ‘READ WRITE’ AND REFRESH_MODE != ‘NONE’
THEN ‘ 경고: READ WRITE 상태의 Refreshable PDB ‘
ELSE ‘NORMAL’
END AS STATUS_CHECK
FROM V$PDBS
WHERE REFRESH_MODE != ‘NONE’;
“`
- Post-Clone 스크립트의 컨텍스트 분리 및 Refreshable 여부 사전 검증
자동화된 클론 또는 프로비저닝 파이프라인에서는 반드시 PDB의 Refresh 모드를 확인한 후 후처리 스크립트를 실행해야 합니다. Refreshable PDB에는 로컬 변경을 수행하는 스크립트가 절대 실행되지 않도록 검증 로직을 추가하고, 모든 초기화 작업은 원본 PDB(Source PDB)에서 수행한 뒤 Refresh를 통해 반영되도록 프로세스를 설계하는 것이 권장됩니다.
관련 에러
- ORA-65169: PDB Refresh 작업 중 내부 오류가 발생했을 때 나타나며, ORA-65164와 함께 체인 에러로 발생하는 경우가 있습니다.
- ORA-17627 / ORA-17629: DB Link를 통한 원격 PDB 접속 실패 시 발생하며, Refreshable PDB의 소스 연결 문제와 관련됩니다.
- ORA-65040: Refreshable PDB가 READ WRITE 상태일 때 특정 작업이 허용되지 않음을 나타내며, ORA-65164 발생 전 단계에서 자주 동반됩니다.
- ORA-65011: 지정한 PDB가 존재하지 않을 때 발생하며, 잘못된 PDB 이름으로 Refresh를 시도할 경우 나타납니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.