안동민 개발노트 아이콘

안동민 개발노트

12장 : 복구와 로깅

복구 실무

이론적인 복구 원리를 이해했다면, 실무에서 사용하는 Oracle 중심의 복구 도구와 백업 전략을 다룹니다. 복구 실무의 목표는 장애 유형을 빠르게 분류하고, 남아 있는 백업과 로그 체인을 기준으로 데이터 손실 범위와 복구 시간을 통제하는 것입니다. 핵심은 "가장 최신 상태로 갈 것인가", "특정 시점으로 되돌릴 것인가", "전체 DB를 복구할 것인가, 일부 객체만 살릴 것인가"를 초기에 분리하는 것입니다.


복구의 분류

데이터베이스 복구는 장애 유형과 범위에 따라 분류됩니다.

복구 유형원인자동/수동주된 기준
인스턴스 복구정전, 인스턴스 비정상 종료자동온라인 redo와 데이터 파일
완전 미디어 복구데이터 파일 손상, 파일 유실수동백업 + 필요한 redo/archive
불완전 미디어 복구사용자 실수, 논리적 오류수동목표 시점 + RESETLOGS
Flashback잘못된 DML, DROP, 논리 오류수동Undo, recyclebin, flashback log

Oracle 인스턴스 복구

Oracle 인스턴스(SGA와 백그라운드 프로세스 집합)가 비정상 종료된 후 재시작하면 일반적으로 인스턴스 복구가 자동으로 수행됩니다. 데이터 파일, 제어 파일, 온라인 redo 자체가 손상되지 않은 경우, STARTUP 과정에서 온라인 redo를 이용해 캐시 복구와 트랜잭션 복구를 진행합니다.

캐시 복구가 끝나 데이터베이스가 열린 뒤에도 일부 트랜잭션 정리는 백그라운드에서 계속될 수 있습니다. 필요한 블록은 먼저 되돌리는 on-demand rollback도 사용되어, 사용자 접속 재개와 남은 rollback 작업을 분리합니다. 이러한 복구 시간 관리는 Fast-Start Instance Recovery와 MTTR 목표 설정과 연결됩니다.


RMAN (Recovery Manager)

RMAN은 Oracle이 제공하는 물리 백업·복구 관리자입니다. 백업 메타데이터, archived redo 처리, 블록 검증, 증분 백업, 압축 백업 같은 기능을 Oracle 내부 구조와 연결해 다룹니다. OS 수준 복사나 스토리지 스냅샷도 사용할 수 있지만, BEGIN BACKUP/스냅샷 일관성, archived redo 보존, 복구 검증을 별도로 관리해야 합니다.

RMAN 기본 명령어
──── RMAN 접속 ────
$ rman target /                          -- 로컬 접속
$ rman target sys@orcl catalog rman@catdb -- 비밀번호는 프롬프트/지갑 사용 권장

──── 백업 ────
-- 전체 백업 (데이터파일 + 제어 파일 + 아카이브 로그)
RMAN> BACKUP DATABASE PLUS ARCHIVELOG;

-- 증분 백업 (레벨 0 = 전체, 레벨 1 = 변경분)
RMAN> BACKUP INCREMENTAL LEVEL 0 DATABASE;
RMAN> BACKUP INCREMENTAL LEVEL 1 DATABASE;
RMAN> BACKUP INCREMENTAL LEVEL 1 CUMULATIVE DATABASE;

-- 테이블스페이스 백업
RMAN> BACKUP TABLESPACE users_ts;

-- 압축 백업
RMAN> BACKUP AS COMPRESSED BACKUPSET DATABASE;

-- 특정 데이터파일 백업
RMAN> BACKUP DATAFILE '/oradata/users01.dbf';

──── 복구 ────
-- 완전 복구: 필요한 redo를 모두 적용할 수 있는 경우
RMAN> STARTUP MOUNT;
RMAN> RESTORE DATABASE;
RMAN> RECOVER DATABASE;
RMAN> ALTER DATABASE OPEN;

