11g -> 12c -> 18c -> 19c (single,RAC) -> 21c
복구할때 사용하는 data
1. flashback database flashback db log
2. flashback drop 휴지통
3. flashback table undo data
4. flashback Query undo data
5. flashback version Query undo data
6. flashback Transaction Query undo data
7. flashback Archive (Total recall)
별도의 테이블스페이스 완전하게 되돌리는 기능
💡 휴지통에서 복구하는 기능
휴지통에 들어가는 object?
1.Table
2.Index
- 유저를 drop하면 휴지통에 안들어간다.(=하나의 프로젝트를 날린다) <- 불완전 복구를 수행
유저는 수십개, 수백개의 테이블을 보유한다. 테이블을 다시 생성해서 데이터를 다시넣는것은 말이 안된다.
실습
1. emp 테이블에 sal 에 인덱스를 생성한다.
SCOTT @ orcl2 > create index emp_sal on emp(sal); SCOTT @ orcl2 > select index_name from user_indexes where table_name='EMP'; INDEX_NAME ------------------------------ EMP_SAL SCOTT @ orcl2 > select i.index_name, i.table_name, c.column_name from user_indexes i, user_ind_columns c where i.index_name = c.index_name and i.table_name='EMP';
2. emp 테이블을 drop 한다. -> 테이블을 drop하면 테이블에 관련된 인덱스들도 같이 삭제된다.SCOTT @ orcl2 > drop table emp; SCOTT @ orcl2 > select i.index_name, i.table_name, c.column_name from user_indexes i, user_ind_columns c where i.index_name = c.index_name and i.table_name='EMP'; # 위 쿼리 조회하면 아무것도 안나온다.
3. 휴지통에 emp 테이블이 존재하는지 확인한다.
SCOTT @ orcl2 > show recyclebin or SCOTT @ orcl2 > select * from user_recyclebin order by droptime desc; or SCOTT @ orcl2 > select object_name, droptime, original_name from user_recyclebin;
💡 휴지통 속에서 emp 테이블을 복원하기 전에 반드시 관련 인덱스 이름을 index의 original 이름으로 변경해주는 작업을 해주어야 한다. 한번 복원하면 이름 변경이 어렵다.SCOTT @ orcl2 > select 'alter index ' || '"'|| object_name || '"' || ' rename to ' || original_name || ';' from user_recyclebin where type='INDEX' and droptime like '2023-10-19%'; alter index "BIN$CAhFOlXszfDgYAB/AQAXag==$0" rename to EMP_SAL;
➡️ 위 스크립트를 미리 만들어놓지 않으면 휴지통속에서 복원하고 나서 인덱스 이름을 변경해주느랴 시간도 많이들고 힘들다!!
4. emp 테이블을 휴지통에서 복원한다.SCOTT @ orcl2 > flashback table emp to before drop; SCOTT @ orcl2 > select * from emp; SCOTT @ orcl2 > select index_name from user_indexes;
5. 인덱스의 이름을 원래 이름으로 변경해준다.SCOTT @ orcl2 > alter index "BIN$CAhFOlXszfDgYAB/AQAXag==$0" rename to EMP_SAL; SCOTT @ orcl2 > select index_name from user_indexes;
문제
hr계정의 employees 테이블을 drop하고, flashback으로 복구하는데 미리 테이블 export를 하고 하기!
$ exp hr/hr tables=employees file=employees.dmp
1. employees 테이블을 drop한다.
# drop전에 확인해봄 select i.index_name, i.table_name, c.column_name from user_indexes i, user_ind_columns c where i.index_name = c.index_name and i.table_name='EMPLOYEES';
HR> drop table employees cascade constraints;
2. 휴지통에 있는지 확인한다.
select * from user_recyclebin order by droptime desc;
3. 인덱스, 트리거 생성 스크립트를 만든다.select 'alter index ' || '"'|| object_name || '"' || ' rename to ' || original_name || ';' from user_recyclebin where type='INDEX' and droptime like '2023-10-19%'; select 'alter trigger ' || '"'|| object_name || '"' || ' rename to ' || original_name || ';' from user_recyclebin where type='TRIGGER' and droptime like '2023-10-19%'; alter index "BIN$CAeul70GZa3gYAB/AQAZNA==$0" rename to EMP_DEPARTMENT_IX; alter index "BIN$CAeul70HZa3gYAB/AQAZNA==$0" rename to EMP_JOB_IX; alter index "BIN$CAeul70IZa3gYAB/AQAZNA==$0" rename to EMP_MANAGER_IX; alter index "BIN$CAeul70JZa3gYAB/AQAZNA==$0" rename to EMP_NAME_IX; alter index "BIN$CAeul70KZa3gYAB/AQAZNA==$0" rename to EMP_EMAIL_UK; alter index "BIN$CAeul70LZa3gYAB/AQAZNA==$0" rename to EMP_EMP_ID_PK; alter trigger "BIN$CAeul70MZa3gYAB/AQAZNA==$0" rename to SECURE_EMPLOYEES; alter trigger "BIN$CAeul70NZa3gYAB/AQAZNA==$0" rename to UPDATE_JOB_HISTORY;
4. 휴지통에서 꺼낸다.
SCOTT @ orcl2 > flashback table employees to before drop; SCOTT @ orcl2 > select * from employees; SCOTT @ orcl2 > select index_name from user_indexes;
5. 인덱스 이름을 바꾸어준다.
alter index "BIN$CAeul70GZa3gYAB/AQAZNA==$0" rename to EMP_DEPARTMENT_IX; alter index "BIN$CAeul70HZa3gYAB/AQAZNA==$0" rename to EMP_JOB_IX; alter index "BIN$CAeul70IZa3gYAB/AQAZNA==$0" rename to EMP_MANAGER_IX; alter index "BIN$CAeul70JZa3gYAB/AQAZNA==$0" rename to EMP_NAME_IX; alter index "BIN$CAeul70KZa3gYAB/AQAZNA==$0" rename to EMP_EMAIL_UK; alter index "BIN$CAeul70LZa3gYAB/AQAZNA==$0" rename to EMP_EMP_ID_PK; alter trigger "BIN$CAeul70MZa3gYAB/AQAZNA==$0" rename to SECURE_EMPLOYEES; alter trigger "BIN$CAeul70NZa3gYAB/AQAZNA==$0" rename to UPDATE_JOB_HISTORY; select * from user_triggers; select index_name from user_indexes;
💡 flashback table을 하기 전에 과거 시점의 data를 미리 확인할 때 사용하는 기능! 특정 테이블의 과거의 데이터를 볼 수 있다.
실습
1. 시간과 scn 번호 확인하기
SQL> select systimestamp from dual; SYSTIMESTAMP --------------------------------------------------------------------------- 19-OCT-23 10.54.58.659565 AM +09:00 SQL> select current_scn from v$database; CURRENT_SCN ----------- 2078789 SYS @ orcl2 > grant select on v_$database to scott; # sys로 왔다갔다 하기 번거로워서 권한 주었다.
2. dept 테이블을 delete하기
SCOTT> delete from dept; SCOTT> commit;
3. 지웠지만 아래쿼리로 dept 테이블 확인해보기
SCOTT> select * from dept as of timestamp to_timestamp('2023/10/19:10:54:40', 'RRRR/MM/DD:HH24:MI:SS'); DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON SCOTT> select * from dept; no rows selected SCOTT> select * from dept as of timestamp (systimestamp - interval '5' minute); # 현재시간 기준 5분전 데이터를 보겠다.
➡️ 가급전 시간을 사용해서 보고, 복구하기
문제
dept 테이블을 flashback table로 복구하기
데이타가 지워지기 전 시점으로 flashback 을 수행한다.
SCOTT>
alter table dept enable row movement;
select table_name, row_movement
from user_tables
where table_name='DEPT';
TABLE_NAME ROW_MOVE
------------------------------ --------
DEPT ENABLED
-- 19-OCT-23 10.54.58.659565 AM +09:00
flashback table dept to timestamp to_timestamp('2023/10/19:10:54:40','RRRR/MM/DD:HH24:MI:SS');
Flashback complete.
SCOTT> select * from dept;
SCOTT> commit; -- rollback 수행해보니 안된다. 커밋할 필요 없음!
문제
flashback database 로그가 생성되지 않도록 flashback database 기능을 끄기
디비 내리고 마운트로 올린다.
SCOTT @ orcl2 > select flashback_on from v$database;
>
FLASHBACK_ON
------------------
YES
SYS> shutdown immediate
SYS> startup mount
SYS> alter database flashback off;
SYS> alter database open;
SYS @ orcl2 > select flashback_on from v$database;
FLASHBACK_ON
------------------
NO
💡 특정 테이블이 그동안 어떻게 변경이 되어왔는지에 대한 이력정보를 보고자 할 때 사용됩니다.
실습
1. 시간, scn을 확인하기
SCOTT> select systimestamp from dual; SYSTIMESTAMP --------------------------------------------------------- 19-OCT-23 11.15.26.730908 AM +09:00 SCOTT> select current_scn from v$database; CURRENT_SCN ----------- 2080662
2. smith 의 월급을 0 으로 변경한다.
update emp set sal = 0 where ename='SMITH';
3. commit;
4. smith 의 부서번호를 40번으로 변경한다.update emp set deptno = 40 where ename='SMITH';
5. commit;
6. smith 의 data 를 지운다.delete from emp where ename='SMITH';
7. commit;
8. version query를 수행한다.--rownum 같은 쉐도우컬럼이라 *로 하면 안나온다. select ename, sal, deptno, versions_operation, versions_startscn, versions_endscn, versions_starttime, versions_endtime from emp versions between scn minvalue and maxvalue where ename='SMITH' order by versions_starttime asc nulls first;
select ename, sal, deptno, versions_operation, versions_startscn, versions_endscn, versions_starttime, versions_endtime from emp versions between scn minvalue and maxvalue where ename='SMITH' order by versions_endtime ; # 얘도 같은 결과가 나오긴 함
문제
다시 smith의 데이터를 복구하기
19-OCT-23 11.15.26.730908 AM +09:00
alter table emp enable row movement; -- 확실히 복구전 데이터와 복구할 데이터가 맞는지 확인하는 버전쿼리 select ename, sal, deptno from emp as of timestamp to_timestamp('2023/10/19:11:15:26','RRRR/MM/DD:HH24:MI:SS') where ename ='SMITH'; ENAME SAL DEPTNO ---------- ---------- ---------- SMITH 800 20 -- 위 데이터가 flashback할 데이터가 맞다면 flashback!! flashback table emp to timestamp to_timestamp('2023/10/19:11:15:26','RRRR/MM/DD:HH24:MI:SS');
💡 테이블이 그동안 어떻게 변경이 되어 왔는지에 대한 이력정보를 DML문으로 확인하는 쿼리
여기서 출력되는 DML문은 과거로 데이터를 되돌릴 수 있는 DML문입니다.
transaction query insert ----------------> delete delete ----------------> insert
➡️ 지금 내가 insert를 하고
transaction query를 조회
한다면 DML문은 delete로 나온다. 과거로 돌려야하니까!
실습
1. flashback transaction Query 를 수행하기위한 로그를 담을 supplemental 공간을 활성화 시킨다.
-- 활성화 되었는지 확인 SQL> select supplemental_log_data_min from v$database; SUPPLEME -------- NO -- 활성화시키기 SYS> alter database add supplemental log data; SYS> select supplemental_log_data_min from v$database; SUPPLEME -------- YES
2. 현재 scn 을 확인한다.
SYS> select current_scn from v$database; CURRENT_SCN ----------- 2082379
3. 직업이 SALESMAN 인 사원들의 직업을 SALESMAN 에서 SALESMAN2 로 변경한다.
SCOTT> update emp set job='SALESMAN2' where job='SALESMAN'; SCOTT> commit;
- 현재 scn 번호를 확인한다.
SCOTT> select current_scn from v$database; CURRENT_SCN ----------- 2082414
- flashback transaction Query 를 수행한다.
-- scott에게 권한주기 SYS> grant select any transaction to scott; -- scn 번호는 between update전 and update후 SCOTT> select undo_sql from flashback_transaction_query where table_name='EMP' and commit_scn between 2082379 and 2082414 order by start_timestamp desc; UNDO_SQL ------------------------------------------------------------------------------ update "SCOTT"."EMP" set "JOB" = 'SALESMAN' where ROWID = 'AAASXUAAEAAAAQ3AAI'; update "SCOTT"."EMP" set "JOB" = 'SALESMAN' where ROWID = 'AAASXUAAEAAAAQ3AAE'; update "SCOTT"."EMP" set "JOB" = 'SALESMAN' where ROWID = 'AAASXUAAEAAAAQ3AAF'; update "SCOTT"."EMP" set "JOB" = 'SALESMAN' where ROWID = 'AAASXUAAEAAAAQ3AAG';
점심시간 문제
dept 테이블의 40번 부서번호의 loc를 seoul로 변경하고 commit한 다음, flashback transaction Query
로 다시 원복시킬 수 있는 update 문장을 뽑아내기
1. 활성화 되었는지 확인
SQL> select supplemental_log_data_min from v$database; SUPPLEME -------- YES
2. 현재 scn 을 확인한다.
SYS> select current_scn from v$database; CURRENT_SCN ----------- 2239385
3. 40번 부서번호의 loc를 seoul로 변경
SCOTT> update dept set loc='seoul' where deptno=40; commit;
4. 현재 scn 번호를 확인한다.
SCOTT> select current_scn from v$database; CURRENT_SCN ----------- 2239396
5. flashback transaction Query 수행
SCOTT> select undo_sql from flashback_transaction_query where table_name='DEPT' and commit_scn between 2239385 and 2239396 order by start_timestamp desc; UNDO_SQL ----------------------------------------------------------------------------- update "SCOTT"."DEPT" set "LOC" = 'BOSTON' where ROWID = 'AAASXTAAEAAAAQrAAD';
undo_retention
SYS> show parameter undo_retention;
undo_retention 3600
SYS> show parameter
undo_tablespace UNDOTBS1
UNDOTBS1의 용도는 1. rollback을 위해, 2. 읽기 일관성을 보존하기 위해
예를들어 아래경우 스캇2에서 5000이 보이는 이유는 언두테이블스페이스 안에 언두 세그먼트에 5000이 써져있다. SCOTT1에서 commit을 하지 않았으니 다른사람들은 당연히 5000을 봐야한다.
SCOTT1 SCOTT2
update king
5000->0
commit X select ename, sal
from emp
where ename='KING';
5000->0 하면 5000이 언두ts에 들어가고 이것은 다른 세션들과의 읽기 일관성을 위해 보존이고 rollback을 하려면 이것을 읽고 rollback을 해야하기때문에 필요하다.
그런데, 한가지 더 기능이 있다 ! 3. flashback 을 위해 필요하다.
여기 안에 5000이 저장되어있으니까 flashback version query
UNDOTBS1 guarantee를 1시간으로 해놓으면 악착같이 1시간을 가지고 있는다. 커밋해도 남아있다. 이런것들이 많으면 undo tablespace가 엄청 꽉찬다. 문제는 누군가 업데이트 하려고 하면 3000->0 3000을 undo에 넣어야 성공하는데 들어갈 자리가 없어서 update가 실패한다.
그래서 해결방법이 3. flashback 을 위해 필요하다.
이 기능은 별도의 테이블스페이스를 따로 만들자! 해서 나온것이 flashback Archive
이다.
실습
1. undo retention 을 1초로 변경한다.
alter system set undo_retention = 1;
2. db 종료후 재시작
startup force SYS @ orcl2 > show parameter undo_retention; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ undo_retention integer 1
3. 과거로 되돌릴 data 를 저장할 테이블 스페이스를 생성한다.
SYS> create tablespace ts701 datafile '/home/oracle/ts701.dbf' size 100m;
4. flashback archive 를 관리할 유져를 생성한다.
SYS> create user flash_admin identified by flash_admin default tablespace ts701; grant connect, resource to flash_admin; grant flashback archive administer to flash_admin;
5. flashback archive 를 생성한다.
SYS> connect flash_admin/flash_admin; FLASH_ADMIN @ orcl2 > create flashback archive flasharch1 tablespace ts701 retention 1 year;
➡️설명 : 과거로 되돌릴 data 를 1년간 저장할수있도록 생성
6. flashback archive 를 사용할수 있는 권한을 scott 에게 부여
FLASH_ADMIN @ orcl2 > grant flashback archive on flasharch1 to scott;
7. scott 유져에서 emp 테이블이 total recall 이 되겠금 설정한다.
connect scott/tiger SCOTT> alter table emp flashback archive flasharch1; SCOTT> select * from user_flashback_archive_tables; EMP SCOTT FLASHARCH1 SYS_FBA_HIST_75220 ENABLED
➡️ emp는 이제 1년동안 flashback의 기능을 모두 쓸수있게 되었다. 1년안에는 언제든지 emp를 복구할 수 있게 되었다!
8. emp테이블 지워보자SCOTT> delete from emp; SCOTT> commit;
9. emp 테이블을 delete 전으로 되돌리시오! (시간 먼저 확인하고 지우기. 그냥 때려맞춤.. 나는)
SCOTT> alter table emp enable row movement; SCOTT> select systimestamp from dual; SCOTT> flashback table emp to timestamp --얘로 확인하고 가늠하기 to_timestamp('2023/10/19:14:02:00','RRRR/MM/DD:HH24:MI:SS');
10. emp 테이블을 flash archive 대상에서 제외하는 방법
SYS> grant flashback archive administer to scott; --권한 부여 SCOTT> alter table emp no flashback archive; SCOTT> select * from user_flashback_archive_tables; no rows selected
문제
hr 계정의 employees 테이블과 departments테이블을 1년안에 언제든 되돌릴 수 있도록 지정하고, 두개의 테이블을 모두 delete, commit한 후에 복구하기
1. flashback archive 를 사용할수 있는 권한을 hr 에게 부여
FLASH_ADMIN @ orcl2 > grant flashback archive on flasharch1 to hr;
2. hr 유져에서 employees, departments 테이블이 total recall 이 되도록 설정한다.
connect hr/hr HR> alter table employees flashback archive flasharch1; HR> alter table departments flashback archive flasharch1; HR> select * from user_flashback_archive_tables;
➡️ emp는 이제 1년동안 flashback의 기능을 모두 쓸수있게 되었다. 1년안에는 언제든지 emp를 복구할 수 있게 되었다!
8. 테이블 지워보자HR> delete from employees; HR> commit; HR> delete from departments; --안되어서 이거 해줌 alter table departments drop constraints dept_id_pk cascade; HR> commit;
9. 테이블들을 delete 전으로 되돌리시오!
19-OCT-23 02.14.44.750499 PM +09:00 -- 보다 일분 전HR> alter table employees enable row movement; HR> alter table departments enable row movement; HR> select systimestamp from dual; HR> flashback table employees to timestamp to_timestamp('2023/10/19:14:13:00','RRRR/MM/DD:HH24:MI:SS'); HR> flashback table departments to timestamp to_timestamp('2023/10/19:14:13:00','RRRR/MM/DD:HH24:MI:SS');
10. 테이블들을 다시 flash archive 대상에서 제외
SYS> grant flashback archive administer to hr; --권한 부여 HR> alter table employees no flashback archive; HR> alter table departments no flashback archive; HR> select * from user_flashback_archive_tables; no rows selected
❗ 참고
위 문제 풀면서 나는 잘 되었는데 안되는 사람들이 있었음. departments 테이블에 제약이 걸려있어서 안되는거였어서 아래처럼 해준 후 진행했음
select *
from user_constraints
where table_name in ('EMPLOYEES','DEPARTMENTS','JOB_HISTORY')
and constraint_type in ('C', 'P');
alter table departments
drop constraints dept_id_pk cascade;
delete from dept_id_pk cascade;
시나리오1.
테이블 스페이스가 drop되었을 때 drop 되기 전으로 복구하기
➡️ 컨트롤 파일이 ts704를 알고있어야 복구를 할 수 있는데 drop은 controlfile에서 지워지기 때문에 복구가 안된다.
해결
drop 테이블스페이스 시 time base 불완전 복구를 rman 으로 수행
1. 알맨으로 전체 백업을 수행한다.
$ rman target sys/oracle@orcl2 catalog rc_user/rc_user@orcl3 RMAN> backup database include current controlfile; Starting Control File and SPFILE Autobackup at 2023/10/19:15:05:06 piece handle=/u01/app/oracle/flash_recovery_area/ORCL2/autobackup/2023_10_19/o1_mf_s_1150643107_lm1krmkt_.bkp comment=NONE Finished Control File and SPFILE Autobackup at 2023/10/19:15:05:08
✅ 후에 autobackup 받은 controlfile 위치와 이름을 아래와 같이 찾는다.
'/u01/app/oracle/flash_recovery_area/ORCL2/autobackup/2023_10_19/o1_mf_s_1150643107_lm1krmkt_.bkp';
2. 로그 스위치를 5번 이상 일으킨다.
SYS > @logs SYS > @ckpt
SYS @ orcl2 > select tablespace_name from dba_tablespaces; TABLESPACE_NAME ------------------------------ SYSTEM SYSAUX UNDOTBS1 TEMP USERS EXAMPLE TS01 TS701 TS600 TS23 TS709
3. 테이블 스페이스를 drop하기 전에 export를 받는다.
SYS> alter tablespace ts01 read only; $ exp transport_tablespace=y tablespaces=ts01 Username: sys as sysdba Password: Export terminated successfully without warnings. SYS> alter tablespace ts01 read write;
4. controlfile을 생성하는 스크립트로 생성하기.
SYS> alter database backup controlfile to trace as '/home/oracle/create_con10.sql';
5. 테이블 스페이스를 drop 한다.
SYS > drop tablespace ts01 including contents and datafiles;
6. ts01 테이블 스페이스 drop 된 시간을 alert log file 에서 찾는다.
[orcl2:~]$ trace [orcl2:trace]$ vi alert* Thu Oct 19 15:13:31 2023
7. shutdown immediate 한후 startup nomount 한다.
✅ 옛날 ts01 테이블 스페이스를 인식하고 있는 옛날 컨트롤파일로 복원하기 위해nomount
로 올렸다. nomount단계에서 컨트롤 파일을 복원해야하니까!8. ts01 테이블 스페이스를 알고있는 백업받은 controlfile 을 복원한다.
$ rman target / -- nocatalog로 붙으면 접속이 된다. RMAN> restore controlfile from '/u01/app/oracle/flash_recovery_area/ORCL2/autobackup/2023_10_19/o1_mf_s_1150643107_lm1krmkt_.bkp';
9. mount 로 올린다.
RMAN> alter database mount;
10. ts01 테이블스페이스 drop 되기 전 10초전으로 데이터 베이스를 불완전 복구한다.
RMAN> run { set until time='2023/10/19:15:13:20'; restore database; recover database; } media recovery complete, elapsed time: 00:00:01 Finished recover at 2023/10/19:15:21:50 SYS > alter database open resetlogs;
11. ts01 테이블스페이스 있는지 확인한다.
SYS > select tablespace_name, file_name from dba_data_files; -- 잘 있다! TS01 /u01/app/oracle/oradata/orcl2/ts01.dbf
12. 불완전 복구 했으니 RMAN으로 fullbakcup 진행
$ rman target sys/oracle@orcl2 catalog rc_user/rc_user@orcl3 RMAN> backup database include current controlfile; Starting Control File and SPFILE Autobackup at 2023/10/19:15:24:27 piece handle=/u01/app/oracle/flash_recovery_area/ORCL2/autobackup/2023_10_19/o1_mf_s_1150644267_lm1lww07_.bkp comment=NONE Finished Control File and SPFILE Autobackup at 2023/10/19:15:24:28
💡 우리는 적어놓고 했지만 만약 예전 controlfile 백업본이 무엇인지 모른다면
RMAN> list backup of controlfile; -- 시간과 날짜가 나오는데 그것을 보고서 tablespace drop되기 전의 controlfile의 Piece Name을 찾으면 된다.
Piece Name: /u01/app/oracle/flash_recovery_area/ORCL2/autobackup/2023_10_19/o1_mf_s_1150644267_lm1lww07_.bkp
문제
ts100 tablespace를 drop하고 불완전복구 하기.
2. 로그 스위치를 5번 이상 일으킨다.
SYS > @logs SYS > @ckpt
3. 테이블 스페이스를 drop하기 전에 export를 받는다.
SYS> alter tablespace example read only; $ exp transport_tablespace=y tablespaces=example file=example1019.dmp Username: sys as sysdba Password: SYS> alter tablespace example read write;
4. controlfile을 생성하는 스크립트로 생성하기.
SYS> alter database backup controlfile to trace as '/home/oracle/create_con11.sql';
5. 테이블 스페이스를 drop 한다.
SYS > drop tablespace example including contents and datafiles;
6. example 테이블 스페이스 drop 된 시간을 alert log file 에서 찾는다.
[orcl2:~]$ trace [orcl2:trace]$ vi alert* Thu Oct 19 15:13:31 2023
7. shutdown immediate 한후 startup nomount 한다.
✅ 옛날 ts01 테이블 스페이스를 인식하고 있는 옛날 컨트롤파일로 복원하기 위해nomount
로 올렸다. nomount단계에서 컨트롤 파일을 복원해야하니까!8. ts01 테이블 스페이스를 알고있는 백업받은 controlfile 을 복원한다.
$ rman target / -- nocatalog로 붙으면 접속이 된다. RMAN> restore controlfile from '/u01/app/oracle/flash_recovery_area/ORCL2/autobackup/2023_10_19/o1_mf_s_1150643107_lm1krmkt_.bkp';
9. mount 로 올린다.
RMAN> alter database mount;
10. ts01 테이블스페이스 drop 되기 전 10초전으로 데이터 베이스를 불완전 복구한다.
RMAN> run { set until time='2023/10/19:15:13:20'; restore database; recover database; } media recovery complete, elapsed time: 00:00:01 Finished recover at 2023/10/19:15:21:50 SYS > alter database open resetlogs;
11. ts01 테이블스페이스 있는지 확인한다.
SYS > select tablespace_name, file_name from dba_data_files; -- 잘 있다! TS01 /u01/app/oracle/oradata/orcl2/ts01.dbf
12. 불완전 복구 했으니 RMAN으로 fullbakcup 진행
시나리오 2.
모든 datafile을 전부 삭제하고 모든 redo log file을 전부 삭제하고 복구
💡 controlfile만 남기고 모두 삭제하는것임. redo log file 안에 current redo log가 포함되어있다. current redo log file은 아직 아카이빙 되지 않은 로그파일이다! current redo log file이 깨지기 전으로 cancel base 불완전 복구를 해야합니다.
Starting Control File and SPFILE Autobackup at 2023/10/19:16:03:54
piece handle=/u01/app/oracle/flash_recovery_area/ORCL2/autobackup/2023_10_19/o1_mf_s_1150646634_lm1o6tty_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 2023/10/19:16:03:55
- 로그 스위치를 3번 일으킨다.
@logs
- 체크 포인트를 수동으로 일으킨다.
- RMAN 으로 Full backup 을 수행한다. - 방금했으니 안해도 됨
- 로그 스위치를 3번 일으킨다.
@logs
5. 체크 포인트를 수동으로 일으킨다.
6. current redo log group 이 몇번인지 확인한다.SYS @ orcl2 > @log GROUP# MEMBERS STATUS SEQUENCE# ---------- ---------- ---------------- ---------- 1 1 CURRENT 13 -- 1번이 CURRENT 2 1 INACTIVE 11 3 1 INACTIVE 12
- current redo log group 의 멤버가 무엇인지 확인한다. (우린 근데 다 지울거라 안해도 되긴 함)
@logf GROUP# MEMBER ---------- --------------------------------------------- 1 /u01/app/oracle/oradata/orcl2/redo01.log 2 /u01/app/oracle/oradata/orcl2/redo02.log 3 /u01/app/oracle/oradata/orcl2/redo03.log
- shutdown abort
- os 에서 모든 datafile, 모든 redo log file을 삭제한다.
-- datafile 위치 확인 SYS @ orcl2 > @ts TABLESPACE FILE_NAME ---------- --------------------------------------------- TS600 /home/oracle/ts600.dbf TS23 /u01/app/oracle/oradata/orcl2/ts200.dbf TS01 /u01/app/oracle/oradata/orcl2/ts01.dbf TS709 /u01/app/oracle/oradata/orcl2/ts709.dbf TS701 /home/oracle/ts701.dbf EXAMPLE /u01/app/oracle/oradata/orcl2/example01.dbf USERS /u01/app/oracle/oradata/orcl2/users01.dbf UNDOTBS1 /u01/app/oracle/oradata/orcl2/undotbs01.dbf SYSAUX /u01/app/oracle/oradata/orcl2/sysaux01.dbf SYSTEM /u01/app/oracle/oradata/orcl2/system01.dbf
SYS> shutdown abort [orcl2:orcl2]$ rm *.log [orcl2:orcl2]$ rm *.dbf $rm /home/oracle/ts600.dbf $rm /home/oracle/ts701.dbf
- startup
- current redo log group 의 시퀀스 번호 확인 (14번)
SYS @ orcl2 > select group#, status, sequence# from v$log; GROUP# STATUS SEQUENCE# ---------- ---------------- ---------- 1 INACTIVE 13 3 INACTIVE 12 2 CURRENT 14 -- 14번 !!!!!
- RMAN으로 복구!
run { set until sequence 14 thread 1; restore database; recover database; }
- RMAN> alter database open resetlogs
⭐ 혹시 위 방법으로 복구가 안된다?? 아래로 수행!
RMAN> list failure; RMAN> advise failure; RMAN> repair failure;
➡️ 위와 같이 했는데 복구를 못했으면 datafile, controlfile, redo log file 전체 다 whole backup 받은 파일을 전부 원본 위치에 다 복원한 후에 startup 하면 됨!!
13. RMAN> alter database open resetlogs;
14. rman fullbackupRMAN> backup database include current controlfile;
문제
datafile중에 임의로 4개를 삭제하고 redologfile을 2개 삭제하고 복구하기
rm /u01/app/oracle/oradata/orcl2/example01.dbf
rm /u01/app/oracle/oradata/orcl2/users01.dbf
rm /u01/app/oracle/oradata/orcl2/undotbs01.dbf
rm /u01/app/oracle/oradata/orcl2/sysaux01.dbf
rm /u01/app/oracle/oradata/orcl2/system01.dbf
rm /u01/app/oracle/oradata/orcl2/redo01.log
rm /u01/app/oracle/oradata/orcl2/redo02.log
오늘의 마지막 문제
시나리오 3번 하기
시나리오 1번 : 테이블 스페이스 drop시 복구
시나리오 2번 : 모든 데이터 파일, 모든 리두로그파일 삭제 후 복구
시나리오 3번 : 모든 데이터 파일과 모든 controlfile을 삭제후 복구
1. 알맨 전체백업
$ rman target sys/oracle@orcl2 catalog rc_user/rc_user@orcl3 RMAN> backup database include current controlfile; Starting Control File and SPFILE Autobackup at 2023/10/19:16:54:40 piece handle=/u01/app/oracle/flash_recovery_area/ORCL2/autobackup/2023_10_19/o1_mf_s_1150649680_lm1r60w4_.bkp comment=NONE Finished Control File and SPFILE Autobackup at 2023/10/19:16:54:41 RMAN> show all; -- 알맨 셋팅 환경정보를 알 수 있다. CONFIGURE CONTROLFILE AUTOBACKUP ON;
2. DB의 ID확인
SYS> select dbid from v$database; DBID ---------- 1130331177
3. log스위치 3번랑 체크포인트 일으키기
4. current redo log group 이 몇번인지 확인한다.SYS @ orcl2 > @log GROUP# MEMBERS STATUS SEQUENCE# ---------- ---------- ---------------- ---------- 1 1 CURRENT 7 2 1 INACTIVE 5 3 1 INACTIVE 6 SYS @ orcl2 > @logf GROUP# MEMBER ---------- --------------------------------------------- 1 /u01/app/oracle/oradata/orcl2/redo01.log 2 /u01/app/oracle/oradata/orcl2/redo02.log 3 /u01/app/oracle/oradata/orcl2/redo03.log
4. controlfile을 생성하는 스크립트로 생성하기. -> 까먹고 안함
alter database backup controlfile to trace as '/home/oracle/create_con11.sql';
5. shutdown abort
6. os에서 모든 datafile, controlfile 삭제$ rm /home/oracle/ts600.dbf $ rm /home/oracle/ts701.dbf [orcl2:orcl2]$ rm *.dbf $ rm $ORACLE_HOME/dbs/spfileorcl2.ora $ rm $ORACLE_HOME/dbs/initorcl2.ora
7. startup -> controlfile 없어서 아예 안올라옴
SYS @ orcl2 > startup ORA-01078: failure in processing system parameters LRM-00109: could not open parameter file '/u01/app/oracle/product/11.2.0/dbhome_1/dbs/initorcl2.ora'
8. nocatalog로 알맨접속(shutdown된 상태에서 접속)
[orcl2:~]$ rman target / nocatalog
9. 가상으로 오라클을 nomount로 올린다.
RMAN> startup nomount
10. 백업받은 spfile을 복원합니다.RMAN> set dbid=1130331177; RMAN> restore spfile from autobackup;
11. 위 작업 에러남 아래로 수행
RMAN> restore spfile from '위에서 확인한 백업위치와 이름'; RMAN> restore spfile from '/u01/app/oracle/flash_recovery_area/ORCL2/autobackup/2023_10_19/o1_mf_s_1150649680_lm1r60w4_.bkp'; channel ORA_DISK_1: SPFILE restore from AUTOBACKUP complete Finished restore at 2023/10/19:17:12:48 RMAN> startup force;
12. startup force 안된다. 왜냐하면 datafile 없어서!
SYS> @i STATUS ------------ MOUNTED
13. mount상태니까 current redo log group 의 시퀀스 번호 확인 (7번)
SYS @ orcl2 > select group#, status, sequence# from v$log; GROUP# STATUS SEQUENCE# ---------- ---------------- ---------- 1 CURRENT 7 --얘 3 INACTIVE 6 2 INACTIVE 5
14. RMAN으로 복구!
[orcl2:~]$ rman target sys/oracle@orcl2 catalog rc_user/rc_user@orcl3 RMAN> run { set until sequence 7 thread 1; restore database; recover database; } Finished recover at 2023/10/19:17:15:53
15. resetlogs로 올리기
RMAN> alter database open resetlogs;
16. rman fullbackupRMAN> backup database include current controlfile; Starting Control File and SPFILE Autobackup at 2023/10/19:17:18:09 piece handle=/u01/app/oracle/flash_recovery_area/ORCL2/autobackup/2023_10_19/o1_mf_s_1150651089_lm1sl1pz_.bkp comment=NONE Finished Control File and SPFILE Autobackup at 2023/10/19:17:18:10
flashback database, flashback table 어떨때?
falshback은 데이터베이스를 전부 과거시점으로 되돌리는 것이다. 불완전 복구는 두가지가 있는데 recovery
, flashback database!
근데 flashback 하는것이 더 빠르기 때문에 이걸로 일단 하고 못한다면 리커버리를 하는 방향. user drop은 무조건 불완전 복구를 해주어야 해서 이 기능은 현업에서는 켠다. 우리는 디스크 공간이 넉넉하지 못해서 위에서 끈거였음
flashback database가 저장되는 flashback db log
는 아카이버로그 파일이 생성되는 위치에 생성이 되어있다.
[orcl2:ORCL2]$ pwd
/u01/app/oracle/flash_recovery_area/ORCL2
[orcl2:ORCL2]$ ls
archivelog autobackup backupset flashback --얘 onlinelog