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

ORA-00320
2026년 06월 08일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-00320 cannot read file header from log of thread 는?

ORA-00320 에러는 Oracle 데이터베이스가 Redo Log 파일의 헤더를 읽을 수 없을 때 발생하는 심각한 오류입니다. 이 에러는 주로 데이터베이스 시작(STARTUP) 과정이나 로그 스위치(Log Switch) 도중에 발생하며, Oracle이 지정된 스레드(Thread)의 온라인 Redo Log 파일에 접근하거나 파일 헤더 정보를 파싱하지 못할 때 나타납니다. 방치할 경우 데이터베이스가 MOUNT 또는 OPEN 상태로 전환되지 못하거나, RAC 환경에서 특정 인스턴스가 정상 기동되지 않는 치명적인 상황으로 이어질 수 있습니다.


주요 발생 원인

1. Redo Log 파일의 물리적 손상 또는 삭제

가장 흔한 원인으로, OS 레벨에서 Redo Log 파일이 실수로 삭제되거나 스토리지 장애로 인해 파일이 물리적으로 손상된 경우입니다. Oracle은 Redo Log 파일의 헤더 블록에서 SCN, 시퀀스 번호, 스레드 번호 등 핵심 메타데이터를 읽어야 하는데, 파일 자체가 없거나 헤더 블록이 깨진 경우 이 에러가 즉시 발생합니다. 특히 Redo Log가 현재 활성(CURRENT) 또는 활성 상태(ACTIVE)일 때 이런 문제가 발생하면 복구가 더욱 복잡해집니다.

2. 잘못된 파일 권한 또는 경로 불일치

Oracle 프로세스(일반적으로 oracle OS 사용자)가 Redo Log 파일에 대한 읽기/쓰기 권한을 갖지 못하는 경우 발생합니다. 파일 시스템 마운트 포인트가 변경되거나 ASM 디스크 그룹이 마운트되지 않은 상태에서 데이터베이스를 기동하려 할 때도 동일한 에러가 발생합니다. 제어 파일(Control File)에 기록된 Redo Log 경로와 실제 OS 파일 경로가 다른 경우에도 이 에러가 트리거됩니다.

3. RAC 환경에서의 스레드(Thread) 구성 오류

Oracle RAC 환경에서는 각 인스턴스가 고유한 Redo Log 스레드를 가집니다. 인스턴스가 추가되거나 제거되는 과정에서 스레드가 비정상적으로 활성화(Enabled)된 상태로 남아 있거나, 해당 스레드의 Redo Log 그룹이 물리적으로 존재하지 않을 때 이 에러가 발생합니다. 또한 단일 인스턴스 데이터베이스로 복원(Restore) 후 RAC 스레드 정보가 제대로 정리되지 않은 경우에도 동일 증상이 나타납니다.


해결 방법

사전 진단: 현재 Redo Log 상태 확인

먼저 어떤 로그 파일이 문제인지 정확히 파악해야 합니다.

-- Redo Log 그룹 및 멤버 현황 확인
SELECT a.GROUP#, a.THREAD#, a.SEQUENCE#, a.STATUS, a.MEMBERS,
       b.MEMBER, b.STATUS AS MEMBER_STATUS
FROM   V$LOG a
JOIN   V$LOGFILE b ON a.GROUP# = b.GROUP#
ORDER  BY a.THREAD#, a.GROUP#;

-- 제어 파일 기준 Redo Log 정보 확인
SELECT * FROM V$LOGFILE ORDER BY GROUP#;

-- Alert Log 최근 에러 확인 (Oracle 11g 이상)
SELECT ORIGINATING_TIMESTAMP, MESSAGE_TEXT
FROM   V$DIAG_INFO
WHERE  ROWNUM <= 1;

-- 혹은 직접 경로 확인
SELECT VALUE FROM V$DIAG_INFO WHERE NAME = 'Diag Trace';

해결책 1: 손상되지 않은 INACTIVE 로그 그룹 재생성

해당 Redo Log 그룹의 상태가 INACTIVE이고 물리적 파일이 손상/삭제된 경우, 그룹을 DROP하고 새로 추가하는 것이 가장 안전합니다.

-- 1단계: 문제 그룹 상태 재확인
SELECT GROUP#, THREAD#, STATUS FROM V$LOG WHERE GROUP# = &problem_group;

-- 2단계: 문제 그룹 삭제 (INACTIVE 상태일 때만 가능)
ALTER DATABASE DROP LOGFILE GROUP 3;

-- 3단계: 새 로그 그룹 추가
ALTER DATABASE ADD LOGFILE THREAD 1
  GROUP 3 ('/u01/app/oracle/oradata/ORCL/redo03a.log',
            '/u01/app/oracle/oradata/ORCL/redo03b.log') SIZE 200M REUSE;

-- 4단계: 정상 여부 확인
SELECT GROUP#, THREAD#, STATUS, MEMBERS FROM V$LOG;

해결책 2: CURRENT 또는 ACTIVE 로그 손상 시 불완전 복구

가장 심각한 케이스로, 현재 활성 Redo Log가 손상된 경우입니다. 이때는 데이터 손실을 감수하고 RESETLOGS로 데이터베이스를 열어야 할 수 있습니다.

-- 1단계: MOUNT 상태로 기동
STARTUP MOUNT;

