[Oracle 11gR2] Data Guard 기반의 백업 오프로딩(Backup Offloading) 구조 구현하기 – Part5

Data Guard 기반의 백업 오프로딩(Backup Offloading) 구조
아래 순서대로 “Data Guard 기반의 백업 오프로딩(Backup Offloading)” 환경구성 및 모의훈련을 실시할 예정입니다.


Part4에서는 실제 Primary DB에서 Standby DB로 데이터가 전송(백업)되는 것을 알아봤는데요, Part5에서는 실무에서 가장 빈번하게 발생하는 핵심 시나리오를 가지고 복구 모의훈련을 실시해 보겠습니다.


  1. DB가 오픈된 상태에서 Flashback 기능을 활용하는 시나리오
    • Primary DB와 Standby DB 모두에서 Flashback 기능이 활성화되어 있는지 확인합니다.
      -- Flashback 기능이 ON되어 있어야 합니다.
      SLQ> SELECT FLASHBACK_ON FROM V$DATABASE;
      FLASHBACK_ON
      ------------------
      YES
      
      -- DB_FLASHBACK_RETENTION_TARGET 파라미터 설정값(분 단위)이 설정되어 있어야 합니다
      SLQ> SHOW PARAMETER DB_FLASHBACK_RETENTION_TARGET; 
      NAME                                 TYPE        VALUE
      ------------------------------------ ----------- ------------------------------
      db_flashback_retention_target        integer     1440
      
    • 시나리오1: 실수로 지운 테이블 살리기 (Flashback Drop)
      -- 1. 휴지통에 테이블이 있는지 확인
      SQL> SHOW RECYCLEBIN;
      
      -- 2. FLASHBACK TABLE 명령으로 삭제한 테이블 복구
      SQL> FLASHBACK TABLE <테이블이름> TO BEFORE DROP; 
      
    • 시나리오2: 특정 시점의 테이블 조회 및 복구 (Flashback Query 및 Flashback Table)
      -- 1. 테이블별로 "ROW MOVEMENT" 기능 활성화
      SQL> ALTER TABLE <스키마>.<테이블이름> ENABLE ROW MOVEMENT;
      
      -- 2. "ROW MOVEMENT" 기능 활성화된 테이블 확인
      SQL> SELECT OWNER, TABLE_NAME, TABLESPACE_NAME, ROW_MOVEMENT
      FROM   DBA_TABLES
      WHERE  ROW_MOVEMENT = 'ENABLED';
      
      -- 3. 복구없이 쿼리로 이전 데이터 조회(Flashback Query)
      ---- "ROW MOVEMENT" 기능을 활성화할 필요없이 UNDO_RETENTION 파라미터 설정값(초 단위) 내에서 조회 가능
      SQL> SHOW PARAMETER UNDO_RETENTION;
      NAME                                 TYPE        VALUE
      ------------------------------------ ----------- ------------------------------
      undo_retention                       integer     3600
      ---- 1분 전 테이블 내용 조회
      SQL> SELECT * FROM <스키마>.<테이블이름> AS OF TIMESTAMP (SYSDATE - 60/(24*60*60)); 
      
      -- 4. 지정된 시간으로 테이블 되돌리기(Flashback Table)
      ---- 10분 전으로 테이블 되돌리기
      SQL> FLASHBACK TABLE <스키마>.<테이블이름> TO TIMESTAMP (SYSDATE - 10/1440);
      ---- 2026-03-05 13:10:00 기준으로 테이블 되돌리기
      SQL> FLASHBACK TABLE <스키마>.<테이블이름> TO TO_TIMESTAMP('2026-03-05 13:10:00', 'YYYY-MM-DD HH24:MI:SS')
      
    • 시나리오3: DB 전체를 과거로 되돌리기 (Flashback Database)
      대규모 Batch작업을 했는데 완전히 실패해서, DB 전체를 이전으로 돌려야 할 때 유용합니다.
      -- 1. Primary DB에서 복구가 가능한 최고(最古) 과거 시간 확인
      SQL> SELECT OLDEST_FLASHBACK_SCN, 
           RETENTION_TARGET,
           TO_CHAR(OLDEST_FLASHBACK_TIME, 'YYYY-MM-DD HH24:MI:SS') AS "복구_가능_최고_과거"
      FROM V$FLASHBACK_DATABASE_LOG;
      
      -- 2. Primary DB를 MOUNT 상태로 전환
      SQL> SHUTDOWN IMMEDIATE;
      SQL> STARTUP MOUNT;
      
      -- 3. Primary DB에서 FLASHBACK DATABASE 명령어 실행
      ---- 1시간 전으로 데이터베이스 복구
      SQL> FLASHBACK DATABASE TO TIMESTAMP (SYSDATE - 60/1440); 
      
      -- 4. 데이터베이스의 '새로운 생애(Incarnation)'를 시작하고, 그 시작점을 확인
      SQL> ALTER DATABASE OPEN RESETLOGS;
      SQL> SELECT RESETLOGS_CHANGE# AS REBIRTH_SCN FROM V$DATABASE;
      
      -- 5. Primary에서 RMAN 접속하여 새로운 생애(Incarnation)가 등록되었는지 확인 (Catalog 포함)
      [oracle@primary-db ~]$ rman target sys/orclsys@pri_db catalog rman_admin/orclsys@cat_db
      RMAN> LIST INCARNATION;
      
      -- 6. Standby DB에서 MRP 프로세스 중단
      SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
      
      -- 7. Standby DB에서 DB를 MOUNT 상태로 유지한 상태에서 Primary의 Resetlogs SCN(REBIRTH_SCN)으로 되감기
      SQL> FLASHBACK DATABASE TO SCN REBIRTH_SCN;
      
      -- 8. Standby DB 재시작 및 동기화(MRP) 프로세스 시작/확인
      ---- ARCH, MRP0, RFS 프로세스 확인
      SQL> SHUTDOWN IMMEDIATE;
      SQL> STARTUP MOUNT;
      SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION PARALLEL 4;
      SQL> SELECT PROCESS, STATUS, SEQUENCE# FROM V$MANAGED_STANDBY;
      
  2. 실수로 인한 데이터 삭제 (Logical Corruption) 시나리오
    1. 장애 발생 전후의 정확한 시간(TIMESTAMP) 확인한 후 임의 테이블에서 일부 데이터를 삭제합니다.
      SQL> SELECT sysdate FROM dual;
      SYSDATE
      -------------------
      2026-03-19 15:39:03
      
      SQL> SELECT MAX(seq_id) FROM dguser.tb_sysdate;
      MAX(SEQ_ID)
      -----------
            90000
      
      SQL> DELETE FROM dguser.tb_sysdate
      WHERE seq_id BETWEEN 80001 AND 90000;
      COMMIT;
      
    2. Primary DB 종료 후 MOUNT 상태로 시작합니다.
      SHUTDOWN IMMEDIATE;
      STARTUP MOUNT;
      
    3. RMAN에 접속한 후 백업 리스트를 확인합니다.
      $ rman target / catalog rman_admin/orclsys@CAT_DB
      RMAN> LIST BACKUP OF DATABASE;
      
    4. 장애 시점으로 설정하고 복구합니다.
      RMAN> RUN {
        SET UNTIL TIME "TO_DATE('2026-03-19 15:39:03', 'YYYY-MM-DD HH24:MI:SS')";
        RESTORE DATABASE;
        RECOVER DATABASE;
      }
      ....
      starting media recovery
      media recovery complete, elapsed time: 00:00:01
      
      Finished recover at 2026-03-19 15:50:11
      
    5. Primary DB를 오픈 및 새로운 세대가 CURRENT인지 확인
      -- RESETLOGS 옵션: 데이터베이스의 Log Sequence를 초기화하고 1번부터 다시 시작합니다.
      ---- 불완전 복구(Incomplete Recovery)를 수행했을 때만 사용하는 옵션으로 과거 특정 시점(Point-in-time)까지만 복구하고, 그 이후의 데이터는 포기하는 상황
      RMAN> ALTER DATABASE OPEN RESETLOGS;
      database opened
      new incarnation of database registered in recovery catalog
      starting full resync of recovery catalog
      full resync complete
      
      -- 새로운 세대가 CURRENT인지 확인
      RMAN> LIST INCARNATION;
      List of Database Incarnations
      DB Key  Inc Key DB Name  DB ID            STATUS  Reset SCN  Reset Time
      ------- ------- -------- ---------------- --- ---------- ----------
      1       14      ORCL11G  1333016804       PARENT  1          2013-08-24 11:37:30
      1       2       ORCL11G  1333016804       PARENT  925702     2026-02-25 08:21:58
      1       12340   ORCL11G  1333016804       CURRENT 3440932    2026-03-19 16:00:39
      
    6. 삭제된 데이터의 복구 확인
      SQL> SELECT MAX(seq_id) FROM dguser.tb_sysdate;
      MAX(SEQ_ID)
      -----------
            90000
      
    7. Standby DB 재구축: “Part1: Catalog DB → Primary DB → Standby DB 운영환경 구성” 글의 6.2를 참고하여 Standby DB 재구축
    8. Full Backup 수행: “Part2: Catalog DB 및 Standby DB를 활용한 백업환경 구성” 글의 3.3 백업 스크립트 사용
    9. (선택사항)“Part4: Primary DB → Standby DB로의 데이터 전송 테스트” 글을 참고하여 Standby DB에도 반영되었는지 확인해 봅니다. 확인 후 “Part3: 서버 중지 및 재기동 절차”에 따라 원복시킵니다.
      SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
      Database altered.
      
      SQL> ALTER DATABASE OPEN;
      Database altered.
      
      SQL> select max(seq_id) from dguser.tb_sysdate;
      MAX(SEQ_ID)
      -----------
            90000
      
  3. 비정상 종료 후 제어 파일(Control File) 유실 시나리오
    1. Primary DB의 모든 제어 파일이 삭제되어 DB가 OPEN되지 않는 상황을 만듭니다.
      -- control file의 저장 위치를 확인합니다.
      SQL> SELECT NAME FROM V$CONTROLFILE;
      NAME
      --------------------------------------------------------------------------------
      /u01/app/oracle/oradata/ORCL11G/control01.ctl
      /u01/app/oracle/fast_recovery_area/ORCL11G/control02.ctl
      
      -- OS레벨에서 control file를 삭제합니다.
      [oracle@primary-db ~]$ rm -rf /u01/app/oracle/oradata/ORCL11G/control01.ctl /u01/app/oracle/fast_recovery_area/ORCL11G/control02.ctl
      
      -- DB를 강제로 중지시킵니다.
      SQL> SHUTDOWN ABORT;
      
    2. RMAN에서 Recovery Catalog 접속한 후 control file을 복구합니다.
      -- Primary DB를 nomount 상태로 재기동합니다.
      RMAN> STARTUP NOMOUNT;
      
      -- AUTOBACKUP 기능을 통해 가장 최근의 컨트롤 파일을 되살립니다.
      RMAN> RESTORE CONTROLFILE FROM AUTOBACKUP;
      RMAN> RESTORE CONTROLFILE FROM '/path/to/control_file_backup';  # 특정 파일을 이용해 복구하는 경우 사용
      
      -- 컨트롤 파일이 복구되었으므로, 이를 읽어서 데이터베이스 구조를 인식시킵니다.
      RMAN> ALTER DATABASE MOUNT;
      
      -- 컨트롤 파일이 과거의 백업본이므로, 데이터 파일과의 SCN 정보를 맞추기 위해 Redo log나 Archive Log를 적용해야 합니다.
      RMAN> RESTORE DATABASE;  # 데이터 파일까지 유실된 경우만 실행
      RMAN> RECOVER DATABASE;
      
      -- 컨트롤 파일을 백업본에서 복구한 경우, 오라클은 "불완전 복구"로 간주하여 반드시 로그 시퀀스를 초기화해야 오픈을 허용합니다.
      RMAN> ALTER DATABASE OPEN RESETLOGS;
      
    3. control file이 복구되었는지 확인합니다.
      SQL> SELECT NAME FROM V$CONTROLFILE;
      NAME
      --------------------------------------------------------------------------------
      /u01/app/oracle/oradata/ORCL11G/control01.ctl
      /u01/app/oracle/fast_recovery_area/ORCL11G/control02.ctl
      
    4. 2.7단계와 2.8단계를 참고하여 Standby DB를 재구축합니다.
    5. Primary DB에서 Standby DB로 데이터 전송이 제대로 되는지 확인합니다.
      -- Primary DB에서 실행한 후
      SQL> exec dguser.proc_test_insert('NORMAL', 10000, 0.5);
      
      -- 위 프로시저가 종료될 때까지 Standby DB에서 프로세스 상태를 확인합니다.
      SQL> SELECT PROCESS, STATUS, SEQUENCE# FROM V$MANAGED_STANDBY;
      PROCESS   STATUS        SEQUENCE#
      --------- ------------ ----------
      ARCH      CONNECTED             0
      ARCH      CONNECTED             0
      ARCH      CONNECTED             0
      ARCH      CLOSING               5
      RFS       IDLE                  0
      RFS       IDLE                  0
      RFS       IDLE                  6
      MRP0      APPLYING_LOG          6
      8 rows selected.
      
      SQL> SELECT PROCESS, STATUS, SEQUENCE# FROM V$MANAGED_STANDBY;
      PROCESS   STATUS        SEQUENCE#
      --------- ------------ ----------
      ARCH      CONNECTED             0
      ARCH      CLOSING               6
      ARCH      CONNECTED             0
      ARCH      CLOSING               5
      RFS       IDLE                  0
      RFS       IDLE                  0
      RFS       IDLE                  7
      MRP0      APPLYING_LOG          7
      8 rows selected.
      
  4. 데이터 파일(Datafile) 물리적 손상 시나리오
    1. 데이터 파일의 물리적 손상을 인위적으로 만듭니다.
      -- Datafile을 확인합니다.
      SQL> set linesize 200;
      col file_name FOR A70;
      col tablespace_name FOR A25;
      col size_MBb FOR 9999;
      col status FOR A10;
      SELECT file_name, tablespace_name, bytes/1024/1024 as size_MB, status FROM DBA_DATA_FILES;
      FILE_NAME                                                              TABLESPACE_NAME           SIZE_MB STATUS
      ---------------------------------------------------------------------- ------------------------- ------- ----------
      /u01/app/oracle/oradata/ORCL11G/users01.dbf                            USERS                           5 AVAILABLE
      /u01/app/oracle/oradata/ORCL11G/undotbs01.dbf                          UNDOTBS1                       75 AVAILABLE
      /u01/app/oracle/oradata/ORCL11G/sysaux01.dbf                           SYSAUX                        820 AVAILABLE
      /u01/app/oracle/oradata/ORCL11G/system01.dbf                           SYSTEM                        750 AVAILABLE
      /u01/app/oracle/oradata/PRIDB/datafile/o1_mf_ts_data_ntdy5l6k_.dbf     TS_DATA                       100 AVAILABLE
      /u01/app/oracle/oradata/PRIDB/datafile/o1_mf_ts_indx_ntdy5wm6_.dbf     TS_INDX                       100 AVAILABLE
      
      6 rows selected.
      
      -- OS 레벨에서 특정 데이터 파일을 삭제하거나 다른 디렉토리로 이동시킵니다.
      [oracle@primary-db ~]$ mv /u01/app/oracle/oradata/PRIDB/datafile/o1_mf_ts_data_ntdy5l6k_.dbf /u01/app/oracle/oradata/PRIDB/
      
      -- Priamry DB를 재기동합니다.
      ---- 일반 데이터를 삭제하였다면 재기동이 필요없을 수 있으나, 시스템 데이터(System, Undo)가 삭제되었다면 MOUNT 상태로 재기동해야 합니다.
      SQL> SHUTDOWN ABORT;
      SQL> STARTUP;
      
      -- 5번 데이터 파일이 손상된 것을 확인합니다.
      SQL> col file# FOR 99;
      col online_status FOR A15;
      col error FOR A20;
      select FILE#, ONLINE_STATUS, ERROR from v$recover_file;
      FILE# ONLINE_STATUS   ERROR
      ----- --------------- --------------------
          5 ONLINE          FILE NOT FOUND
      
    2. RMAN에 접속하여 복구합니다.(rman target /)
      -- 손상된 5번 데이터 파일을 OFFLINE 상태로 변경합니다.
      RMAN> SQL "ALTER DATABASE DATAFILE 5 OFFLINE";
      using target database control file instead of recovery catalog
      sql statement: ALTER DATABASE DATAFILE 5 OFFLINE
      
      -- 데이터 파일을 복원합니다.(RESTORE)
      ---- 백업 파일(Backup Set 또는 Image Copy)로부터 물리적인 데이터 파일, 컨트롤 파일 등을 원래 위치(또는 지정된 위치)로 다시 가져다 놓는 작업입니다.
      RMAN> RESTORE DATAFILE 5;
      
      -- 데이터 파일을 복구합니다.(RECOVER)
      ---- 복원된 파일에 백업 이후 발생한 변경 사항(Redo Log, Archive Log)을 적용하여 현재 시점(또는 특정 시점)까지 데이터를 맞추는 작업입니다.
      RMAN> RECOVER DATAFILE 5;
      
      -- 복구가 완료된 파일을 다시 사용 가능한 상태로 만듭니다.
      RMAN> SQL "ALTER DATABASE DATAFILE 5 ONLINE";
      
      -- 데이터베이스를 OPEN 상태로 변경합니다.
      RMAN> SQL "ALTER DATABASE OPEN";
      
    3. 데이터 파일의 정상적으로 생성되었는지 확인합니다.
      SQL> set linesize 200;
      col file_name FOR A70;
      col tablespace_name FOR A25;
      col size_MBb FOR 9999;
      col status FOR A10;
      SELECT file_name, tablespace_name, bytes/1024/1024 as size_MB, status FROM DBA_DATA_FILES;
      FILE_NAME                                                              TABLESPACE_NAME              SIZE_MB STATUS
      ---------------------------------------------------------------------- ------------------------- ---------- ----------
      /u01/app/oracle/oradata/ORCL11G/users01.dbf                            USERS                              5 AVAILABLE
      /u01/app/oracle/oradata/ORCL11G/undotbs01.dbf                          UNDOTBS1                          75 AVAILABLE
      /u01/app/oracle/oradata/ORCL11G/sysaux01.dbf                           SYSAUX                           820 AVAILABLE
      /u01/app/oracle/oradata/ORCL11G/system01.dbf                           SYSTEM                           750 AVAILABLE
      /u01/app/oracle/oradata/PRIDB/datafile/o1_mf_ts_data_nvsck606_.dbf     TS_DATA                          100 AVAILABLE
      /u01/app/oracle/oradata/PRIDB/datafile/o1_mf_ts_indx_ntdy5wm6_.dbf     TS_INDX                          100 AVAILABLE
      
      6 rows selected.
      
  5. 아카이브 로그 갭(Archive Gap) 발생 시나리오
    1. Primary DB: Archive Log 파일 확인
      -- 최신 데이터를 아카이브화하여 Standby DB로 강제로 '밀어내기(Push)' 하는 역할을 수행합니다.
      SQL> ALTER SYSTEM ARCHIVE LOG CURRENT;
      
      -- STANDBY_APPLIED가 "NO"인 Archive Log가 있는지 확인합니다.
      ---- "/"로 반복 실행하여 변경사항이 없으면 다음 단계를 진행합니다.
      SQL> set linesize 200;
      col LOCAL_PATH FOR A100;
      col STANDBY_APPLIED FOR A20;
      SELECT A.SEQUENCE#, 
             A.NAME AS LOCAL_PATH,
             A.RESETLOGS_ID,
             B.APPLIED AS STANDBY_APPLIED,
             A.FIRST_TIME,
             A.COMPLETION_TIME
      FROM   V$ARCHIVED_LOG A
      LEFT JOIN V$ARCHIVED_LOG B 
             ON A.SEQUENCE# = B.SEQUENCE# AND B.DEST_ID = 2
      WHERE  A.DEST_ID = 1
      AND    A.NAME IS NOT NULL
      AND   (B.APPLIED = 'NO' OR B.APPLIED IS NULL)
      ORDER BY A.SEQUENCE# DESC;
      
       SEQUENCE# LOCAL_PATH                                                                                           RESETLOGS_ID STANDBY_APPLIED      FIRST_TIME          COMPLETION_TIME
      ---------- ---------------------------------------------------------------------------------------------------- ------------ -------------------- ------------------- -------------------
             172 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_172_nvssdyo9_.arc               1228380722 NO                   2026-03-20 15:08:37 2026-03-20 15:13:50
      
    2. Primary DB: Archive Log 전송 중단 상황 설정
      -- 로그 전송 경로(LOG_ARCHIVE_DEST_2)를 DEFER 상태로 변경하여 전송을 중단시킵니다.
      SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=DEFER;
      
    3. Primary DB: 데이터 입력 및 로그 스위치 발생
      SQL> exec dguser.proc_test_insert('NORMAL', 2000, 0);
      
    4. Standby DB: MRP 프로세스의 상태를 확인합니다.
      SQL> SELECT PROCESS, STATUS, SEQUENCE# FROM V$MANAGED_STANDBY WHERE PROCESS LIKE 'MRP%';
      PROCESS   STATUS        SEQUENCE#
      --------- ------------ ----------
      MRP0      WAIT_FOR_LOG        174
      
    5. Primary DB: STANDBY_APPLIED가 “NO”인 Archive Log를 다시 확인합니다.
      SQL> SELECT A.SEQUENCE#, 
             A.NAME AS LOCAL_PATH,
             A.RESETLOGS_ID,
             B.APPLIED AS STANDBY_APPLIED,
             A.FIRST_TIME,
             A.COMPLETION_TIME
      FROM   V$ARCHIVED_LOG A
      LEFT JOIN V$ARCHIVED_LOG B 
             ON A.SEQUENCE# = B.SEQUENCE# AND B.DEST_ID = 2
      WHERE  A.DEST_ID = 1
      AND    A.NAME IS NOT NULL
      AND   (B.APPLIED = 'NO' OR B.APPLIED IS NULL)
      ORDER BY A.SEQUENCE# DESC;
      
       SEQUENCE# LOCAL_PATH                                                                                           RESETLOGS_ID STANDBY_APPLIED      FIRST_TIME          COMPLETION_TIME
      ---------- ---------------------------------------------------------------------------------------------------- ------------ -------------------- ------------------- -------------------
             182 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_182_nvsts1dk_.arc               1228380722                      2026-03-20 15:37:18 2026-03-20 15:37:21
             181 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_181_nvstrybd_.arc               1228380722                      2026-03-20 15:37:15 2026-03-20 15:37:18
             180 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_180_nvstrv85_.arc               1228380722                      2026-03-20 15:37:12 2026-03-20 15:37:15
             179 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_179_nvstrr5x_.arc               1228380722                      2026-03-20 15:37:09 2026-03-20 15:37:12
             178 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_178_nvstro6v_.arc               1228380722                      2026-03-20 15:37:06 2026-03-20 15:37:09
             177 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_177_nvstrl4s_.arc               1228380722                      2026-03-20 15:37:03 2026-03-20 15:37:06
             176 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_176_nvstrh51_.arc               1228380722                      2026-03-20 15:37:03 2026-03-20 15:37:03
             175 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_175_nvstrh2s_.arc               1228380722                      2026-03-20 15:36:59 2026-03-20 15:37:03
             174 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_174_nvstrcz5_.arc               1228380722                      2026-03-20 15:36:59 2026-03-20 15:37:00
             173 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_173_nvstrcwd_.arc               1228380722 NO                   2026-03-20 15:13:50 2026-03-20 15:36:59
             172 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_172_nvssdyo9_.arc               1228380722 NO                   2026-03-20 15:08:37 2026-03-20 15:13:50
      
    6. 178번 파일(2026_03_20/o1_mf_1_178_nvstro6v_.arc)을 복사한 후 삭제하여 Archive Log 파일이 없는 상태를 만듭니다.
      SQL> !cp /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_178_nvstro6v_.arc /u01/app/oracle/fast_recovery_area/PRIDB/archivelog
      SQL> !rm -rf /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_178_nvstro6v_.arc
      
    7. Primary DB: Archive Log 전송 시작
      -- 로그 전송 경로(LOG_ARCHIVE_DEST_2)를 ENABLE 상태로 변경하여 전송을 시작합니다.
      SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=ENABLE;
      
    8. Standby DB: Archive Log Gap을 확인합니다.
      -- 178번 파일에서 GAP이 발생했다는 정보가 표시됩니다.
      SQL> SELECT * FROM V$ARCHIVE_GAP;
         THREAD# LOW_SEQUENCE# HIGH_SEQUENCE#
      ---------- ------------- --------------
               1           178            178
      
      -- MRP 프로세스의 상태가 WAIT_FOR_GAP 입니다. 
      SQL> SELECT PROCESS, STATUS, SEQUENCE# FROM V$MANAGED_STANDBY WHERE PROCESS LIKE 'MRP%';
      PROCESS   STATUS        SEQUENCE#
      --------- ------------ ----------
      MRP0      WAIT_FOR_GAP        178
      
    9. Primary DB: STANDBY_APPLIED가 “NO”인 Archive Log를 다시 확인합니다.
      -- 178번 파일에서 더 이상 진행하지 않고 멈춰있습니다.
      SQL> SELECT A.SEQUENCE#, 
             A.NAME AS LOCAL_PATH,
             A.RESETLOGS_ID,
             B.APPLIED AS STANDBY_APPLIED,
             A.FIRST_TIME,
             A.COMPLETION_TIME
      FROM   V$ARCHIVED_LOG A
      LEFT JOIN V$ARCHIVED_LOG B 
             ON A.SEQUENCE# = B.SEQUENCE# AND B.DEST_ID = 2
      WHERE  A.DEST_ID = 1
      AND    A.NAME IS NOT NULL
      AND   (B.APPLIED = 'NO' OR B.APPLIED IS NULL)
      ORDER BY A.SEQUENCE# DESC;
       SEQUENCE# LOCAL_PATH                                                                                           RESETLOGS_ID STANDBY_APPLIED      FIRST_TIME          COMPLETION_TIME
      ---------- ---------------------------------------------------------------------------------------------------- ------------ -------------------- ------------------- -------------------
             183 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_183_nvsv7d9w_.arc               1228380722 NO                   2026-03-20 15:37:21 2026-03-20 15:45:00
             182 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_182_nvsts1dk_.arc               1228380722 NO                   2026-03-20 15:37:18 2026-03-20 15:37:21
             181 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_181_nvstrybd_.arc               1228380722 NO                   2026-03-20 15:37:15 2026-03-20 15:37:18
             180 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_180_nvstrv85_.arc               1228380722 NO                   2026-03-20 15:37:12 2026-03-20 15:37:15
             179 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_179_nvstrr5x_.arc               1228380722 NO                   2026-03-20 15:37:09 2026-03-20 15:37:12
             178 /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/2026_03_20/o1_mf_1_178_nvstro6v_.arc               1228380722                      2026-03-20 15:37:06 2026-03-20 15:37:09
      
    10. Primary DB에서 LOG_ARCHIVE_DEST_STATE_2=ENABLE를 설정하면 다시 전송되지만, 자동 복구가 안되는 경우에 Primary에서 해당 파일을 직접 복사해와서 Standby에 등록합니다.
      -- Primary DB에서 삭제한 Archive Log 파일을 공유 디렉토리(/backup_data/)로 복사하거나,
      -- scp 명령어 등을 사용해서 Standby DB 서버로 전송합니다.
      SQL> !cp /u01/app/oracle/fast_recovery_area/PRIDB/archivelog/o1_mf_1_178_nvstro6v_.arc /backup_data/
      
      -- Standby DB에서 누락된 Archive Log 파일을 강제로 등록하면 정상적으로 등록됩니다.
      SQL> !mv /backup_data/o1_mf_1_178_nvstro6v_.arc /u01/app/oracle/fast_recovery_area/STBDB/archivelog/2026_03_20/o1_mf_1_178_nvstro6v_.arc
      SQL> ALTER DATABASE REGISTER LOGFILE '/u01/app/oracle/fast_recovery_area/STBDB/archivelog/2026_03_20/o1_mf_1_178_nvstro6v_.arc';
      SQL> SELECT PROCESS, STATUS, SEQUENCE# FROM V$MANAGED_STANDBY WHERE PROCESS LIKE 'MRP%';
      PROCESS   STATUS        SEQUENCE#
      --------- ------------ ----------
      MRP0      APPLYING_LOG        184
      

You may also like...

답글 남기기

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