데이터베이스 연구실.log

RAC 파일과 파라미터 복구

2노드 RAC의 데이터 파일, 컨트롤 파일, 리두 로그와 공유 SPFILE 손실 복구 및 인스턴스 기동 순서

ORA-01623RMAN-06054RACsrvctl데이터 파일 복구CREATE DATAFILERESTORE CONTROLFILE FROM AUTOBACKUPredo threadADD LOGFILE THREAD공유 SPFILESET DBID

#핵심 요약

실습의 공통 순서는 srvctl stop database로 모든 인스턴스를 내리고, 1번 노드에서만 STARTUP해 멈춘 단계와 오류를 확인하고, 1번 노드에서 복구해 연 뒤 srvctl start instance로 2번 인스턴스를 올리는 것임

파일이 공유 디스크 그룹(+DATA, +FRA)에 있으므로 한 노드에서 복구한 결과를 다른 노드도 그대로 씀

인스턴스마다 자기 redo thread를 씀
데이터 파일 복구에는 모든 thread의 리두가 필요하고, 리두 로그 그룹을 다시 만들 때는 원래 thread를 지정함

공유 SPFILE 하나를 모든 인스턴스가 쓰므로 그 파일을 잃으면 모든 인스턴스가 뜨지 않음
RMAN 자동 백업이나 미리 만든 PFILE로 되살림

#개념과 동작 원리

잃은 파일 1번 노드 STARTUP 결과 복구
일반 데이터 파일 MOUNT에서 멈춤, ORA-01157, ORA-01110 RESTORE/RECOVER DATAFILE, OPEN
백업 없는 데이터 파일 위와 같음 ALTER DATABASE CREATE DATAFILE, RECOVER DATAFILE, OPEN
컨트롤 파일 전체 NOMOUNT(STARTED)에서 멈춤, ORA-00205 RESTORE CONTROLFILE FROM AUTOBACKUP, RECOVER DATABASE, OPEN RESETLOGS
컨트롤 파일 멤버 하나 위와 같음 남은 멤버로 RESTORE CONTROLFILE FROM '<멤버>', 일반 OPEN
INACTIVE 리두 그룹 전체 멤버 MOUNT 뒤 ORA-03113으로 인스턴스 종료
원인은 alert log의 ORA-00313, ORA-00312
DROP LOGFILE GROUP, ADD LOGFILE THREAD <n> GROUP <n>, OPEN
공유 SPFILE ORA-01078, ORA-01565로 시작 실패 RMAN 자동 백업에서 RESTORE SPFILE, 또는 PFILE로 CREATE SPFILE

설명: 여러 인스턴스가 같은 공유 파일에 접근하는 동안 파일을 바꾸거나 복구하면 파일 상태와 SCN의 일관성을 관리하기 어려워, 전체 접근을 막고 한 인스턴스에서 복구함
인스턴스가 열어 둔 파일은 ASM에서 지울 수 없음(ORA-15028)

설명: 컨트롤 파일 멤버가 하나만 없어도 인스턴스는 CONTROL_FILES의 모든 멤버를 열어야 MOUNT하므로 NOMOUNT에서 멈춤
다중화는 "하나가 남아 있으면 그것으로 되살릴 수 있다"는 뜻임

#필수 명령어 또는 SQL

#공통: 전체 정지와 한 노드 기동

OS 셸 (oracle 사용자, 1번 노드)인스턴스 또는 서비스 중단이 필요함
srvctl stop database -d <DB_NAME>
srvctl status database -d <DB_NAME>

결과 해석:

설명: 1번 노드에서 실행해도 클러스터 전체 인스턴스가 내려감

SQL*Plus (SYSDBA, 1번 노드)조회만 함
STARTUP
SELECT status FROM v$instance;

결과 해석:

복구가 끝난 뒤:

OS 셸 (oracle 사용자, 1번 노드)객체 또는 설정을 변경함
srvctl start instance -d <DB_NAME> -i <DB_NAME>2
srvctl status database -d <DB_NAME>
SQL*Plus (SYSDBA, 2번 노드)조회만 함
SELECT inst_id, instance_name, status FROM gv$instance;

결과 해석: 개별 실행 출력은 기재 없음

#데이터 파일 (백업 있음)

