2026년 09월 26일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-16000 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-16000 database open for read-only access 는?
ORA-16000 에러는 현재 접속한 Oracle 데이터베이스가 읽기 전용(Read-Only) 모드로 열려 있을 때 발생합니다. 이 상태에서는 INSERT, UPDATE, DELETE, CREATE, DROP 등 데이터를 변경하거나 구조를 수정하는 모든 DDL/DML 작업이 차단됩니다. 주로 Oracle Data Guard 환경의 Standby 데이터베이스, Physical Standby DB를 READ ONLY 모드로 열었을 때, 또는 관리 목적으로 데이터베이스를 READ ONLY로 마운트했을 때 나타납니다.
주요 발생 원인
1. Oracle Data Guard Standby 데이터베이스 접속
가장 흔한 원인으로, Data Guard 구성에서 Physical Standby 데이터베이스는 기본적으로 읽기 전용 또는 Mount 상태로 운영됩니다. 운영자가 Primary DB와 Standby DB의 접속 정보를 혼동하여 Standby DB에 쓰기 작업을 시도할 때 이 에러가 발생합니다. Active Data Guard 라이선스를 통해 READ ONLY WITH APPLY 모드로 운영 중인 경우에도 동일한 에러가 발생하며, 해당 DB에서는 절대 쓰기가 허용되지 않습니다.
2. 데이터베이스를 READ ONLY 모드로 명시적 오픈
DBA가 데이터 보호 또는 감사 목적으로 데이터베이스를 명시적으로 READ ONLY 모드로 오픈한 경우입니다. ALTER DATABASE OPEN READ ONLY; 명령으로 오픈된 DB는 SHUTDOWN 후 다시 READ WRITE로 열기 전까지 모든 쓰기 작업이 불가능합니다. 이런 설정은 운영 중 변경 내역 없이 특정 시점의 데이터를 분석하거나 검증해야 할 때 주로 사용됩니다.
3. PDB(Pluggable Database)의 READ ONLY 상태
Oracle 12c 이상 멀티테넌트 환경에서 특정 PDB만 READ ONLY 상태로 열려 있을 수 있습니다. PDB 수준에서 ALTER PLUGGABLE DATABASE pdb_name OPEN READ ONLY; 명령이 실행되면 해당 PDB에 접속한 사용자는 쓰기 작업 시 ORA-16000을 경험하게 됩니다. CDB 전체는 정상이더라도 특정 PDB만 READ ONLY 상태인 경우가 있어 DBA가 간과하기 쉬운 원인입니다.
해결 방법
원인 1 해결: Data Guard Standby DB 확인 및 Primary DB 접속
먼저 현재 접속한 DB가 Primary인지 Standby인지 확인합니다.
-- 현재 DB 역할 확인
SELECT NAME, DB_UNIQUE_NAME, DATABASE_ROLE, OPEN_MODE
FROM V$DATABASE;
-- 결과 예시
-- NAME DB_UNIQUE_NAME DATABASE_ROLE OPEN_MODE
-- ORCL ORCL_STB PHYSICAL STANDBY READ ONLY WITH APPLY
Standby DB임이 확인되면 Primary DB의 접속 정보(TNS, IP)를 사용하여 재접속합니다. Primary DB 확인 방법은 다음과 같습니다.
-- Primary DB 정보 확인 (Data Guard Broker 사용 시)
-- DGMGRL 에서 실행
-- DGMGRL> SHOW CONFIGURATION;
-- DGMGRL> SHOW DATABASE VERBOSE 'ORCL';
-- V$DATAGUARD_CONFIG 뷰에서 확인
SELECT DEST_ID, DEST_NAME, STATUS, TARGET, ARCHIVER, SCHEDULE,
DESTINATION, DB_UNIQUE_NAME
FROM V$ARCHIVE_DEST
WHERE TARGET = 'PRIMARY'
AND STATUS = 'VALID';
원인 2 해결: READ ONLY 모드 해제 후 READ WRITE로 재오픈
현재 DB 오픈 모드를 확인한 뒤, READ WRITE 모드로 변경합니다.
-- 현재 오픈 모드 확인
SELECT OPEN_MODE FROM V$DATABASE;
-- READ ONLY 상태라면 아래 절차로 READ WRITE 전환
-- 1단계: DB 종료
SHUTDOWN IMMEDIATE;
-- 2단계: Mount 상태로 시작
STARTUP MOUNT;
-- 3단계: READ WRITE로 오픈
ALTER DATABASE OPEN READ WRITE;
-- 오픈 모드 재확인
SELECT NAME, OPEN_MODE FROM V$DATABASE;
-- 결과: OPEN_MODE = READ WRITE
> ⚠️ 주의: Standby DB에서는 위 명령 실행 시 Data Guard 동기화가 중단될 수 있으므로, 반드시 Primary DB에서만 실행하십시오.
원인 3 해결: PDB READ ONLY 상태 해제
멀티테넌트 환경에서 PDB 오픈 모드를 확인하고 변경합니다.
-- CDB에서 모든 PDB 상태 확인
SELECT CON_ID, NAME, OPEN_MODE, RESTRICTED
FROM V$PDBS
ORDER BY CON_ID;
-- 특정 PDB READ ONLY 해제 (CDB$ROOT 또는 해당 PDB에서 실행)
ALTER PLUGGABLE DATABASE pdb_name CLOSE IMMEDIATE;
ALTER PLUGGABLE DATABASE pdb_name OPEN READ WRITE;
-- PDB에 직접 접속하여 확인
ALTER SESSION SET CONTAINER = pdb_name;
SELECT NAME, OPEN_MODE FROM V$DATABASE;
-- 재시작 후에도 READ WRITE 유지 (저장 설정)
ALTER PLUGGABLE DATABASE pdb_name SAVE STATE;
종합 진단 스크립트
-- ORA-16000 발생 시 빠른 진단용 스크립트
SELECT
d.NAME AS db_name,
d.DB_UNIQUE_NAME AS unique_name,
d.DATABASE_ROLE AS db_role,
d.OPEN_MODE AS open_mode,
d.PROTECTION_MODE AS protection_mode,
i.INSTANCE_NAME AS instance_name,
i.HOST_NAME AS host_name
FROM V$DATABASE d, V$INSTANCE i;
예방 방법
1. 접속 계층 분리 및 TNS 명명 규칙 표준화
Primary DB와 Standby DB의 TNS 서비스명을 명확하게 구분하여 관리합니다. 예를 들어 ORCL_PRD(Primary용), ORCL_STB(Standby 읽기 전용용)처럼 명명 규칙을 정하고, 애플리케이션 접속 설정에서 쓰기 작업은 반드시 Primary 서비스명을 사용하도록 강제합니다. 또한 Oracle Database의 Service 기반 접속 기능을 활용하여 Primary DB에서만 활성화되는 전용 서비스를 생성하면 자동 페일오버 시에도 올바른 DB로 연결될 수 있습니다.
-- Primary 전용 서비스 생성 예시 (DBMS_SERVICE 패키지 활용)
EXEC DBMS_SERVICE.CREATE_SERVICE('WRITE_SVC', 'WRITE_SVC');
EXEC DBMS_SERVICE.START_SERVICE('WRITE_SVC');
-- Data Guard Broker에서 Primary에만 서비스 등록
-- DGMGRL> ADD SERVICE 'orcl' 'WRITE_SVC' PREFERRED 'orcl_primary';
2. 정기적인 DB 상태 모니터링 자동화
운영 환경에서는 DB 오픈 모드가 예상치 않게 변경되는 경우를 대비해 주기적인 상태 점검 스크립트를 스케줄링합니다. Oracle Enterprise Manager(OEM) 또는 커스텀 쉘 스크립트를 통해 OPEN_MODE가 READ WRITE가 아닌 경우 즉시 DBA에게 알림이 가도록 설정합니다.
-- 모니터링 쿼리 (Cron Job 또는 OEM Custom Metric으로 활용)
SELECT CASE
WHEN OPEN_MODE != 'READ WRITE' THEN
'WARNING: DB is in ' || OPEN_MODE || ' mode!'
ELSE
'OK: DB is in READ WRITE mode.'
END AS db_status,
NAME,
OPEN_MODE,
DATABASE_ROLE
FROM V$DATABASE;
관련 에러
- ORA-01552: 읽기 전용 데이터베이스에서 시스템 롤백 세그먼트 사용 불가 에러로, ORA-16000과 함께 발생하는 경우가 있습니다.
- ORA-16004: Standby 데이터베이스가 Primary와의 연결 실패 시 발생하며, Data Guard 환경에서 ORA-16000과 연관되어 나타납니다.
- ORA-01219: 데이터베이스가 MOUNT 상태에서 오픈되지 않았을 때 발생하는 에러로, READ ONLY 전환 중 절차 오류 시 함께 발생할 수 있습니다.
- ORA-16014: Standby Redo Log 관련 에러로 Data Guard 환경에서 READ ONLY 모드 운영 시 연관될 수 있습니다.
- ORA-00604: 내부적으로 트리거나 재귀 SQL이 읽기 전용 DB에 쓰기를 시도할 때 ORA-16000과 연계되어 발생하기도 합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.