상세 컨텐츠

본문 제목

2024년 1월 9일 2교시 시나리오 1. 특정 dbf 손상 + 백업본 O + 백업 이후 리두 정보 O

오라클 백업 리커버리

by 병아리 엔지니어 2024. 1. 9. 11:54

본문

 

노아카이브 모드에서 주의할 점: 운영 중에 백업을 받을 수 없다.

그래서 DB 를 정상 종료한 다음

백업할 파일들이 있는 물리적인 위치로 가서 카피해야 한다.

 

지금 백업을 완료하고 DB 띄우는 것까지 했는데.

 

 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ 시나리오 1 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★

 

특정 데이터파일 손상 + 백업본이 있고 + 백업 이후 리두 정보 있음 = 완전 복구

 

(d 102)

select * from v$log;

리두로그 파일 확인하기

(현재 current 한 그룹들이 어디인지 등)

 

 

1번 그룹이 커런트한 그룹으로 되어 있다.

(여기에 리두가 만들어지게 된다)

 

(d 102 hr) (퍼티에서 해도 된다)

 

테이블을 하나 생성해보자.

 

CREATE TABLE new(id number) tablespace example;
(이미 만들어져 있는) example 이라는 테이블스페이스에 new 라는 테이블 생성

 

 

insert into new(id) values(1);

새로 만든 테이블에 인서트 작업하고


commit;

커밋

 

 

이렇게 되면 이제 insert 에 해당하는 리두 정보도 current 한 리두 로그 그룹에 기록되어 있게 된다.

(테이블 생성 / 인서트 작업 / 커밋 모두 백업 이후에 & 다른 세션에서 이루어짐)

 

select * from new;

인서트가 잘 되었는지 확인해보기

 

(d 102)

다시 102 에서

 

select f.file_name
from dba_extents e, dba_data_files f
where e.file_id = f.file_id
and e.segment_name = 'NEW'
and e.owner = 'HR';

hr 이 가지고 있는 new 테이블이 어느 테이블스페이스에 있는지 조회해보기

 

/u01/app/oracle/oradata/ora11g/example01.dbf

이 위치에 있다고 나온다.

음... example 테이블스페이스로 잘 들어갔네.

 

 

 

그럼 이제 저 테이블스페이스에 속한 데이터파일을 깨뜨려서 장애를 한번 유발시켜 보자.

 

1. DB 내리기

 

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

 

2. 데이터파일 깨뜨리기

 

[oracle@oracle ~]$ rm /u01/app/oracle/oradata/ora11g/example01.dbf

 

[oracle@oracle ~]$ ls /u01/app/oracle/oradata/ora11g/example01.dbf

ls: cannot access /u01/app/oracle/oradata/ora11g/example01.dbf: No such file or directory

파일을 확인해보면: 없다고 나온다. (당연하겠지)

 

3. DB 올리기

 

SQL> startup

 

그러면 오픈 시점의 동기화 체크시에 오류가 발생하게 된다.

 

 

(체크포인트 정보를 맞춰보았는데 있어야 할 위치에 파일이 없기 때문에 오류가 발생함,

5번 데이터파일이 없다고 나옴)

이러면 DB 가 올라올 수가 없다.

 

그럼 이제 백업받아놓은 데이터 파일을 부어넣고 파일을 복구하는 작업을 해보자.

 

다시 OS로

 

SQL> !

 

[oracle@oracle ~]$ cd /home/oracle/backup/noarch/

백업받은 위치로 가서

 

[oracle@oracle noarch]$ ls example01.dbf
example01.dbf

파일이 있는지 체크 : 있다.

 

 

[oracle@oracle noarch]$ cp -av example01.dbf /u01/app/oracle/oradata/ora11g/example01.dbf

백업파일을 원래 원본파일이 있던 위치에 부어넣기 (백업파일 리스토어 restore)

원본 파일 위치에서 데이터파일을 삭제했기 때문에 파일이 없어져 있을 텐데

백업파일이 원본 파일 위치로 들어가면 없어진 파일이 만들어져 있게 된다.

원본 파일 위치로 가서 파일이 잘 들어갔는지도 (카피가 잘 되었는지도) 확인해 보자.

 

 

리커버리시에 가장 먼저 해야 하는 일:

1. 백업파일 찾기

2. 원래 원본파일이 있던 위치에 카피 cp

 

하지만 저 백업파일은 한참 전에 받아놓은 것이기 때문에

다른 파일들과 싱크가 맞지 않게 된다.

그래서 recovery 작업이 따로 필요하다 (recovery 작업 = 싱크 맞추는 작업)

 

4. 백업으로 복구한 데이터파일 리커버리 작업

 

