Oracle/RMAN

백업&복구 18번째 RMAN ; sql문 실행, 데이터파일들의 경로변경하기, Recover(물리적, 논리적복구 예시들)

에몽이ㅋ 2012. 2. 26. 18:48
RMAN에서 sql 문실행하기
RMAN> sql "alter tablespace fbda offline";
위와같이 sql "SQL문"; 하시면 됩니다.  (sql 'SQL문'; 도 가능)

*주의사항 : "  "안에서 '을 표현하려고 한다면, ''를 써야합니다.
alter database datafile '/temp/data.dbf' offline; 
--> RMAN> sql "alter database datafile ''/temp/data.dbf'' offline"; 입니다.

복원명령어
restore database;
restore datafile 1,2,..;
restore tablespace 'KOO','TEST';

복구명령어
recover database;
recover datafile 1,2,..;
recover tablespace 'KOO', 'TEST';

불완전복구명령어(불완전 복구니까 mount상태에서 해야겠죠?) 
$ export nls_date_format='rrrr-mm-dd:hh24:mi:ss' 실행시킨 후
run {

set until time='2012-01-01:01:01:01';
restore tablespace 'KOO';
recover tablespace 'KOO';
}

새로운 경로에서 불완전복구를 하고 싶다면?
run {
startup mount
set newname for datafile 1 to '/temp/system01.dbf';
set newname for datafile 2 to '/temp/undotbs01.dbf'; 
set newname for datafile 3 to '/temp/sysaux01.dbf'; 
set newname for datafile 6 to '/temp/koo01.dbf'; 


restore datafile 1,2,3,6;
switch datafile all;  (or switch datafile 1,2,3,6;)    

recover datafile 1,2,3,6;


sql "alter database open resetlogs";
}

set newname 을 하게 되면 restore은 newname경로에서 하게되지만, recover는 예전경로에서 하게 되어버리므로,
switch datafile all;을 꼭 써줘서 recover도 newname경로에서 하게 해야합니다.



--> switch datafile all;을 안쓰게 되면 데이터파일들이 엄청나게 꼬입니다.
RMAN으로 복구하려다가 되려 DB가 문제가 생기는 경우가 있으므로, 
set newname과 switch datafile은 셋트로 무조건 기억하세요.



복구1. test tablespace의 test01.dbf가 지워진 물리적장애 복구
run {
sql "alter database datafile ''/app/oracle/oradata/testdb/test01.dbf'' offline";
restore datafile 7;
recover datafile 7;
sql "alter database datafile ''/app/oracle/oradata/testdb/test01.dbf'' online";
}
sql statement: alter database datafile ''/app/oracle/oradata/testdb/test01.dbf'' offline

Starting restore at 2012-02-26:17:41:48
using channel ORA_DISK_1

channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00007 to /app/oracle/oradata/testdb/test01.dbf
channel ORA_DISK_1: reading from backup piece /app/rman/0un4a3o3_1_1_20120226.rman
channel ORA_DISK_1: piece handle=/app/rman/0un4a3o3_1_1_20120226.rman tag=TAG20120226T164100
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: restore complete, elapsed time: 00:00:01
Finished restore at 2012-02-26:17:41:50

Starting recover at 2012-02-26:17:41:50
using channel ORA_DISK_1

starting media recovery
media recovery complete, elapsed time: 00:00:00

Finished recover at 2012-02-26:17:41:50

sql statement: alter database datafile ''/app/oracle/oradata/testdb/test01.dbf'' online


복구2. 잘못된 truncate table 살려내기(논리적인 오류, 살릴 시간은 알고 있다고 가정합니다.)
; 복구시 새로운 경로에 살립니다., 필요없는 파일들은 복원하지 않겠습니다.,
redo log파일을 복사하고, control file도 복사 한 후 파라미터에 임시경로의 컨트롤파일을 사용하도록 한 후 작업합니다.

; koo tablespace의 자료가 날라갔다고 가정하고 살리는 것입니다 !
SQL> select sysdate from dual;

SYSDATE
-------------------
2012-02-26:17:48:14

SQL> truncate table koo.test;

Table truncated.

SQL> select * from koo.test;