-- 불완전 복구/PITR: 목표 시점까지만 적용하는 경우
RMAN> RUN {
  SET UNTIL TIME "TO_DATE('2024-03-15 13:55:00', 'YYYY-MM-DD HH24:MI:SS')";
  RESTORE DATABASE;
  RECOVER DATABASE;
}
RMAN> ALTER DATABASE OPEN RESETLOGS; -- 새 incarnation 시작

-- RESETLOGS가 필요한 대표 상황:
-- 목표 시점 복구, backup control file 사용 복구, redo branch 변경

-- 테이블스페이스 복구 (온라인 상태에서)
RMAN> SQL 'ALTER TABLESPACE users_ts OFFLINE IMMEDIATE';
RMAN> RESTORE TABLESPACE users_ts;
RMAN> RECOVER TABLESPACE users_ts;
RMAN> SQL 'ALTER TABLESPACE users_ts ONLINE';

-- 데이터파일 복구
RMAN> SQL 'ALTER DATABASE DATAFILE 5 OFFLINE';
RMAN> RESTORE DATAFILE 5;
RMAN> RECOVER DATAFILE 5;
RMAN> SQL 'ALTER DATABASE DATAFILE 5 ONLINE';

RMAN 증분 백업 상세

증분 백업은 변경된 블록만 백업해 시간과 공간을 줄이는 전략입니다. 다만 복구 시에는 기준 Level 0 백업과 이후 필요한 증분 백업, archived redo가 함께 있어야 하므로 백업 체인 관리가 중요합니다. RMAN의 차등 증분(differential)은 직전 Level 0 또는 Level 1 이후 변경분이고, 누적 증분(cumulative)은 마지막 Level 0 이후 변경분을 계속 누적합니다.

Block Change Tracking
-- 변경 블록 추적 활성화 (증분 백업 성능 향상)
ALTER DATABASE ENABLE BLOCK CHANGE TRACKING
  USING FILE '/oradata/bct/change_tracking.f';

효과:
* 증분 백업 시 변경 블록 후보를 더 빠르게 찾음
* 변경 추적 파일의 bitmap을 이용해 스캔 부담 감소
* 대용량 DB에서 백업 시간을 줄일 수 있으나 변경량, 파일 위치, 추적 파일 손상 여부에 영향받음

상태 확인:
SELECT filename, status, bytes
FROM V$BLOCK_CHANGE_TRACKING;

백업 전략

전략설명복구 특성저장 공간
전체/Level 0 백업복구 기준이 되는 전체 물리 백업단순하지만 큼많음
차등 증분 Level 1직전 Level 0 또는 Level 1 이후 변경백업은 작고 체인이 김적음
누적 증분 Level 1마지막 Level 0 이후 누적 변경복구 단계가 비교적 단순중간~증가
archived redo/binlog/WAL백업 이후 변경 재생 로그PITR과 최신 복구의 핵심정책 의존

아카이브 로그 모드

Oracle에서 온라인 백업과 미디어 복구, PITR을 운영하려면 archived redo를 보존하는 ARCHIVELOG 모드가 핵심 조건입니다. NOARCHIVELOG 모드는 운영 방식이 단순하지만, 운영 중 온라인/hot 백업과 백업 이후 미디어 복구가 사실상 불가능합니다. 장애 후 복구 가능 범위는 보통 마지막 일관된 cold backup 시점에 가깝게 제한됩니다.


물리적 백업 vs 논리적 백업

구분물리적 백업논리적 백업
대상데이터 파일과 로그 체인테이블, 스키마, 메타데이터
도구RMAN, 스토리지 스냅샷, 백업 제품Data Pump(expdp/impdp), dump
장점대용량 재해 복구와 PITR에 적합이동, 부분 추출, 마이그레이션
한계DBMS/버전/플랫폼 제약 확인 필요전체 장애 복구 수단으로는 부족
일관성로그와 체크포인트 기준export 옵션과 Undo 기준