다시 sql+에서

 

SQL>

recover tablespace example;

recover tablespace 테이블스페이스이름 또는

 

 

원본파일이 들어있던 테이블스페이스를 잘 모르겠는 경우에는 그냥

 

SQL>

recover database;

이렇게 해서 복구해도 된다.

(데이터베이스 레벨로 니가 좀 알아서 복구해달라는 뜻)

 

recover 하는 순간 리두를 적용해서 데이터파일을 복구한다.

 

5. DB 오픈하기

 

SQL> alter database open;

 

 

SQL> select name, checkpoint_change# from v$datafile;

체크포인트 정보 확인하기

 

 

체크포인트 정보가 모두 맞춰져 있다.

(백업받아놓은 것 중 example 에 속한 데이터파일만 리스토어하고

나머지는 리스토어하지 않았는데도 모든 데이터파일들의 싱크가 다 맞춰져 있다)

 

그럼 저 테이블스페이스에 속한 테이블의 데이터를 조회해서

조회가 되는지 (조회가 되면 데이터파일이 복구된 것) 확인해 보자.

 

sql+에서 hr 유저로 로그인

 

SQL> conn hr/hr
Connected.

 

 select * from new;

 

SQL> select * from new;

        ID
----------
         1

 

조회가 된다. (데이터파일 복구에 성공한 것)

 

 


 

(칠판 그림)

 

★ 시나리오 1.

 

아까 데이터파일을 백업받아놓은 시점 (2024-01-09-AM09:00) 의 SCN 번호가 #100이라고 하자.

(current 한 리두로그 그룹에 SCN #100 이 기록됨,

current 한 리두로그 그룹 번호는 #10)

 

운영을 하다가, AM 09:05 에 hr 유저가 example tablespace 에 new 라는 테이블을 생성하고

commit 까지 하면

new 라는 테이블의 정보, commit 정보가 current 리두에 기록되게 된다.

 

그리고 나서 insert 문장을 돌려서 데이터를 테이블에 1건 집어넣었는데 (AM 09:05)

이때 로그 스위치가 발생해서 리두로그 그룹이 그다음 그룹으로 넘어가고

insert 정보가 #11 에 기록되게 되었다고 하자.

 

그리고 AM 09:06 에 장애가 발생해서

이 NEW 라는 테이블이 속한 테이블스페이스의 데이터파일이 깨졌다면

있어야 할 위치에 파일이 없어서 startup 시에 오류가 뜨게 된다.

 

그러면 백업받아놓은 파일로 복구를 해야 하는데

백업은 SCN 번호가 #100 일 때 받은 것이므로

저 백업파일 안에는 new 라는 테이블도 없고 insert 한 데이터 정보도 없다.

(SCN #100 이후의 정보가 current 리두 그룹에 가보니까 없다)

 

이럴 때는: v$log의 first_change#, next_change# 정보를 보고

저 백업파일이 current 리두로그 그룹이 몇 번일 때 백업받았는지 찾고 (#10, #11)

그때 당시의 리두 그룹에 써있는 정보를 가지고

(첫번째 리두로그 그룹 보고 > 로그 스위치가 발생했다면 그 다음 그룹에 가서 리두 정보를 찾는다)

new 테이블을 생성하고 + commit 하고 + insert 까지 끝내서 리커버리한다.

(완전 복구, 리두 정보만 있으면 no archive 라도 완전 복구가 가능하다)

 

 

그런데 이건 마지막 백업 시점 이후에 redo 가 있을 때의 이야기고...

#10 까지 redo 를 받아놓고

(백업하려면 #10, #11 둘다 필요)

 

1번 리두그룹(#10)에서 로그 스위치가 발생해서

2번 리두그룹(#11)로 넘어가고

2번 리두그룹(#11)에서도 또 로그 스위치가 발생해서

3번 리두그룹(#12)로 넘어가고

3번 리두그룹(#12)에서 또 로그 스위치가 발생해서

다시 1번 리두그룹(#13)으로 넘어왔다고 하자.

 

그러면 1번 리두그룹이 current 그룹이 되면서

그 안에 있던 데이터들은 다 overwrite 가 되어서 사라져 버리게 된다.

이 때 장애가 발생해서 파일이 깨지면

리두 정보가 없으므로 DB 를 완전 복구할 수 없고

불완전 복구밖에 못하게 된다. (전체 DB 가 예전 시점으로 돌아간다)

백업시점 이후의 리두가 없으면 : DB를 복구할 수 없다,

리두가 살아있어야만 복구가 가능하고

없으면 전체 파일을 부어넣어서 과거 DB 로 되돌리는 작업을 할 수밖에 없다.

 

관련글 더보기