실습에서는 테이블스페이스를 만들어 백업한 뒤 행을 하나 더 넣고 ALTER SYSTEM ARCHIVE LOG CURRENT로 모든 thread의 리두를 아카이브했음
그 다음 전체를 내리고 데이터 파일을 지웠음

SQL*Plus (SYSDBA, 1번 노드, MOUNT)조회만 함
SELECT r.file#, r.error, d.name
  FROM v$recover_file r, v$datafile d
 WHERE r.file# = d.file#;
RMAN (1번 노드, MOUNT)객체 또는 설정을 변경함
RESTORE DATAFILE <FILE_NO>;
RECOVER DATAFILE <FILE_NO>;
ALTER DATABASE OPEN;

결과 해석:

실습 기록: 2번 노드에서 조회하니 백업 뒤에 넣은 행까지 두 행이 모두 있었음
실습에서는 복구 대상을 오류 메시지와 V$RECOVER_FILE로 확정하라고 적었음
실습의 파일 번호와 파일 이름은 조회 결과와 기동 오류에서 서로 다름

#데이터 파일 (백업 없음)

설명: 백업이 없어도 데이터 파일을 만든 시점 이후의 리두가 모두 남아 있으면 빈 파일을 다시 만들고 리두를 처음부터 적용해 재구성할 수 있음
백업 복원보다 필요한 로그 범위가 긺

SQL*Plus (SYSDBA, 1번 노드, MOUNT)조회만 함
SELECT file#, creation_change# FROM v$datafile WHERE file# = <FILE_NO>;

SELECT thread#, sequence#, first_change#, next_change#
  FROM v$archived_log
 WHERE next_change# > (SELECT creation_change# FROM v$datafile WHERE file# = <FILE_NO>)
   AND deleted = 'NO'
 ORDER BY thread#, sequence#;

결과 해석:

설명: thread 1과 2의 시퀀스가 빠짐없이 이어지는지 확인함
중간 시퀀스가 없으면 그 지점에서 복구가 멈출 수 있음

SQL*Plus (SYSDBA, 1번 노드, MOUNT)객체 또는 설정을 변경함
ALTER DATABASE CREATE DATAFILE <FILE_NO> AS '+DATA';
RMAN (1번 노드, MOUNT)객체 또는 설정을 변경함
RECOVER DATAFILE <FILE_NO>;
ALTER DATABASE OPEN;

결과 해석:

실습 기록: 빈 파일은 새 OMF 이름으로 만들어졌고, 1번 노드에서 넣은 행(thread 1)과 2번 노드에서 넣은 행(thread 2)이 모두 되살아났음
실습에서는 여러 파일을 RECOVER DATAFILE 21, 22, 23처럼 한 번에 처리하는 예도 적었음
백업 없이 RMAN RESTORE DATAFILE로 빈 파일을 만들 수 있는지는 확인 불가

운영 중(두 인스턴스 OPEN) 일반 테이블스페이스의 파일이면 DB를 내리지 않음

SQL*Plus (SYSDBA, 1번 노드, OPEN)인스턴스 또는 서비스 중단이 필요함
ALTER DATABASE DATAFILE <FILE_NO> OFFLINE;
ALTER DATABASE CREATE DATAFILE <FILE_NO> AS '+DATA';
RMAN (1번 노드)객체 또는 설정을 변경함
RECOVER DATAFILE <FILE_NO>;
SQL 'ALTER DATABASE DATAFILE <FILE_NO> ONLINE';

결과 해석:

설명: SYSTEM과 UNDO가 아닌 테이블스페이스에 쓸 수 있고, CREATE DATAFILE 전에 오프라인이 필요함
파일 상태는 컨트롤 파일에 기록되므로 한 노드에서 바꾸면 다른 노드에도 반영됨

#컨트롤 파일 전체 손실

RMAN (1번 노드)객체 또는 설정을 변경함
SHOW CONTROLFILE AUTOBACKUP;
CONFIGURE CONTROLFILE AUTOBACKUP ON;
BACKUP CURRENT CONTROLFILE;
LIST BACKUP OF CONTROLFILE;

결과 해석:

설명: 자동 백업을 켜면 백업 뒤 컨트롤 파일과 SPFILE이 +FRA에 자동 백업됨
ALTER DATABASE BACKUP CONTROLFILE TO TRACE로 받는 파일은 백업이 아니라 재생성 SQL 스크립트임
실습에서는 +DATA와 +FRA의 멤버를 모두 지웠음