논리 백업에서 여러 테이블 간 같은 시점의 일관성이 중요하다면 Data Pump에 FLASHBACK_TIME 또는 FLASHBACK_SCN을 지정하는 것이 안전합니다. 그렇지 않으면 객체별 export 시점과 Undo 보존 상태에 따라 기대한 전체 스냅샷과 다르게 보일 수 있습니다.

Data Pump 사용법 (Oracle)
──── 디렉토리 오브젝트 생성 ────
CREATE DIRECTORY dump_dir AS '/backup/dumps';
GRANT READ, WRITE ON DIRECTORY dump_dir TO hr;

──── 스키마 단위 백업 (Export) ────
$ expdp hr/password \
    schemas=HR \
    directory=DUMP_DIR \
    dumpfile=hr_%U.dmp \
    filesize=2G \
    parallel=4 \
    logfile=hr_exp.log

──── 테이블 단위 백업 ────
$ expdp hr/password \
    tables=EMPLOYEES,DEPARTMENTS \
    directory=DUMP_DIR \
    dumpfile=tables.dmp

──── 복원 (Import) ────
$ impdp system/password \
    schemas=HR \
    directory=DUMP_DIR \
    dumpfile=hr_%U.dmp \
    parallel=4 \
    remap_schema=HR:HR_NEW \
    logfile=hr_imp.log

──── 주요 옵션 ────
CONTENT=DATA_ONLY    -- 데이터만 (DDL 제외)
CONTENT=METADATA_ONLY -- DDL만 (데이터 제외)
EXCLUDE=TABLE:"='TEMP_LOG'"  -- 특정 테이블 제외
QUERY=EMPLOYEES:"WHERE hire_date > DATE '2023-01-01'"
                             -- 조건부 백업

MySQL/PostgreSQL 백업 도구

Oracle 외 DBMS도 백업의 기본 구조는 비슷합니다. 물리 백업은 재해 복구와 PITR의 기준이 되고, 논리 백업은 이관·부분 복원·검증 용도에 더 잘 맞습니다. 단, PITR에 쓰는 로그는 제품마다 계층이 다릅니다. MySQL의 binary log는 InnoDB redo log와 다른 서버 계층 로그이고, PostgreSQL의 archived WAL은 물리 복구의 핵심 로그입니다.

MySQL 백업 도구
──── mysqldump (논리적 백업) ────
$ mysqldump -u root -p \
    --single-transaction \
    --routines --triggers --events \
    mydb > mydb_backup.sql

$ mysqldump -u root -p \
    --single-transaction \
    --all-databases > full_backup.sql

복원:
$ mysql -u root -p mydb < mydb_backup.sql

──── MySQL Shell Dump Utilities (논리적 백업) ────
mysqlsh> util.dumpInstance('/backup/mysql-shell-dump', {
    threads: 4,
    consistent: true
})

──── Percona XtraBackup (물리적 백업, 핫 백업) ────
$ xtrabackup --backup --target-dir=/backup/full
$ xtrabackup --prepare --target-dir=/backup/full
$ xtrabackup --copy-back --target-dir=/backup/full

특징
* InnoDB 물리 핫 백업
* 증분 백업 지원
* 압축/암호화 지원
* 복구 copy-back 전에는 대상 datadir 상태와 MySQL 중지 여부 확인 필요

PITR (Point-in-Time Recovery)

특정 시점까지 데이터베이스를 복원하는 기법입니다. 사용자가 실수로 대량 데이터를 삭제했을 때 유력한 복구 방법이지만, 기준 백업과 목표 시점까지 이어지는 로그 체인이 남아 있어야 합니다. 전체 DB PITR은 목표 시점 이후의 정상 변경도 함께 제외할 수 있으므로, 가능하면 별도 복구 환경에 되살린 뒤 필요한 데이터만 추출하는 절차도 검토합니다.


Oracle Flashback

