Oracle/백업&복구

복구시나리오 종합(drop tablespace장애(백업 전 생성, 백업 후 생성), 사용자 실수로 지운 drop table 복구 (logmnr error 포함)

에몽이ㅋ 2012. 2. 8. 07:13

--------------------------------------------------------------------------------------------장애

(장애)

A tbs

생성

백업

받았음

B tbs

생성

A,B tbs

test_a,b table생성

(생성후 자료insert)

test_a,b

실수로

drop

모든

Datafile,

Ctlfile

삭제됨



위 시나리오 요약 및 복구목적
1. A tbs 생성 이후 switch logfile
2. 백업
3. B tbs 생성 이후 switch logfile
4. A,B tbs에 test_a,b table생성 후 자료 insert (commit 후 switch logfile)
5. datafile, contorl file 모두 삭제됨

복구 목적 : DB OPEN, 실수로 drop 한 table 불완전복구( 위 그림에서 5번째 ▼ 이전으로 )

해결
1. 임시경로에 백업된 datafile, control file, 현재 redolog file을 임시경로로 RESTORE
2. alter database rename으로 임시경로로 DB셋팅
3. logmnr이용해서 test_a,b drop된 시간 검색
4. 복구시도
  1. 해결3번에서 찾은 시간으로 recover 한번 실행하면 control file에 A tbs정보가 입력됨
  2. 입력된 tbs 정보를 임시경로로 datafile 지정
  3. 다시 복구 시도(해결3번에서 찾은 시간으로 불완전 복구)
5. 복구확인 

실습 DB 설명
모든 datafile, controlfile, redo log file은
/home/oracle/oradata/testdb/안에 저장되어 있습니다.
복구를 위해 Archive log mode입니다. 

-----------------------------------------------------------------------
-------------------실습시작--------------------------------------------
-----------------------------------------------------------------------
1. A tbs 생성 이후 switch logfile
  1  create tablespace a
  2* datafile '/home/oracle/oradata/testdb/a01.dbf' size 5m
SQL> /

Tablespace created.

-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------

2. 백업
SQL> !sh ~/main_backup.sh

set begin backup mode~~

real    0m0.658s
user    0m0.037s
sys     0m0.050s

end begin backup mode--

start file copy.…

real    0m41.002s
user    0m0.118s
sys     0m6.353s
end file copy~

set end backup mode~~

real    0m2.002s
user    0m0.033s
sys     0m0.050s
complete hot backup~!!

-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------
3. B tbs 생성 이후 switch logfile
SQL> create tablespace b
  2  datafile '/home/oracle/oradata/testdb/b01.dbf' size 5M;

Tablespace created.

SQL> alter system switch logfile;

System altered.

SQL> /

System altered.

SQL> /

System altered.

SQL> /

System altered.

SQL> /

System altered.

-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------
4. A,B tbs에 test_a,b table생성 후 자료 insert (commit 후 switch logfile)
SQL> insert into scott.test_a values(1);
SQL> insert into scott.test_a values(2);

SQL> insert into scott.test_b values(10);
SQL> insert into scott.test_b values(20);

SQL> commit;

SQL> alter system switch logfile;

System altered.

SQL> /

System altered.

SQL> /
/

System altered.

SQL>
System altered.

SQL> /

System altered.

SQL> /

System altered.

-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------
5. 사용자 실수로 table drop한 후, datafile, contorl file 모두 삭제됨 이후 shutdown abort
SQL> drop table scott.test_a;
SQL> drop table scott.test_b;
    << 실수로 table drop

SQL> !rm -v ~/oradata/testdb/*.dbf
removed `/home/oracle/oradata/testdb/a01.dbf'
removed `/home/oracle/oradata/testdb/b01.dbf'
removed `/home/oracle/oradata/testdb/example01.dbf'
removed `/home/oracle/oradata/testdb/sysaux01.dbf'
removed `/home/oracle/oradata/testdb/system01.dbf'
removed `/home/oracle/oradata/testdb/temp01.dbf'
removed `/home/oracle/oradata/testdb/undotbs01.dbf'
removed `/home/oracle/oradata/testdb/users01.dbf'

SQL> !rm -v ~/oradata/testdb/*.ctl
removed `/home/oracle/oradata/testdb/control01.ctl'

SQL> shutdown abort
ORACLE instance shut down.
*********************여기까지 장애발생 완료**************************


*****************************************************************
복구시도(DB OPEN하고, 실수로 DROP한 table 불완전 복구)
*****************************************************************
1. 임시경로에 백업된 datafile, control file, 현재 redolog file을 임시경로로 RESTORE
   한 후 파라미터에 임시경로로 control file셋팅
SQL> !cp -av /backup/open/2012-02-07-21-48-47/*.dbf  ~/temp/
`/backup/open/2012-02-07-21-48-47/a01.dbf' -> `/home/oracle/temp/a01.dbf'
`/backup/open/2012-02-07-21-48-47/example01.dbf' -> `/home/oracle/temp/example01.dbf'
`/backup/open/2012-02-07-21-48-47/sysaux01.dbf' -> `/home/oracle/temp/sysaux01.dbf'
`/backup/open/2012-02-07-21-48-47/system01.dbf' -> `/home/oracle/temp/system01.dbf'
`/backup/open/2012-02-07-21-48-47/undotbs01.dbf' -> `/home/oracle/temp/undotbs01.dbf'
`/backup/open/2012-02-07-21-48-47/users01.dbf' -> `/home/oracle/temp/users01.dbf'

SQL> !cp -av /backup/open/2012-02-07-21-48-47/*.ctl  ~/temp/control01.ctl
`/backup/open/2012-02-07-21-48-47/2012-02-07-21-48-47.ctl' -> `/home/oracle/temp/control01.ctl'

SQL>  !cp -av ~/oradata/testdb/*.log  ~/temp/
`/home/oracle/oradata/testdb/redo01.log' -> `/home/oracle/temp/redo01.log'
`/home/oracle/oradata/testdb/redo02.log' -> `/home/oracle/temp/redo02.log'
`/home/oracle/oradata/testdb/redo03.log' -> `/home/oracle/temp/redo03.log'


SQL> !vi $ORACLE_HOME/dbs/inittestdb.ora
*.control_files='/home/oracle/temp/control01.ctl'

-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------
2. mount로 올린 후 alter database rename으로 임시경로로 DB셋팅
SQL> startup mount
ORACLE instance started.

Total System Global Area  167772160 bytes
Fixed Size                  1272600 bytes
Variable Size              96470248 bytes
Database Buffers           67108864 bytes
Redo Buffers                2920448 bytes
Database mounted.

alter database rename file '/home/oracle/oradata/testdb/system01.dbf' to '/home/oracle/temp/system01.dbf';
alter database rename file '/home/oracle/oradata/testdb/undotbs01.dbf' to '/home/oracle/temp/undotbs01.dbf';
alter database rename file '/home/oracle/oradata/testdb/sysaux01.dbf' to '/home/oracle/temp/sysaux01.dbf';
alter database rename file '/home/oracle/oradata/testdb/users01.dbf' to '/home/oracle/temp/users01.dbf';
alter database rename file '/home/oracle/oradata/testdb/example01.dbf' to '/home/oracle/temp/example01.dbf';
alter database rename file '/home/oracle/oradata/testdb/a01.dbf' to '/home/oracle/temp/a01.dbf';
(TBS B의 정보는 백업된 control file에는 없으므로 없는게 맞습니다.)

Database altered.


alter database rename file '/home/oracle/oradata/testdb/redo03.log' to '/home/oracle/temp/redo03.log';
alter database rename file '/home/oracle/oradata/testdb/redo02.log' to '/home/oracle/temp/redo02.log';
alter database rename file '/home/oracle/oradata/testdb/redo01.log' to '/home/oracle/temp/redo01.log';

Database altered.

-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------
3. logmnr이용해서 test_a,b drop된 시간 검색
(아쉽게도 mount단계에서는 실행이 안됩니다. 이 부분 마지막에서 추론해낸 시간을 사용하겠습니다.)
(mount단계에서 할 수가 없기 때문에, 어떠한 DML시간을 찾아서 그 시점으로 복구해야할 때에는, 일단 시간을 먼저 찾아놓고, 불완전 복구를 시작하십시오) 
** 여기에서는 모든 ctl, datafile이 삭제되고, shutdown abort가 되어버렸기 때문에 logminer를 사용할 수 없습니다. 
첫번째. archive 파일정보보기
SQL> !ls -al /backup/arc | sort -k 8 << 시간별정렬했습니다.
합계 14300
-rw-r-----  1 oracle dba   417280  2월  5 01:53 1_1_774409410.dbf
-rw-r-----  1 oracle dba     1024  2월  5 01:53 1_2_774409410.dbf
-rw-r-----  1 oracle dba     2048  2월  5 01:53 1_3_774409410.dbf

*************생략*************
 
-rw-r-----  1 oracle dba     1024  2월  6 18:02 1_16_774410678.dbf
-rw-r-----  1 oracle dba     1024  2월  6 18:31 1_17_774410678.dbf
-rw-r-----  1 oracle dba     1024  2월  6 18:31 1_18_774410678.dbf
-rw-r-----  1 oracle dba   124928  2월  6 18:31 1_19_774410678.dbf
-rw-r-----  1 oracle dba  1497088  2월  7 21:50 1_1_774556272.dbf
-rw-r-----  1 oracle dba     1024  2월  7 21:50 1_2_774556272.dbf
-rw-r-----  1 oracle dba     2048  2월  7 21:50 1_3_774556272.dbf
-rw-r-----  1 oracle dba     1024  2월  7 21:50 1_4_774556272.dbf
-rw-r-----  1 oracle dba     1024  2월  7 21:50 1_5_774556272.dbf
drwxr-xr-x  2 oracle dba     4096  2월  7 21:54 .
-rw-r-----  1 oracle dba     1024  2월  7 21:54 1_10_774556272.dbf
-rw-r-----  1 oracle dba     1024  2월  7 21:54 1_11_774556272.dbf
-rw-r-----  1 oracle dba    24576  2월  7 21:54 1_6_774556272.dbf
-rw-r-----  1 oracle dba     1024  2월  7 21:54 1_7_774556272.dbf
-rw-r-----  1 oracle dba     2048  2월  7 21:54 1_8_774556272.dbf
-rw-r-----  1 oracle dba     1024  2월  7 21:54 1_9_774556272.dbf
drwxr-xr-x  6 oracle dba     4096  2월  4 22:36 ..

(백업받은 후 Archive file들을 정렬하지 않아서 좀 복잡한데
보통 Incarnation#가 가장 높은 것이 최신 것입니다.
(시간에서도 볼 수 있듯이 Incarnation#가 774556272 이전 자료들은
현재 DB에서 사용하지 않는 archive file임을 알 수 있죠)
1_1_774556272.dbf ~ 1_11_774556272.dbf들과 /home/oracle/temp/*.log
들을 분석해야합니다.)

두번째, logmnr를 위한 파라미터파일변경
!vi $ORACLE_HOME/dbs/inittestdb.ora
 utl_file_dir="/backup/logmnr"

SQL> l
  1  select NAME, ISSYS_MODIFIABLE, ISINSTANCE_MODIFIABLE, VALUE from v$parameter
  2* where name='utl_file_dir'
SQL> /

NAME                 ISSYS_MOD ISINS VALUE
-------------------- --------- ----- --------------------
utl_file_dir         FALSE     FALSE /backup/logmnr

**ISSYS_MODIFIABLE이 FALSE이므로, alter system set으로 즉각 변경이 적용이 되지 않기 떄문에
shutdown 후 startup mount 까지 해줍니다.

SQL> shutdown immediate
ORA-01109: database not open


Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.

Total System Global Area  167772160 bytes
Fixed Size                  1272600 bytes
Variable Size              96470248 bytes
Database Buffers           67108864 bytes
Redo Buffers                2920448 bytes
Database mounted.

세번째, log mnr 설정하기(dbmslmd.sql 파일을 참조하세요)
SQL> exec dbms_logmnr_d.build('dict','/backup/logmnr');
BEGIN dbms_logmnr_d.build('dict','/backup/logmnr'); END;

      *
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'DBMS_LOGMNR_D.BUILD' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
위 오류 발생시 http://www.dbasupport.com/forums/archive/index.php/t-16703.html 참조

** 여기서도 위같은 오류가 나서, logmnr를 사용할 수 없습니다
(dbmslmd.sql 을 변경하고 재compile해야하는데 OPEN상태에서만 할 수 있습니다)
그래서 archive log시간을 보고 대충 때려잡아서 복구하겠습니다.

* drop 이후에 alter database switch logfile;을 실행 한 적이 없고,
insert 이후에 switch logfile을 6번 실행했으므로, 6~11에 해당하는 log switch입니다.
그러므로 archive log file 1_11_774556272.dbf 에 해당하는 시간인
2012-02-07:21:54:25까지 불완전 복구를 하겠습니다.


-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------
4. 복구시도
************************************************************
4-1. 해결3번에서 찾은 시간으로 recover 한번 실행하면 control file에 A tbs정보가 입력
SQL>  recover database until time '2012-02-07:21:54:25' using backup controlfile;
ORA-00279: change 743547 generated at 02/07/2012 21:48:47 needed for thread 1
ORA-00289: suggestion : /backup/arc/1_1_774556272.dbf
ORA-00280: change 743547 for thread 1 is in sequence #1


Specify log: {=suggested | filename | AUTO | CANCEL}
auto
ORA-00283: recovery session canceled due to errors
ORA-01244: unnamed datafile(s) added to control file by media recovery  << 없던 tbs정보가 controlfile에 추가됨
ORA-01110: data file 7: '/home/oracle/oradata/testdb/b01.dbf'


ORA-01112: media recovery not started
************************************************************
4-2. 입력된 tbs 정보를 임시경로로 datafile 지정
SQL> select name from v$datafile;

NAME
---------------------------------------------
/home/oracle/temp/system01.dbf
/home/oracle/temp/undotbs01.dbf
/home/oracle/temp/sysaux01.dbf
/home/oracle/temp/users01.dbf
/home/oracle/temp/example01.dbf
/home/oracle/temp/a01.dbf
/home/oracle/product/10g/dbs/UNNAMED00007

SQL> alter database create datafile '/home/oracle/product/10g/dbs/UNNAMED00007'
  2  as '/home/oracle/temp/b01.dbf';

Database altered.

************************************************************
4-3. 다시 복구 시도(해결3번에서 찾은 시간으로 불완전 복구)
SQL> recover database until time '2012-02-07:21:54:25' using backup controlfile; <<
ORA-00279: change 743665 generated at 02/07/2012 21:50:33 needed for thread 1
ORA-00289: suggestion : /backup/arc/1_1_774556272.dbf
ORA-00280: change 743665 for thread 1 is in sequence #1


Specify log: {=suggested | filename | AUTO | CANCEL}
auto
ORA-00279: change 743691 generated at 02/07/2012 21:50:39 needed for thread 1
ORA-00289: suggestion : /backup/arc/1_2_774556272.dbf
ORA-00280: change 743691 for thread 1 is in sequence #2
ORA-00278: log file '/backup/arc/1_1_774556272.dbf' no longer needed for this recovery


ORA-00279: change 743693 generated at 02/07/2012 21:50:39 needed for thread 1
ORA-00289: suggestion : /backup/arc/1_3_774556272.dbf
ORA-00280: change 743693 for thread 1 is in sequence #3
ORA-00278: log file '/backup/arc/1_2_774556272.dbf' no longer needed for this recovery


생략


ORA-00279: change 743802 generated at 02/07/2012 21:54:24 needed for thread 1
ORA-00289: suggestion : /backup/arc/1_11_774556272.dbf
ORA-00280: change 743802 for thread 1 is in sequence #11
ORA-00278: log file '/backup/arc/1_10_774556272.dbf' no longer needed for this recovery


Log applied.
Media recovery complete.

-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------
5. 복구확인
SQL> l
  1* select tablespace_name, file_name from dba_data_files
SQL> /

TABLESPACE_NAME                FILE_NAME
------------------------------ ---------------------------------------------
EXAMPLE                        /home/oracle/temp/example01.dbf
USERS                          /home/oracle/temp/users01.dbf
SYSAUX                         /home/oracle/temp/sysaux01.dbf
UNDOTBS1                       /home/oracle/temp/undotbs01.dbf
SYSTEM                         /home/oracle/temp/system01.dbf
A                              /home/oracle/temp/a01.dbf   <<
B                              /home/oracle/temp/b01.dbf   <<

7 rows selected.

SQL> select * from scott.test_a;

        NO
----------
         1
         2

SQL> select * from scott.test_b;

        NO
----------
        10
        20

복구가 완료되었습니다.  어때요. 참 쉽죠?