RMAN (1번 노드, NOMOUNT)객체 또는 설정을 변경함
RESTORE CONTROLFILE FROM AUTOBACKUP;
ALTER DATABASE MOUNT;
RECOVER DATABASE;
ALTER DATABASE OPEN RESETLOGS;
SQL*Plus (SYSDBA)조회만 함
SELECT incarnation#, resetlogs_time, status FROM v$database_incarnation;
RMAN (1번 노드)객체 또는 설정을 변경함
BACKUP DATABASE PLUS ARCHIVELOG;

결과 해석:

설명: 복원 출력의 output file name으로 두 디스크 그룹에 다시 만들어졌는지 봄
RESETLOGS 뒤에는 로그 시퀀스가 1부터 시작하고 새 incarnation이 생기므로 바로 전체 백업함
실습에서는 백업 전에 ALTER SYSTEM CHECKPOINT GLOBAL을 실행했음

#컨트롤 파일 멤버 하나 손실

실습 적용 문제: +FRA 멤버 하나만 지우고 +DATA 멤버는 남긴 경우, 백업을 쓰지 않고 RESETLOGS 없이 복구함

SQL*Plus (SYSDBA, 1번 노드, NOMOUNT)인스턴스 또는 서비스 중단이 필요함
ALTER SYSTEM SET control_files = '+DATA', '+FRA' SCOPE = SPFILE SID = '*';
SHUTDOWN ABORT
STARTUP NOMOUNT
RMAN (1번 노드, NOMOUNT)객체 또는 설정을 변경함
RESTORE CONTROLFILE FROM '+DATA/<DB_NAME>/CONTROLFILE/current.<번호>.<번호>';
ALTER DATABASE MOUNT;
ALTER DATABASE OPEN;

결과 해석:

설명: OMF 이름은 같은 이름으로 다시 만들 수 없으므로 디스크 그룹 이름만 지정해 RMAN이 새 파일을 만들게 함
복원에 쓴 파일이 깨끗이 내려간 현재 컨트롤 파일이라 RECOVER도 RESETLOGS도 필요 없음
OPEN 때 RESETLOGS를 요구하면(ORA-01589) 현재 멤버가 아니라 백업을 지정한 것임
복구 뒤 incarnation과 로그 시퀀스가 그대로인지, 두 인스턴스의 CONTROL_FILES가 같은지 확인하고, 필요하면 새 파일 이름으로 SID = '*' 고정함
V$CONTROLFILE에 없는 옛 멤버를 대조한 뒤 지우고 컨트롤 파일 백업을 하나 받음

#리두 로그 그룹 손실

SQL*Plus (SYSDBA)조회만 함
SELECT group#, thread#, status, archived FROM v$log ORDER BY thread#, group#;
SELECT group#, member FROM v$logfile ORDER BY group#;

결과 해석:

실습 기록: 1번 노드에서 조회해도 두 thread의 그룹이 모두 보이고, CURRENT 그룹은 thread마다 하나씩 있었음
멤버는 그룹마다 +DATA와 +FRA에 하나씩이었음

INACTIVE이고 아카이브가 끝난(ARC=YES) 그룹의 멤버를 모두 지운 경우:

OS 셸 (oracle 사용자, 1번 노드)조회만 함
tail -50 $ORACLE_BASE/diag/rdbms/<DB_NAME>/<DB_NAME>1/trace/alert_<DB_NAME>1.log
SQL*Plus (SYSDBA, 1번 노드)데이터 또는 파일을 삭제함, 되돌릴 수 없음
STARTUP MOUNT
ALTER DATABASE DROP LOGFILE GROUP <GROUP_NO>;
ALTER DATABASE ADD LOGFILE THREAD <THREAD_NO> GROUP <GROUP_NO>;
ALTER DATABASE OPEN;
ALTER SYSTEM SWITCH LOGFILE;

결과 해석:

설명: 화면의 ORA-03113만으로는 원인을 알 수 없어 alert log에서 thread, 그룹, 없는 멤버를 확인함
thread를 확인하지 않고 다른 thread에 다시 만들면 인스턴스별 리두 구성이 어긋남
OMF 설정(DB_CREATE_FILE_DEST, DB_RECOVERY_FILE_DEST)에 따라 새 그룹의 멤버가 +DATA와 +FRA에 하나씩 만들어졌고, 새 그룹은 UNUSED였음