Flashback은 Oracle의 과거 시점 조회·복구 기능 묶음입니다. RMAN 복구보다 범위가 작고 빠른 선택지가 될 수 있지만, Undo 보존 기간, recyclebin, flashback log 설정 등 기능별 전제 조건을 확인해야 합니다. Flashback은 논리 오류 대응에 강하지만 데이터 파일 손상이나 로그 체인 손실을 대신하지는 못합니다.

Flashback 유형용도의존 기술
Flashback Query특정 시점의 데이터 조회Undo 세그먼트
Flashback Version Query데이터 변경 이력 추적Undo 세그먼트
Flashback Transaction Query트랜잭션 단위 변경 조회Undo + Supplemental Log
Flashback Table테이블을 과거 시점으로 되돌림Undo 세그먼트
Flashback DropDROP된 테이블 복원 (휴지통)Recyclebin
Flashback Database전체 DB를 과거 시점으로 복원Flashback Log

Flashback Table은 대상 테이블의 row movement, 제약 관계, DDL 이력에 영향을 받을 수 있습니다. Flashback Database는 사전에 Flashback Database가 활성화되어 있고 Fast Recovery Area 등 flashback log 저장 공간이 준비되어 있어야 합니다.

Flashback Query
-- 1시간 전 데이터 조회
SELECT * FROM users
AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' HOUR)
WHERE id = 101;

-- SCN 기반 과거 데이터 조회
SELECT * FROM orders
AS OF SCN 12345678
WHERE order_id = 999;

-- 현재 vs 과거 비교 (실수 확인)
SELECT curr.*, past.salary AS old_salary
FROM employees curr,
     employees AS OF TIMESTAMP
       (SYSTIMESTAMP - INTERVAL '2' HOUR) past
WHERE curr.employee_id = past.employee_id
  AND curr.salary <> past.salary;
Flashback Version Query (변경 이력)
-- 특정 행의 모든 변경 이력 조회
SELECT versions_starttime, versions_endtime,
       versions_operation, -- I(Insert), U(Update), D(Delete)
       employee_id, salary
FROM employees
VERSIONS BETWEEN TIMESTAMP
  SYSTIMESTAMP - INTERVAL '1' DAY AND SYSTIMESTAMP
WHERE employee_id = 101;

-- versions_operation은 작업 종류를 보여줌
-- 트랜잭션 상세는 versions_xid와 FLASHBACK_TRANSACTION_QUERY 등 추가 조회 필요
Flashback Table & Drop
-- 실수로 삭제한 테이블 복원 (휴지통에서)
FLASHBACK TABLE users TO BEFORE DROP;
FLASHBACK TABLE users TO BEFORE DROP RENAME TO users_restored;

-- 테이블을 특정 시점으로 되돌림
ALTER TABLE orders ENABLE ROW MOVEMENT;  -- 사전 설정 필수
FLASHBACK TABLE orders TO TIMESTAMP
  TO_TIMESTAMP('2024-01-15 14:30:00', 'YYYY-MM-DD HH24:MI:SS');

복구 시나리오별 대응 절차

실무에서 발생할 수 있는 다양한 장애 시나리오와 대응 방법입니다.

시나리오 1: 데이터파일 손실
상황: /oradata/users01.dbf 파일 손실 (디스크 장애)

즉시 대응:
1. 해당 테이블스페이스 오프라인
   SQL> ALTER TABLESPACE users_ts OFFLINE IMMEDIATE;

2. RMAN으로 데이터파일 복원
   RMAN> RESTORE DATAFILE '/oradata/users01.dbf';

3. 아카이브 로그 적용 (완전 복구)
   RMAN> RECOVER DATAFILE '/oradata/users01.dbf';

4. 테이블스페이스 온라인
   SQL> ALTER TABLESPACE users_ts ONLINE;

※ 손상 범위와 테이블스페이스 상태에 따라 온라인 복구가 가능할 수 있음
시나리오 2: 전체 DB 손실 (재해 복구)
상황: 서버 전체 재해 (화재, 장비 손실)