-- 2단계: 강제로 로그를 클리어 (아카이브 모드 여부에 따라 선택)
-- ARCHIVELOG 모드가 아닌 경우 (데이터 손실 가능성 있음)
ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 2;

-- ARCHIVELOG 모드인 경우
ALTER DATABASE CLEAR LOGFILE GROUP 2;

-- 3단계: 복구 시도
RECOVER DATABASE UNTIL CANCEL;

-- 4단계: RESETLOGS로 오픈 (마지막 수단)
ALTER DATABASE OPEN RESETLOGS;

-- 5단계: 오픈 후 즉시 전체 백업 수행
-- RMAN을 통한 즉시 백업
-- RMAN> BACKUP DATABASE PLUS ARCHIVELOG;

해결책 3: 파일 권한 및 경로 문제 해결

-- 현재 제어 파일에 등록된 Redo Log 경로 확인
SELECT GROUP#, MEMBER FROM V$LOGFILE;

-- OS 레벨에서 확인 (SQL*Plus 외부에서 실행)
-- ls -la /u01/app/oracle/oradata/ORCL/redo*.log
-- chown oracle:oinstall /u01/app/oracle/oradata/ORCL/redo*.log
-- chmod 640 /u01/app/oracle/oradata/ORCL/redo*.log

-- 경로가 다를 경우: 새 위치에 파일을 복사한 후 멤버 추가/제거
ALTER DATABASE ADD LOGFILE MEMBER
  '/new/path/oradata/ORCL/redo02b.log'
  TO GROUP 2;

-- 이전 잘못된 경로 멤버 제거
ALTER DATABASE DROP LOGFILE MEMBER '/old/path/redo02b.log';

해결책 4: RAC 스레드 비활성화

-- 활성화된 스레드 목록 확인
SELECT THREAD#, STATUS, ENABLED FROM V$THREAD;

-- 불필요한 스레드 비활성화
ALTER DATABASE DISABLE THREAD 2;

-- 해당 스레드의 로그 그룹 확인 후 제거
SELECT GROUP#, THREAD#, STATUS FROM V$LOG WHERE THREAD# = 2;
ALTER DATABASE DROP LOGFILE GROUP 4;
ALTER DATABASE DROP LOGFILE GROUP 5;

예방 방법

1. Redo Log 다중화(Multiplexing) 및 정기 상태 점검 자동화

Redo Log는 반드시 서로 다른 물리적 디스크(또는 ASM 디스크 그룹)에 2개 이상의 멤버로 다중화해야 합니다. 하나의 멤버가 손상되더라도 다른 멤버로 정상 운영이 가능하도록 구성하고, 아래와 같은 점검 스크립트를 크론잡(Cron Job)이나 Oracle Scheduler로 주기적으로 실행하여 INVALID 또는 STALE 상태의 멤버를 사전에 감지하세요.

-- Redo Log 이상 상태 점검 스크립트 (주기적 실행 권장)
SELECT l.GROUP#, l.THREAD#, l.SEQUENCE#, l.STATUS AS LOG_STATUS,
       lf.MEMBER, lf.STATUS AS MEMBER_STATUS,
       l.BYTES/1024/1024 AS SIZE_MB
FROM   V$LOG l
JOIN   V$LOGFILE lf ON l.GROUP# = lf.GROUP#
WHERE  lf.STATUS IN ('INVALID', 'STALE')
   OR  l.STATUS   IN ('UNUSED')
ORDER  BY l.THREAD#, l.GROUP#;

2. RMAN 백업 정책에 Archived Log 포함 및 Alert Log 모니터링 강화

ARCHIVELOG 모드를 반드시 활성화하고, RMAN 백업 정책에 Archived Redo Log를 포함시켜 최소한의 복구 지점을 항상 확보해야 합니다. 또한 Oracle Enterprise Manager(OEM) 또는 별도의 모니터링 툴을 활용하여 Alert Log에서 ORA-003xx 계열 에러가 발생하면 즉시 DBA에게 알림이 가도록 구성하면, 문제가 악화되기 전에 빠르게 대응할 수 있습니다.

-- ARCHIVELOG 모드 확인
SELECT LOG_MODE FROM V$DATABASE;

-- ARCHIVELOG 모드 활성화 (MOUNT 상태에서)
-- STARTUP MOUNT;
-- ALTER DATABASE ARCHIVELOG;
-- ALTER DATABASE OPEN;

-- 최근 아카이브 로그 생성 현황 확인
SELECT THREAD#, SEQUENCE#, NAME, COMPLETION_TIME
FROM   V$ARCHIVED_LOG
WHERE  COMPLETION_TIME > SYSDATE - 1
ORDER  BY COMPLETION_TIME DESC;

관련 에러

  • ORA-00312: 온라인 로그 파일 자체를 식별할 수 없을 때 발생하며, ORA-00320과 함께 Alert Log에 출력되는 경우가 많습니다.
  • ORA-00313: Redo Log 그룹의 멤버를 오픈(Open)하지 못할 때 발생하며, 파일 접근 권한이나 경로 문제가 주요 원인입니다.
  • ORA-00316: 파일 헤더가 Redo Log 형식이 아닌 다른 파일 타입으로 인식될 때 발생합니다.
  • ORA-00333: Redo Log 읽기 오류로 복구(Recovery) 작업이 중단될 때 발생합니다.
  • ORA-00345: Redo Log 파일에 쓰기 작업이 실패했을 때 발생하며, 스토리지 문제와 연관된 경우가 많습니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기