운영 중 멤버 하나만 잃은 경우(다른 멤버는 정상):

SQL*Plus (SYSDBA, OPEN)데이터 또는 파일을 삭제함, 되돌릴 수 없음
SELECT group#, status, member FROM v$logfile ORDER BY group#;
ALTER SYSTEM SWITCH LOGFILE;
ALTER SYSTEM CHECKPOINT;
ALTER DATABASE DROP LOGFILE MEMBER '+FRA/<DB_NAME>/ONLINELOG/group_<n>.<번호>.<번호>';
ALTER DATABASE ADD LOGFILE MEMBER '+FRA' TO GROUP <GROUP_NO>;

결과 해석:

설명: 정상 멤버가 남아 있으면 그 멤버로 계속 기록하고 alert log에 오류를 남김
잃은 멤버는 V$LOGFILE.STATUS가 INVALID임
CURRENT 그룹의 멤버는 지울 수 없으므로(ORA-01609) 로그 스위치로 넘김
이때 그룹 전체를 DROP하면 정상 멤버까지 지움

실습의 thread 2 적용 문제는 장애 대상 그룹 번호가 설명과 명령에서 다름

#CURRENT 그룹 손실 (thread와 시퀀스 기준 불완전 복구)

아직 아카이브되지 않은 CURRENT 그룹의 멤버를 모두 잃으면 최신 변경을 되살릴 수 없어, 복구할 수 있는 마지막 시퀀스까지 불완전 복구하고 OPEN RESETLOGS로 엶
RAC는 thread마다 시퀀스가 따로 올라가므로 같은 시퀀스 번호가 thread 1과 2에 모두 있어 반드시 THREAD#와 함께 지정함

SQL*Plus (SYSDBA, 1번 노드)조회만 함
SELECT name, ROUND(space_limit / 1024 / 1024) AS limit_mb,
       ROUND(space_used / 1024 / 1024) AS used_mb
  FROM v$recovery_file_dest;

SELECT group#, status, sequence#, thread# FROM v$log ORDER BY thread#, group#;
SELECT thread#, MAX(sequence#) FROM v$archived_log GROUP BY thread#;
RMAN (1번 노드, 모든 인스턴스 종료 뒤 1번만 MOUNT)데이터 또는 파일을 삭제함, 되돌릴 수 없음
RUN {
  SET UNTIL SEQUENCE <SEQ> THREAD 1;
  RESTORE DATABASE;
  RECOVER DATABASE;
}
ALTER DATABASE OPEN RESETLOGS;
LIST INCARNATION OF DATABASE;
OS 셸 (oracle 사용자, 1번 노드)객체 또는 설정을 변경함
srvctl start instance -db <DB_NAME> -i <INSTANCE2>
srvctl status database -db <DB_NAME>

결과 해석:

실습 기록:

  1. 전체 백업 뒤 srvctl stop database로 모두 내리고 asmcmd에서 thread 1의 CURRENT 그룹 2 멤버(+DATA, +FRA 각 하나)를 지우자, 1번 노드 STARTUP이 MOUNT에서 ORA-00313: open failed for members of log group 2 of thread 1, ORA-15012: ASM file does not exist로 멈췄음
  2. ALTER DATABASE DROP LOGFILE GROUP 2는 ORA-01623: log 2 is current log for instance <INSTANCE1> (thread 1) - cannot drop으로 거부됐음
    INACTIVE 그룹처럼 지우고 다시 만들 수 없음
  3. MOUNT 상태 조회에서 잃은 그룹은 thread 1의 시퀀스 8이었고, thread 2도 CURRENT 시퀀스 8이 아직 아카이브 전이었음
  4. SET UNTIL SEQUENCE 8 THREAD 1은 RMAN-06054: media recovery requesting unknown archived log for thread 2로 실패했고, SET UNTIL SEQUENCE 7 THREAD 1로 다시 하자 media recovery complete였음
  5. OPEN RESETLOGS 뒤 새 incarnation이 CURRENT가 됐고, 2번 인스턴스를 기동하자 두 인스턴스 모두 실행 중이었으며 리두 시퀀스는 1부터 다시 시작했음
    바로 새 백업을 받음

