RAC 파일과 파라미터 복구
2노드 RAC의 데이터 파일, 컨트롤 파일, 리두 로그와 공유 SPFILE 손실 복구 및 인스턴스 기동 순서
#핵심 요약
실습의 공통 순서는 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
#공통: 전체 정지와 한 노드 기동
srvctl stop database -d <DB_NAME>
srvctl status database -d <DB_NAME>결과 해석:
설명: 1번 노드에서 실행해도 클러스터 전체 인스턴스가 내려감
STARTUP
SELECT status FROM v$instance;결과 해석:
복구가 끝난 뒤:
srvctl start instance -d <DB_NAME> -i <DB_NAME>2
srvctl status database -d <DB_NAME>SELECT inst_id, instance_name, status FROM gv$instance;결과 해석: 개별 실행 출력은 기재 없음
#데이터 파일 (백업 있음)
실습에서는 테이블스페이스를 만들어 백업한 뒤 행을 하나 더 넣고 ALTER SYSTEM ARCHIVE LOG CURRENT로 모든 thread의 리두를 아카이브했음
그 다음 전체를 내리고 데이터 파일을 지웠음
SELECT r.file#, r.error, d.name
FROM v$recover_file r, v$datafile d
WHERE r.file# = d.file#;RESTORE DATAFILE <FILE_NO>;
RECOVER DATAFILE <FILE_NO>;
ALTER DATABASE OPEN;결과 해석:
실습 기록: 2번 노드에서 조회하니 백업 뒤에 넣은 행까지 두 행이 모두 있었음
실습에서는 복구 대상을 오류 메시지와 V$RECOVER_FILE로 확정하라고 적었음
실습의 파일 번호와 파일 이름은 조회 결과와 기동 오류에서 서로 다름
#데이터 파일 (백업 없음)
설명: 백업이 없어도 데이터 파일을 만든 시점 이후의 리두가 모두 남아 있으면 빈 파일을 다시 만들고 리두를 처음부터 적용해 재구성할 수 있음
백업 복원보다 필요한 로그 범위가 긺
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의 시퀀스가 빠짐없이 이어지는지 확인함
중간 시퀀스가 없으면 그 지점에서 복구가 멈출 수 있음
ALTER DATABASE CREATE DATAFILE <FILE_NO> AS '+DATA';RECOVER DATAFILE <FILE_NO>;
ALTER DATABASE OPEN;결과 해석:
실습 기록: 빈 파일은 새 OMF 이름으로 만들어졌고, 1번 노드에서 넣은 행(thread 1)과 2번 노드에서 넣은 행(thread 2)이 모두 되살아났음
실습에서는 여러 파일을 RECOVER DATAFILE 21, 22, 23처럼 한 번에 처리하는 예도 적었음
백업 없이 RMAN RESTORE DATAFILE로 빈 파일을 만들 수 있는지는 확인 불가
운영 중(두 인스턴스 OPEN) 일반 테이블스페이스의 파일이면 DB를 내리지 않음
ALTER DATABASE DATAFILE <FILE_NO> OFFLINE;
ALTER DATABASE CREATE DATAFILE <FILE_NO> AS '+DATA';RECOVER DATAFILE <FILE_NO>;
SQL 'ALTER DATABASE DATAFILE <FILE_NO> ONLINE';결과 해석:
설명: SYSTEM과 UNDO가 아닌 테이블스페이스에 쓸 수 있고, CREATE DATAFILE 전에 오프라인이 필요함
파일 상태는 컨트롤 파일에 기록되므로 한 노드에서 바꾸면 다른 노드에도 반영됨
#컨트롤 파일 전체 손실
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의 멤버를 모두 지웠음
RESTORE CONTROLFILE FROM AUTOBACKUP;
ALTER DATABASE MOUNT;
RECOVER DATABASE;
ALTER DATABASE OPEN RESETLOGS;SELECT incarnation#, resetlogs_time, status FROM v$database_incarnation;BACKUP DATABASE PLUS ARCHIVELOG;결과 해석:
설명: 복원 출력의 output file name으로 두 디스크 그룹에 다시 만들어졌는지 봄
RESETLOGS 뒤에는 로그 시퀀스가 1부터 시작하고 새 incarnation이 생기므로 바로 전체 백업함
실습에서는 백업 전에 ALTER SYSTEM CHECKPOINT GLOBAL을 실행했음
#컨트롤 파일 멤버 하나 손실
실습 적용 문제: +FRA 멤버 하나만 지우고 +DATA 멤버는 남긴 경우, 백업을 쓰지 않고 RESETLOGS 없이 복구함
ALTER SYSTEM SET control_files = '+DATA', '+FRA' SCOPE = SPFILE SID = '*';
SHUTDOWN ABORT
STARTUP NOMOUNTRESTORE 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에 없는 옛 멤버를 대조한 뒤 지우고 컨트롤 파일 백업을 하나 받음
#리두 로그 그룹 손실
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) 그룹의 멤버를 모두 지운 경우:
tail -50 $ORACLE_BASE/diag/rdbms/<DB_NAME>/<DB_NAME>1/trace/alert_<DB_NAME>1.logSTARTUP 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였음
운영 중 멤버 하나만 잃은 경우(다른 멤버는 정상):
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#와 함께 지정함
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#;RUN {
SET UNTIL SEQUENCE <SEQ> THREAD 1;
RESTORE DATABASE;
RECOVER DATABASE;
}
ALTER DATABASE OPEN RESETLOGS;
LIST INCARNATION OF DATABASE;srvctl start instance -db <DB_NAME> -i <INSTANCE2>
srvctl status database -db <DB_NAME>결과 해석:
실습 기록:
- 전체 백업 뒤
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로 멈췄음 ALTER DATABASE DROP LOGFILE GROUP 2는ORA-01623: log 2 is current log for instance <INSTANCE1> (thread 1) - cannot drop으로 거부됐음
INACTIVE 그룹처럼 지우고 다시 만들 수 없음- MOUNT 상태 조회에서 잃은 그룹은 thread 1의 시퀀스 8이었고, thread 2도 CURRENT 시퀀스 8이 아직 아카이브 전이었음
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였음OPEN RESETLOGS뒤 새 incarnation이 CURRENT가 됐고, 2번 인스턴스를 기동하자 두 인스턴스 모두 실행 중이었으며 리두 시퀀스는 1부터 다시 시작했음
바로 새 백업을 받음
복구 중에는 모든 인스턴스를 닫고 복구 담당 인스턴스 하나만 MOUNT하며, 복구가 끝나기 전에 2번 노드를 띄우지 않음
잃은 thread만이 아니라 다른 thread의 아카이브가 어디까지 있는지도 복구 경계를 정함
연습 문제: 2번 인스턴스(thread 2)의 리두 멤버를 모두 잃은 경우, 양쪽 노드에서 로그 스위치를 세 번씩 한 뒤 두 thread의 리두를 모두 잃은 경우를 복구하고 두 인스턴스를 엶
#공유 SPFILE 손실
SHOW PARAMETER spfile
SELECT dbid FROM v$database;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 자동 백업으로 복구:
cd +DATA/<DB_NAME>
mkdir parameterfile결과 해석:
설명: 마지막 파일이 지워지면서 PARAMETERFILE 디렉터리도 사라져 다시 만들었음
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>'을 대안으로 적었음
이 형식과 백업 조각 직접 지정 방식의 차이는 확인 불가
srvctl modify database -d <DB_NAME> -spfile '+DATA/<DB_NAME>/PARAMETERFILE/spfile'
srvctl start database -d <DB_NAME>결과 해석:
설명: 복구한 SPFILE 이름이 이전과 다르면 양쪽 노드의 포인터 파일과 srvctl 등록 경로를 새 경로로 맞춤
PFILE로 다시 만들기:
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='<경로>' 한 줄로 다시 만들었음