이전에 쓴 아래의 글을 다시 읽어보니 실행방법에 치우친 것 같아 추가적으로 덧붙인다.
실수로 데이터를 삭제한 것을, 오라클에서는 user error라고 하여 에러종류중 하나로 취급한다. 밑에서 언급되는 삭제된 데이터는 user error에 인한 것으로 묵시적으로 취급할 것이다. 로그마이너는 대충 다음과 같은 기능을 수행할 수 있다.
테이블 데이터를 delete한 사용자 파악 삭제한 데이터를 검출하여 복구 DML문장을 수행한 사용자와 실행된 순서 파악 활동이 많은 테이블(디스크 액세스 분석정보) 파악
[예제] C:oracleadminmaddogpfileinit.ora utl_file_dir=C:oracleoradatamaddog
SQL> connect sys/change_on_install 연결되었습니다. SQL> @?/rdbms/admin/dbmslm.sql
패키지가 생성되었습니다.
권한이 부여되었습니다.
dbmslmd.sql파일의 145라인중 513을 1000으로 변경한 다음, 실행 SQL> @?/rdbms/admin/dbmslmd.sql
패키지가 생성되었습니다.
패키지 본체가 생성되었습니다.
오류가 없음.
권한이 부여되었습니다.
[kang유저에서 다음을 수행]
SQL> create table test ( id varchar(10), name varchar(10));
테이블이 생성되었습니다.
SQL> insert into test values('maddog', '강명규');
1 개의 행이 만들어졌습니다.
SQL> insert into test values('superman', '슈퍼맨');
1 개의 행이 만들어졌습니다.
SQL> commit;
커밋이 완료되었습니다.
SQL>
[다시 sys유저에서] 이미 logmnr_dic.ora파일이 존재한다면 EOF에러가 발생하므로, 먼저 삭제한 다음 해야한다. 그리고, 분석할 객체(테이블,.. 여기서는 kang의 test테이블이 될 것이다.)를 먼저 생성한 후 실행해주는 것이 좋다. 아니면, v_logmnr_contents의 seg_name, seg_type컬럼값이 표시되지 않는다.
SQL> exec dbms_logmnr_d.build('logmnr_dic.ora', 'C:oracleoradatamaddog');
SQL> select member from v$logfile;
MEMBER -------------------------------------------------------------------------------- C:ORACLEORADATAMADDOGREDO01.LOG C:ORACLEORADATAMADDOGREDO02.LOG C:ORACLEORADATAMADDOGREDO03.LOG
SQL> exec dbms_logmnr.add_logfile('C:ORACLEORADATAMADDOGREDO01.LOG', dbms_logmnr.NEW);
PL/SQL 처리가 정상적으로 완료되었습니다.
SQL> exec dbms_logmnr.add_logfile('C:ORACLEORADATAMADDOGREDO02.log', dbms_logmnr.ADDFILE);
PL/SQL 처리가 정상적으로 완료되었습니다.
SQL> exec dbms_logmnr.add_logfile('C:ORACLEORADATAMADDOGREDO03.log', dbms_logmnr.ADDFILE);
PL/SQL 처리가 정상적으로 완료되었습니다.
SQL> exec dbms_logmnr.start_logmnr(dictfilename=> 'C:oracleoradatamaddoglogmnr_dic.ora');
PL/SQL 처리가 정상적으로 완료되었습니다.
이제, kang에서 insert한 작업에 대한 것을 v$logmnr_contents뷰를 통해 알아보자.
SQL> set linesize 200 SQL> col operation format a10 SQL> col sql_redo format a40 SQL> col sql_undo format a40
SQL> select operation, sql_redo, sql_undo 2 from v$logmnr_contents 3 where 4 seg_owner='KANG' and seg_name='TEST' and 5 operation='INSERT' and username='KANG';
OPERATION SQL_REDO SQL_UNDO ---------- ---------------------------------------- ---------------------------------------- INSERT insert into "KANG"."TEST"("ID","NAME") v delete from "KANG"."TEST" where "ID" = ' alues ('maddog','강명규'); maddog' and "NAME" = '강명규' and ROWID = 'AAAAxnAADAAAAADAAA';
INSERT insert into "KANG"."TEST"("ID","NAME") v delete from "KANG"."TEST" where "ID" = ' alues ('superman','슈퍼맨'); superman' and "NAME" = '슈퍼맨' and ROWI D = 'AAAAxnAADAAAAADAAB';
테이블 소유자가 KANG이고, 테이블명이 TEST, KANG이란 유저가 INSERT한 레코드를 찾는 것이다. SQL_REDO에서는 작업한 내용이 표시되고, SQL_UNDO에는 취소할 수 있는 SQL문이 표시된다. 즉, SQL_REDO와 대응되는 SQL_UNDO는 실행한 작업을 되돌릴 수 있게 한다. 위에서는 ROWID가 ROW를 식별하기 위한 조건으로 표시되고 있는데, 실제 ROWID를 확인해 보자.
[KANG유저에서 실행] SQL> SELECT ROWID, TEST.* FROM TEST;
ROWID ID NAME ------------------ ---------- ---------- AAAAxnAADAAAAADAAA maddog 강명규 AAAAxnAADAAAAADAAB superman 슈퍼맨
그럼, 실수로 테이블데이터를 삭제했을때의 시나리오를 생각해 보자.
[KANG유저에서 실행] SQL> delete from test;
2 행이 삭제되었습니다.
SQL> commit;
커밋이 완료되었습니다.
위에서 test에 있는 모든 데이터를 삭제했고, commit까지 했다. 어떻게 복구할 것인가? v_logmnr_contents뷰에서 delete operation을 검색하여 나온 row의 sql_undo컬럼값으로 실행하면 될 것이다.
SQL> select operation, sql_redo, sql_undo 2 from v$logmnr_contents 3 where 4 seg_owner='KANG' and seg_name='TEST' and 5 operation='DELETE' and username='KANG';
OPERATION SQL_REDO SQL_UNDO ---------- ---------------------------------------- ---------------------------------------- DELETE delete from "KANG"."TEST" where "ID" = ' insert into "KANG"."TEST"("ID","NAME") v maddog' and "NAME" = '강명규' and ROWID alues ('maddog','강명규'); = 'AAAAxnAADAAAAADAAA';
DELETE delete from "KANG"."TEST" where "ID" = ' insert into "KANG"."TEST"("ID","NAME") v superman' and "NAME" = '슈퍼맨' and ROWI alues ('superman','슈퍼맨'); D = 'AAAAxnAADAAAAADAAB';
sql_undo컬럼값을 수행해 주자. 복구끝.
SQL> insert into "KANG"."TEST"("ID","NAME") values ('maddog','강명규');
1 개의 행이 만들어졌습니다.
SQL> insert into "KANG"."TEST"("ID","NAME") values ('superman','슈퍼맨');
1 개의 행이 만들어졌습니다.
SQL> commit;
커밋이 완료되었습니다.
SQL> select * from kang.test;
ID NAME ---------- ---------- superman 슈퍼맨 maddog 강명규
SQL>
|
This article comes from dbakorea.pe.kr (Leave this line as is)
|