복구 중에는 모든 인스턴스를 닫고 복구 담당 인스턴스 하나만 MOUNT하며, 복구가 끝나기 전에 2번 노드를 띄우지 않음

잃은 thread만이 아니라 다른 thread의 아카이브가 어디까지 있는지도 복구 경계를 정함

연습 문제: 2번 인스턴스(thread 2)의 리두 멤버를 모두 잃은 경우, 양쪽 노드에서 로그 스위치를 세 번씩 한 뒤 두 thread의 리두를 모두 잃은 경우를 복구하고 두 인스턴스를 엶

#공유 SPFILE 손실

SQL*Plus (SYSDBA, 1번 노드)조회만 함
SHOW PARAMETER spfile
SELECT dbid FROM v$database;
OS 셸 (oracle 사용자, 각 노드)조회만 함
cat $ORACLE_HOME/dbs/init<DB_NAME>1.ora
srvctl config database -d <DB_NAME> | grep -i spfile

결과 해석:

설명: 각 노드의 init<SID>.ora에는 설정값 대신 공유 SPFILE 경로 한 줄만 있음(포인터 파일)
SPFILE과 컨트롤 파일을 모두 잃을 때를 대비해 DBID를 미리 적어 둠
장애 전에 RMAN 자동 백업(BACKUP SPFILE)과 텍스트 PFILE(CREATE PFILE='<PFILE>' FROM SPFILE) 두 가지를 준비했음

RMAN 자동 백업으로 복구:

asmcmd (grid 사용자)객체 또는 설정을 변경함
cd +DATA/<DB_NAME>
mkdir parameterfile

결과 해석:

설명: 마지막 파일이 지워지면서 PARAMETERFILE 디렉터리도 사라져 다시 만들었음

RMAN (1번 노드, rman target / nocatalog)인스턴스 또는 서비스 중단이 필요함
STARTUP NOMOUNT
SET DBID = <DBID>;
RESTORE SPFILE TO '+DATA/<DB_NAME>/PARAMETERFILE/spfile' FROM '<AUTOBACKUP_PIECE>';
SHUTDOWN ABORT

결과 해석:

실습 기록: 파라미터 파일 없이 "starting Oracle instance without parameter file for retrieval of spfile" 메시지와 함께 임시 인스턴스가 떴고, 복원이 완료되었음
실습에서는 파일 이름을 모를 때 RESTORE SPFILE TO '<경로>' FROM AUTOBACKUP DB_RECOVERY_FILE_DEST='+FRA' DB_NAME='<DB_NAME>'을 대안으로 적었음
이 형식과 백업 조각 직접 지정 방식의 차이는 확인 불가

OS 셸 (oracle 사용자, 1번 노드)객체 또는 설정을 변경함
srvctl modify database -d <DB_NAME> -spfile '+DATA/<DB_NAME>/PARAMETERFILE/spfile'
srvctl start database -d <DB_NAME>

결과 해석:

설명: 복구한 SPFILE 이름이 이전과 다르면 양쪽 노드의 포인터 파일과 srvctl 등록 경로를 새 경로로 맞춤

PFILE로 다시 만들기:

SQL*Plus (SYSDBA, 1번 노드)인스턴스 또는 서비스 중단이 필요함
STARTUP PFILE='<PFILE>'
CREATE SPFILE = '+DATA/<DB_NAME>/PARAMETERFILE/spfile' FROM PFILE = '<PFILE>';
STARTUP FORCE
SHOW PARAMETER spfile

결과 해석:

설명: PFILE로 뜬 동안 SHOW PARAMETER spfile은 비어 있고, STARTUP FORCE 뒤에 SPFILE 경로가 보임
PFILE에는 만든 시점의 설정만 있으므로 그 뒤 SCOPE=SPFILE로 바꾼 값은 다시 반영해야 함
이어서 2번 노드를 기동했음

실습에서는 양쪽 포인터 파일을 지운 상태에서도 STARTUP FORCE가 성공했다고 기록했지만, 어느 경로로 SPFILE을 찾았는지는 확인 불가
포인터 파일은 SPFILE='<경로>' 한 줄로 다시 만들었음

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기