복구 절차
1. 새 서버에 Oracle 설치 및 환경 변수/스토리지 경로 준비
2. SPFILE 또는 pfile 확보 후 NOMOUNT 시작
   SQL> STARTUP NOMOUNT;
3. 복구 카탈로그 또는 control file autobackup 사용 여부 확인
   RMAN> SET DBID 123456789;  -- 카탈로그가 없을 때 필요할 수 있음
4. RMAN으로 제어 파일 복원
   RMAN> RESTORE CONTROLFILE FROM '/backup/ctrl.bkp';
5. DB MOUNT
   RMAN> ALTER DATABASE MOUNT;
6. 데이터파일 복원
   RMAN> RESTORE DATABASE;
7. 아카이브 로그 적용
   RMAN> RECOVER DATABASE;
8. DB OPEN
   RMAN> ALTER DATABASE OPEN RESETLOGS;
9. 즉시 전체 백업 수행

전제 조건: 제어 파일/SPFILE, 데이터파일 백업, 필요한 archived redo가 원격지나 별도 장애 도메인에 남아 있어야 함

※ 현재 제어 파일과 필요한 redo를 모두 확보한 완전 복구라면 RESETLOGS가 필요하지 않을 수 있습니다. 백업 제어 파일을 사용했거나 불완전 복구를 수행한 경우에는 일반적으로 RESETLOGS로 새 incarnation을 시작합니다.

백업 검증과 복구 테스트

백업은 복원 절차까지 검증되어야 의미가 있습니다. 정기적으로 백업 조각을 검증하고, 별도 환경에서 복구 리허설을 수행해야 RTO와 RPO를 현실적으로 판단할 수 있습니다. RESTORE VALIDATECROSSCHECK는 중요한 점검이지만 실제 서비스 기동, 애플리케이션 무결성, 권한·연동까지 검증하는 복구 리허설을 대체하지는 못합니다.


백업 보존 정책

보존 정책은 "백업 파일을 얼마나 오래 둘 것인가"가 아니라 언제까지 실제로 복구할 수 있어야 하는가를 정하는 운영 규칙입니다. RMAN에서는 CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF n DAYS처럼 복구 가능 기간을 기준으로 잡거나, REDUNDANCY n으로 백업 중복 개수를 기준으로 잡을 수 있습니다.

DELETE OBSOLETE는 보존 정책상 더 이상 필요 없는 백업을 정리하고, CROSSCHECK는 RMAN 카탈로그의 기록과 실제 파일 존재 여부를 대조합니다. 이때 EXPIRED는 기록은 있지만 파일을 찾지 못한 상태이고, OBSOLETE는 파일이 있어도 현재 보존 정책상 더 이상 필요 없다고 판단된 상태입니다. Fast Recovery Area가 가득 차면 archived redo나 flashback log 보존에 영향을 줄 수 있으므로, 로컬 FRA뿐 아니라 원격지 복사와 불변 백업도 함께 설계해야 합니다.


고가용성(HA) 아키텍처와 복구

대규모 시스템에서는 백업 복구만으로는 RTO를 맞추기 어렵습니다. Data Guard, 복제, 클러스터, 스냅샷 같은 HA/DR 구조를 함께 설계하되, 자동 전환은 백업을 대체하지 않는다는 점을 분리해 이해해야 합니다.


복구 실무 종합 정리

DBMS물리적 백업 예시논리적 백업 예시PITR 로그HA/DR 예시
OracleRMANData Pumparchived redoData Guard
MySQLEnterprise Backup, XtraBackupmysqldump, MySQL Shell dumpbinary logReplication, InnoDB Cluster
PostgreSQLpg_basebackuppg_dumparchived WALStreaming Replication, Patroni
SQL ServerBACKUP DATABASEBCP, SSIStransaction log backupAlways On Availability Groups

다음 장에서는 쿼리의 성능을 분석하고 개선하는 쿼리 최적화를 다루겠습니다.