강좌
클라우드/리눅스에 관한 강좌입니다.
데이터베이스 분류

log miner의 활용

작성자 정보

  • 웹관리자 작성
  • 작성일

컨텐츠 정보

본문

log miner의 활용

t.gif
t.gif
이전에 쓴 아래의 글을 다시 읽어보니 실행방법에 치우친 것 같아 추가적으로 덧붙인다.

실수로 데이터를 삭제한 것을, 오라클에서는 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)

관련자료

댓글 0
등록된 댓글이 없습니다.

공지사항


뉴스광장


  • 현재 회원수 :  60,150 명
  • 현재 강좌수 :  36,432 개
  • 현재 접속자 :  217 명