no rows selected
에러발생!!!
------------------------------------------------------------------
------------------------------------------------------------------
복구 전초작업
SQL> shutdown immediate
[oracle@server16 testdb]$ cp -v *.log /app/temp
[oracle@server16 testdb]$ cp -v *.ctl /app/temp
[oracle@server16 testdb]$ vi $ORACLE_HOME/dbs/inittestdb.ora
*.control_files='/app/temp/control01.ctl'  << 값추가하고 원래 control은 주석처리

------------------------------------------------------------------
------------------------------------------------------------------
복구작업

RMAN에서 작업
[oracle@server16 ~]$ rman target /

RMAN> run {
startup mount;
sql "alter database rename file ''/app/oracle/oradata/testdb/redo01.log''
 to ''/app/temp/redo01.log''";
sql "alter database rename file ''/app/oracle/oradata/testdb/redo02.log''
 to ''/app/temp/redo02.log''";
sql "alter database rename file ''/app/oracle/oradata/testdb/redo03.log''
 to ''/app/temp/redo03.log''";

set newname for datafile 1 to '/app/temp/system01.dbf';
set newname for datafile 2 to '/app/temp/sysaux01.dbf';
set newname for datafile 3 to '/app/temp/undotbs01.dbf';
set newname for datafile 6 to '/app/temp/koo01.dbf';
set newname for datafile 9 to '/app/temp/koo02.dbf';

restore datafile 1,2,3,6,9;
switch datafile all;
sql 'alter session set nls_date_format="rrrr-mm-dd:hh24:mi:ss"';
set until time='2012-02-26:17:48:14';
sql "alter database flashback off";
recover database skip tablespace 'TEST', 'USERS', 'EXAMPLE', 'FBDA';
sql "alter database flashback on";
}

------------------------------------------------------------------
------------------------------------------------------------------
확인작업

SQL에서 작업
SQL> alter database open resetlogs;

Database altered.

SQL> select count(*) from koo.test;

  COUNT(*)
----------
      1000

여기서 중요한 점은 중간에
sql 'alter session set nls_date_format="rrrr-mm-dd:hh24:mi:ss"';
set until time='2012-02-26:17:48:14';
를 반드시 써주셔야 불완전복구가 된다는 것입니다.


sql 'alter session set nls_date_format="rrrr-mm-dd:hh24:mi:ss"';  대신
RMAN실행 전
$ export nls_date_format='rrrr-mm-dd:hh24:mi:ss' 를 실행해주셔도 됩니다.

**** recover datafile 1,2,3,6,9;를 실행해버리면, oracle에서 database level이 아닌 datafile level로 생각해서 복구하기때문에
불완전복구 그런거 없습니다.(recover datafile 'users01.dbf' until time; 명령어는 사용할 수 없음을 기억합시다)
불완전복구를 하려면 recover database 를 기본적으로 사용해주셔야 합니다.
이후에 skip tablespace를 명시하면 RMAN에서 알아서 skip 된 tablespace는 OFFLINE처리해버립니다.

* 중간에 flashback off, on을 한 이유는 실행 도중 버그발생떄문에 넣어준 것으로 기본적으로 안 넣어주셔도 됩니다.
(http://gyh214.tistory.com/129  참조)



여기서 마지막 남은 가장 중요한점

OPEN되고 난 후 DB의 상태는
임시경로의 controlfile, logfile을 사용하고 있고, 필수데이터파일만 임시경로에서 사용하고 있다는 점입니다.


남은 작업은
살린 데이터를 export하여서 파일로 저장 후 임시경로에서의 DB는 완전히 꺼버리고, 모든 파일을 삭제 후
파라미터파일에서 원래 DB의 control파일을 지정한 후 원래 DB를 open 하고 나서 자료를 import해야합니다.

[oracle@server16 ~]$ exp koo/koo tables=test file='/app/oracle/test.dmp'

SQL> shutdown immediate

[oracle@server16 temp]$ pwd
/app/temp
[oracle@server16 temp]$ rm *
[oracle@server16 temp]$ vi $ORACLE_HOME/dbs/inittestdb.ora
*.control_files='/app/oracle/oradata/testdb/control01.ctl'  (임시경로의 controlfile은 주석)
[oracle@server16 ~]$ sqlplus  / as sysdba
SQL> startup
[oracle@server16 ~]$ imp koo/koo file='/app/oracle/test.dmp' full=y ignore=y