[Oracle] “ORA-00257: archiver error” 발생원인 및 조치방법

오라클 개발용 DB를 사용 중 아래와 같이 “ORA-00257: archiver error”가 발생하여 DB 연결까지 안되는 사태가 발생했습니다. ORA-00257 오류는 오라클 데이터베이스의 아카이브 로그 디렉토리가 가득 차서 더 이상 로그 파일을 생성할 수 없을 때 발생합니다. 그래서 Archive Log가 뭐고, ORA-00257 오류를 해결하는 방법에 대해 정리하고자 합니다.

Caused by: org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException:
ORA-00257: archiver error. Connect internal only, until freed.
  1. 아카이브 로그(Archive Log)란?
  2. FRA(Fast Recovery Area) 공간확보 방법: 보존 정책 기반 삭제
  3. FRA 공간확보 방법: 상태 기반 메타데이터 삭제

1. 아카이브 로그(Archive Log)란?

아카이브 로그는 오라클 데이터베이스에서 발생하는 모든 데이터 변경 사항을 기록한 파일의 복사본입니다. 이는 데이터베이스 복구의 핵심 요소입니다. 아래와 같은 절차로 생성됩니다.

Redo log, Archive Log
(출처: https://sapbasissolutions.wordpress.com/2018/11/26/how-oracle-database-redo-and-archived-logs-function/)
  1. 리두 로그 버퍼(Redo Log Buffer): 사용자가 INSERT, UPDATE, DELETE 등의 DML(데이터 조작어) 트랜잭션을 실행하면, 해당 변경 사항 정보(리두 엔트리)는 가장 먼저 SGA (System Global Area) 내의 메모리 영역에 있는 리두 로그 버퍼에 기록됩니다.
  2. 온라인 리두 로그(Online Redo Log) 파일: 백그라운드 프로세스인 LGWR(Log Writer)가 리두 로그 버퍼의 내용이 특정 조건(예: 1MB 이상의 변경, 3초 주기 등)을 만족할 때, 버퍼의 내용을 읽어 디스크의 온라인 리두 로그 파일에 순차적으로 기록합니다.
  3. 로그 스위치(Log Switch): 현재 사용 중인 리두 로그 그룹이 가득 차서 다음 그룹으로 전환될 때 (로그 스위치 발생), 오라클의 아카이버 프로세스(ARCH)가 가득 찬 리두 로그 그룹의 내용을 복사하여 별도의 디스크 공간에 저장합니다.
  4. 아카이브 로그 파일: 이렇게 복사되어 영구적으로 저장된 파일이 바로 아카이브 로그 파일 (Archive Redo Log File, ARC)입니다. 오래된 변경 기록(온라인 리두 로그)을 영구 보존하여, 미디어 장애(디스크 손상 등) 발생 시 데이터베이스를 복원하고 롤포워드(Roll-Forward) 복구를 수행할 때 사용됩니다.

FRA가 활성화되어 있으면 아카이브 로그 파일은 기본적으로 FRA 디렉토리에 저장됩니다. FRA 디렉토리가 물리적 또는 통계적으로 가득 차면 아카이브 로그는 더 이상 저장되지 않기 때문에 앞서 이야기한 것처럼 ORA-00257 오류가 발생합니다.

  • FRA 디렉토리를 확인하는 방법
    아카이브 로그 저장 경로: {DB_RECOVERY_FILE_DEST}/{DB_UNIQUE_NAME}/archivelog/{YYYY_MM_DD}/{파일명.arc}
    SQL> SHOW PARAMETER DB_RECOVERY_FILE_DEST;
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- -----------------------------------
    db_recovery_file_dest                string      /u02/app/oracle/fast_recovery_area/
    db_recovery_file_dest_size           big integer 600G
    
  • 물리적으로 가득 찬 경우는 리눅스 OS 관점에서 디스크 공간이 부족한 상태 ▶ 보존 정책 기반 삭제
    #확인방법 : Use%가 100%인지 확인
    $ df -h <FRA 경로의 마운팅 포인트>
    
  • 통계적으로 가득 찬 경우는 오라클 DB 관점에서 설정된 FRA 용량 제한에 도달한 상태 ▶ 상태 기반 메타데이터 삭제
    #확인방법 : USED_PCT가 100%인지 확인
    SELECT
        NAME,
        ROUND(SPACE_LIMIT / 1024 / 1024) AS "TOTAL_MB",
        ROUND(SPACE_USED / 1024 / 1024) AS "USED_MB",
        ROUND(SPACE_RECLAIMABLE / 1024 / 1024) AS "RECLAIMABLE_MB",
        ROUND((SPACE_USED / SPACE_LIMIT) * 100) AS "USED_PCT"
    FROM
        V$RECOVERY_FILE_DEST;
    < 컬럼 설명 > NAME FRA 경로 (리눅스 경로) TOTAL_MB FRA에 할당된 총 크기 (DB_RECOVERY_FILE_DEST_SIZE 파라미터 값) USED_MB 현재 사용 중인 크기 RECLAIMABLE_MB RMAN 정책에 따라 삭제되어 재활용 가능한 공간 크기 (백업이 완료된 아카이브 로그 등) USED_PCT FRA 공간 사용률 (%)

2. FRA 공간확보 방법: 보존 정책 기반 삭제

아카이브 로그를 보존 정책(Retention Policy) 기반으로 삭제하는 절차는 RMAN의 DELETE OBSOLETE 명령을 활용하는 것입니다. 이 방법은 데이터베이스의 복구 가능성을 깨뜨리지 않고 가장 안전하게 공간을 확보하는 표준 절차입니다.

  1. rman 접속
    $ rman target /
    
  2. 현재 보존 정책 확인
    • 복구 기간 기반 (Recovery Window) : 특정 기간(예: 7일) 내의 어떤 시점으로든 복구할 수 있도록 보장합니다. 가장 일반적인 방식입니다.
    • 중복 기반 (Redundancy) : 모든 데이터 파일 백업본을 지정된 횟수만큼 보존합니다.
    RMAN> SHOW RETENTION POLICY;
    (복구 기간 기반) RMAN retention policy is set to recovery window of 7 days
    (중복 기반) RMAN retention policy is set to redundancy 1
    
  3. 삭제 대상 확인(선택 사항)
    실제로 어떤 백업 및 아카이브 로그 파일이 삭제 대상인지 확인할 수 있습니다. 출력 목록에 있는 파일들은 현재 설정된 보존 정책을 만족시키고 남는 ‘잉여 파일’이므로 삭제해도 안전합니다.
    RMAN> REPORT OBSOLETE;
    
  4. 보존 정책에 따른 삭제 실행
    REPORT OBSOLETE;에 나왔던 모든 파일을 삭제하며, 아카이브 로그 역시 복구 기간 유지에 필요하지 않다면 함께 삭제됩니다.
    RMAN> DELETE OBSOLETE;
    
  5. 아카이브 로그 복사본 정리(선택 사항)
    만약 아카이브 로그를 복사본 형태로 관리하고 있다면, 다음 명령을 통해 OBSOLETE 처리된 아카이브 로그의 복사본도 함께 정리할 수 있습니다.
    RMAN> DELETE OBSOLETE ARCHIVELOG ALL;
    
  6. 백업이 성공적으로 완료된 아카이브 로그 파일 삭제(선택 사항)
    DELETE OBSOLETE;는 이미 백업된 로그가 아닌, 복구 정책상 필요 없는 로그만 삭제합니다. 만약 아카이브 로그가 너무 빨리 쌓여 보존 정책에 따라도 아직 삭제 시점이 되지 않았다면, 추가 공간 확보를 위해 아래 명령을 실행합니다.
    #모든 아카이브 로그를 읽어 백업 세트(Backup Set)로 생성한 후, 원본 아카이브 로그 파일들을 삭제합니다.
    RMAN> BACKUP ARCHIVELOG ALL DELETE INPUT;
    
    #압축된 백업 세트로 생성한 후, 원본 아카이브 로그 파일들을 삭제합니다.
    #BACKUPSET 저장 경로: {DB_RECOVERY_FILE_DEST}/{DB_UNIQUE_NAME}/backupset/{YYYY_MM_DD}/{백업파일.bkp}
    RMAN> BACKUP AS COMPRESSED BACKUPSET ARCHIVELOG ALL DELETE INPUT;
    
    #압축된 백업 세트를 생성하여 FRA가 아닌, 지정된 디렉토리에 저장합니다.
    RMAN> BACKUP FORMAT <디렉토리 경로> AS COMPRESSED BACKUPSET ARCHIVELOG ALL DELETE INPUT;
    
  7. DELETE OBSOLETE; 실행 스크립트 등록(선택 사항)
    oracle 사용자로 아래 쉘 스크립트 파일을 crontab에 등록하여 주기적으로 실행합니다.
    $ vi cleanup_obsolete.sh
    #!/bin/bash
    
    rman target / << EOF
    DELETE NOPROMPT OBSOLETE;
    
    EXIT;
    EOF
    
    find "{DB_RECOVERY_FILE_DEST}/{DB_UNIQUE_NAME}/archivelog/" -type d -empty -delete
    
  8. FRA 크기 확장(장기적인 해결책)
    #FRA 크기를 1000GB로 확장
    SQL> ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE = 1000G SCOPE=BOTH;
    

3. FRA 공간확보 방법: 상태 기반 메타데이터 삭제

리눅스 rm를 사용하여 아카이브 로그나 백업 파일을 디스크에서 직접 삭제했거나, 백업 파일이 저장된 디스크나 테이프 장치에 물리적인 오류가 발생하여 RMAN이 해당 파일에 접근할 수 없게 되었을 때 메타데이터를 삭제해야 합니다.

  1. RMAN 카탈로그(메타데이터) 동기화
    CROSSCHECK 명령어는 RMAN 메타데이터에 등록된 백업 파일이나 아카이브 로그가 실제 디스크에 존재하는지 확인합니다.
    • 만약 파일이 존재하면 상태는 AVAILABLE로 유지됩니다.
    • 만약 파일이 디스크에서 사라졌다면 (OS 명령어로 수동 삭제했거나, 디스크 오류 등으로 접근 불가능할 경우) 상태를 EXPIRED로 변경합니다.
    RMAN> CROSSCHECK BACKUP;
    RMAN> CROSSCHECK ARCHIVELOG ALL;
    
  2. 만료된 파일 삭제
    1단계에서 EXPIRED로 상태가 변경된 파일 정보를 RMAN 카탈로그에서 깨끗하게 제거하여 불일치 문제를 해결합니다.
    RMAN> DELETE EXPIRED BACKUP;
    RMAN> DELETE EXPIRED ARCHIVELOG ALL;
    CROSSCHECK 명령을 실행하지 않고 DELETE 명령을 실행하면 아래와 같은 오류가 발생합니다. RMAN의 메타데이터(카탈로그) 정보와 실제 디스크에 저장된 아카이브 로그 파일의 상태가 일치하지 않아 삭제하지 못한 파일이 있다는 경고입니다. RMAN-06207: WARNING: 165 objects could not be deleted for DISK channel(s) due RMAN-06208: to mismatched status. Use CROSSCHECK command to fix status RMAN-06210: List of Mismatched objects
  3. 실제 아카이브 파일 삭제 및 공간 확보
    위 두 단계를 완료하여 RMAN 카탈로그가 정리되었다면, 아카이브 로그 보관 정책에 따라 일정 기간이 경과한 로그 파일을 삭제합니다.
    # 예: 7일 이전 로그 삭제
    RMAN> DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE - 7';
    
  4. 백업 및 원본 삭제(가장 강력한 공간 확보 방법, 선택 사항)
    3단계로도 여전히 실패하고 로그가 삭제되지 않는다면, 해당 로그 파일이 특정 백업 세트에 필수적인 종속성을 가지고 있거나 손상되었을 가능성이 있습니다. 이 경우, 아카이브 로그 백업 후 원본을 즉시 삭제하는 DELETE INPUT 전략을 사용해 보세요.
    RUN {
      ALLOCATE CHANNEL disk1 DEVICE TYPE DISK;
      BACKUP
        ARCHIVELOG ALL DELETE INPUT; 
      RELEASE CHANNEL disk1;
    }
    
  5. 보존 정책 기반 삭제와 상태 기반 삭제를 모두 수행하는 자동화 쉘 스크립트(crontab 등록 방법)
    #!/bin/bash
    
    # ==========================================================
    # RMAN 포괄적 정리 스크립트: 메타데이터 정리 및 정책 기반 삭제
    # ----------------------------------------------------------
    
    # 오라클 환경 변수 설정 (필수: 실제 환경에 맞게 수정)
    export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1 
    export ORACLE_SID=ORCLDB                                  
    export PATH=$ORACLE_HOME/bin:$PATH
    
    # FRA 경로 설정 (필수: 실제 환경에 맞게 수정)
    FRA_DIR="/u02/app/oracle/fast_recovery_area"
    
    # 로그 파일 경로 설정 (필수: 실제 환경에 맞게 수정)
    LOG_DIR="/u01/app/oracle/scripts/log"
    LOG_FILE="$LOG_DIR/rman_full_cleanup_$(date +%Y%m%d%H%M%S).log"
    DATE_INFO=$(date '+%Y-%m-%d %H:%M:%S')
    
    # 로그 디렉토리가 없으면 생성 (오라클 유저 소유로)
    if [ ! -d "$LOG_DIR" ]; then
        mkdir -p "$LOG_DIR"
    fi
    
    # 로그 시작 기록
    echo "==========================================================" >> "$LOG_FILE"
    echo "RMAN Full Cleanup Start: $DATE_INFO" >> "$LOG_FILE"
    echo "==========================================================" >> "$LOG_FILE"
    
    
    # RMAN 명령어 실행 블록
    # ------------------------------------------------------------------------------------------------
    # 1. 메타데이터 정리 (상태 기반 삭제)
    # 2. 정책 기반 삭제
    # ------------------------------------------------------------------------------------------------
    rman target / log="$LOG_FILE" append << EOF
    
    # 섹션 1: 상태 기반 메타데이터 정리 (불일치 해소)
    # 1-1. 백업 세트 및 복사본, 아카이브 로그, 컨트롤파일 복사본 크로스 체크 (파일 존재 여부 확인)
    CROSSCHECK BACKUP;
    CROSSCHECK ARCHIVELOG ALL;
    CROSSCHECK COPY OF CONTROLFILE;
    # 1-2. EXPIRED로 표시된 백업 및 아카이브 로그 메타데이터 삭제
    DELETE NOPROMPT EXPIRED BACKUP;
    DELETE NOPROMPT EXPIRED ARCHIVELOG ALL;
    DELETE NOPROMPT EXPIRED COPY OF CONTROLFILE;
    
    # 섹션 2: 보존 정책 기반 삭제
    # 2-1. 삭제 대상 보고
    REPORT OBSOLETE;
    # 2-2. 보존 정책을 초과한 모든 백업 및 아카이브 로그 삭제
    DELETE NOPROMPT OBSOLETE;
    # 2-3. 필요 시 지정한 기간(15일) 이전에 완료된 복사본을 강제로 삭제
    #DELETE NOPROMPT BACKUP COMPLETED BEFORE 'SYSDATE - 15';
    #DELETE NOPROMPT ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE - 15';
    #DELETE NOPROMPT COPY OF CONTROLFILE COMPLETED BEFORE 'SYSDATE - 15';
    
    EXIT;
    EOF
    
    # RMAN 종료 시간 기록
    echo "==========================================================" >> "$LOG_FILE"
    echo "RMAN Full Cleanup Finished: $(date '+%Y-%m-%d %H:%M:%S')" >> "$LOG_FILE"
    echo "==========================================================" >> "$LOG_FILE"
    
    # 7일이 지난 오래된 스크립트 로그 파일 삭제
    find "$LOG_DIR" -type f -name 'rman_full_cleanup_*.log' -mtime +7 -exec rm {} \;
    
    # FRA 디렉토리의 빈 하위 디렉토리 삭제
    find "$FRA_DIR/archivelog/" -type d -empty -delete -print
    

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다