探索Oracle之LogMiner 最佳实践一

前端之家收集整理的这篇文章主要介绍了探索Oracle之LogMiner 最佳实践一前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

探索Oracle之LogMiner 最佳实践一

作者:吴伟龙PrudentWoo

Oracle LogMiner 是Oracle公司8i以后提供的一个很有用日志分析工具,该工具可以帮助我们非常好的通过在线/归档日志文件提取数据库的操作痕迹,不仅仅是对本库,同时也可以提取其它的数据库的重做日志文件和归档日志文件。因为该工具具有完全还原数据库所有的DML和DDL操纵语句能力,使得其本身具有很强的犯罪取证和痕迹追踪功能。但是这个工具一直是一位蒙纱羞女在默默的等待有为的新青年dba们发起一次一次的挑战,因为这个对于很多DBA来说可能在整个生涯中都很难会有机会用上,尤其是新一代的DBA,他的很多功能已经被flashback & RMAN备份恢复所部分替代,但是他也具有完全不可替代的部分,那就是前面提到的数据的取证和痕迹追踪,在今天的这篇文章中我将详细介绍LogMiner的使用方法和场景。

LogMiner分析工具其实是由一组PL/sql包和一些动态视图(Oracle8i内置包的一部分)组成,它作为Oracle数据库的一部分来发布。但该工具在11g之前和其他Oracle内建工具相比使用起来显得有些复杂,主要原因是该工具没有提供任何的图形用户界面(GUI),当然oracle也很快意识到该问题,在11g的EM将LogMiner添加进去,大大降低了其使用难度。


示例:


这是一个LogMiner示例配置。在这个图中,位于波士顿的源数据库生成重做日志文件,这些文件被归档并发送到旧金山的数据库。已将LogMiner字典提取到这些重做日志文件中。LogMiner将实际分析重做日志文件的挖掘数据库位于旧金山。两边的数据库版本不要求一样。


LogMiner数据字典选项:


LogMiner需要一个字典来将对象id转换为对象名称,当它返回重做数据给你时。LogMiner为您提供了提供字典的三个选项:

使用Online Catalog: Oracle建议您将访问源数据库使用这个选项,同时创建重做日志文件,并在预期的表中没有对列定义进行更改。这是最高效、最容易使用的选项。

将LogMiner字典提取到重做日志文件中: Oracle建议您使用此选项时,不要期望访问重新创建日志文件的源数据库,或者您预期会对感兴趣的表中的列定义进行更改。

将LogMiner字典提取到一个平文本文件: 这个选项是为了向后兼容以前的版本而保留的。此选项并不保证事务一致性。Oracle建议您使用联机目录或从重做日志文件提取字典。

我们既然已经了解了什么是LogMiner之后,那么我们现在来开始做实验,用实验证明我说的话是对的:

LogMiner组件检查:

首先我们要确认数据库是否已经拥有必须的包,如果没有则需要运行两个包:@?/rdbms/admin/dbmslm.sql脚本用来安装DBMS_LOGMNR包,这个包用户来分析日志文件;@?/rdbms/admin/dbmslmd.sql脚本用来安装DBMS_LOGMNR_D包,这个包主要是创建LogMiner所必须的数据字典。

  1. sql> conn / as sysdba
  2. Connected.
  3. sql> @?/rdbms/admin/dbmslm.sql
  4.  
  5. Package created.
  6.  
  7.  
  8. Grant succeeded.
  9.  
  10.  
  11. Synonym created.
  12.  
  13. sql> @?/rdbms/admin/dbmslmd.sql
  14.  
  15. Package created.
  16.  
  17.  
  18. Synonym created.
  19.  
  20. sql> r
  21. 1 SELECT DISTINCT name
  22. 2 FROM DBA_SOURCE
  23. 3 WHERE type = 'PACKAGE'
  24. 4 AND upper(text) LIKE upper('%logmnr%')
  25. 5 order by name
  26.  
  27. NAME
  28. -------------------------
  29. DBMS_LOGMNR
  30. DBMS_LOGMNR_D
  31. DBMS_LOGMNR_INTERNAL
  32. DBMS_LOGMNR_LOGREP_DICT
  33. DBMS_LOGMNR_SESSION
  34. LOGMNR_DICT_CACHE
  35. LOGMNR_EM_SUPPORT
  36.  
  37. 7 rows selected.

一、同库基于Redo的LogMiner

1、创建测试表:

  1. sql> conn wwl/wwl
  2. Connected.
  3.  
  4. sql> create table test02 (id number(10),name varchar2(200));
  5. Table created.
2、对测试表进行 增加,更新的操作并提交
  1. sql> insert into test02 values(1,'woo');
  2. 1 row created.
  3.  
  4. sql> commit;
  5. Commit complete.
  6.  
  7. sql> update test02 set name='wwl' where name='woo';
  8. 1 row updated.
  9.  
  10. sql> commit;
  11. Commit complete.

3、查询当前的RedoLog File,定位刚才操作所在的RedoLog File:

  1. sql> select group#,archived,status from v$log;
  2.  
  3. GROUP# ARC STATUS
  4. ---------- --- ----------------
  5. 1 YES INACTIVE
  6. 2 YES INACTIVE
  7. 3 NO CURRENT

4、至此,环境已经构建完成。

5、添加状态为CURRENT的RedoLog File到LogMiner中

  1. sql> exec dbms_logmnr.add_logfile(logfilename=>'/DBSoft/oracle/oradata/woo/redo03.log',options=>dbms_logmnr.new);
  2. PL/sql procedure successfully completed.

6、启动LogMiner进行分析

  1. sql> execute dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
  2. PL/sql procedure successfully completed.

7、查看分析后的结果

  1. sql> set linesize 300
  2. sql> set pagesize 8096
  3. sql> col seg_name format a6
  4. sql> col seg_owner format a4
  5. sql> col sql_redo format a70
  6. sql> col sql_undo format a70
  7. sql> SELECT SEG_OWNER,SEG_NAME,sql_REDO,sql_UNDO
  8. 2 FROM v$LOGMNR_CONTENTS
  9. 3 WHERE SEG_NAME = 'TEST02' and seg_owner='WWL';
  10.  
  11. SEG_ SEG_NA sql_REDO sql_UNDO
  12. ---- ------ ---------------------------------------------------------------------- ----------------------------------------------------------------------
  13. WWL TEST02 create table test02 (id number(10),name varchar2(200));
  14. WWL TEST02 insert into "WWL"."TEST02"("ID","NAME") values ('1','woo'); delete from "WWL"."TEST02" where "ID" = '1' and "NAME" = 'woo' and ROW
  15. ID = 'AAAVXrAAEAAAACvAAA';
  16.  
  17. WWL TEST02 update "WWL"."TEST02" set "NAME" = 'wwl' where "NAME" = 'woo' and ROWI update "WWL"."TEST02" set "NAME" = 'woo' where "NAME" = 'wwl' and ROWI
  18. D = 'AAAVXrAAEAAAACvAAA'; D = 'AAAVXrAAEAAAACvAAA';

8、我们可以看到在这里已经清晰的显示了之前所做所有操作的详细SQL语句,包括创建test02表,插入一条ID 为 1 和 将ID=1 更新为 ID=2。完成了整个操作的重演。



二、同库基于ArchiveLog File的LogMiner

1、创建测试表:

  1. sql> conn wwl/wwl
  2. Connected.
  3.  
  4. sql> create table test03(id number(10),name varchar2(200));
  5.  
  6. Table created.
  7.  
  8. sql> insert into test03 values(1,'wwl');
  9.  
  10. 1 row created.
  11.  
  12. sql> insert into test03 values(2,'wwl');
  13.  
  14. 1 row created.
  15.  
  16. sql> insert into test03 values(3,'pru');
  17.  
  18. 1 row created.
  19.  
  20. sql> insert into test03 values(4,'pru');
  21.  
  22. 1 row created.
  23.  
  24.  
  25. 增删改操作:
  26. sql> insert into test03 values(4,'pru');
  27.  
  28. 1 row created.
  29.  
  30. sql> update test03 set name='woo' where id=2;
  31.  
  32. 1 row updated.
  33.  
  34. sql> delete from test03 where id=4;
  35.  
  36. 1 row deleted.
  37.  
  38. sql> commit;

2、检查刚才数据:

  1. sql> col name format a4
  2. sql> select * from test03;
  3.  
  4. ID NAME
  5. ---------- ----
  6. 1 wwl
  7. 2 woo
  8. 3 pru

3、查询当前的RedoLog File,定位刚才操作所在的RedoLog File:

  1. sql> select thread#,sequence#,bytes,status from v$log;
  2.  
  3. THREAD# SEQUENCE# BYTES ARC STATUS
  4. ---------- ---------- ---------- --- ----------------
  5. 1 46 52428800 NO CURRENT
  6. 1 44 52428800 YES INACTIVE
  7. 1 45 52428800 YES ACTIVE

4、查询归档日志

  1. sql> select SEQUENCE#,name,status from v$archived_log where name is not null and sequence#=45;
  2.  
  3. SEQUENCE# NAME S
  4. ---------- ------------------------------------------------------------------------------------- -
  5. 45 /DBSoft/oracle/fast_recovery_area/WOO/archivelog/2017_11_21/o1_mf_1_45_f17jvko7_.arc A

5、添加归档日志做离线分析:

  1. sql> execute dbms_logmnr.add_logfile(logfilename=>'/DBSoft/oracle/fast_recovery_area/WOO/archivelog/2017_11_21/o1_mf_1_45_f17jvko7_.arc',options=>dbms_logmnr.NEW);
  2.  
  3. PL/sql procedure successfully completed.

6、启动LogMiner分析进程

  1. sql> execute dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
  2.  
  3. PL/sql procedure successfully completed.

7查询分析结果:

  1. sql> col sql_REDO format a100
  2. sql> col sql_UNDO format a100
  3. sql> SELECT SEG_OWNER,sql_UNDO
  4. 2 FROM v$LOGMNR_CONTENTS
  5. 3 WHERE SEG_NAME = 'TEST03' and seg_owner='WWL';
  6.  
  7. SEG_ SEG_NA sql_REDO
  8. ---- ------ ----------------------------------------------------------------------------------------------------
  9. sql_UNDO
  10. ----------------------------------------------------------------------------------------------------
  11. WWL TEST03 create table test03(id number(10),name varchar2(200));
  12.  
  13.  
  14. WWL TEST03 insert into "WWL"."TEST03"("ID",'wwl');
  15. delete from "WWL"."TEST03" where "ID" = '1' and "NAME" = 'wwl' and ROWID = 'AAAVXsAAEAAAAC3AAA';
  16.  
  17. WWL TEST03 insert into "WWL"."TEST03"("ID","NAME") values ('2','wwl');
  18. delete from "WWL"."TEST03" where "ID" = '2' and "NAME" = 'wwl' and ROWID = 'AAAVXsAAEAAAAC3AAB';
  19.  
  20. WWL TEST03 insert into "WWL"."TEST03"("ID","NAME") values ('3','pru');
  21. delete from "WWL"."TEST03" where "ID" = '3' and "NAME" = 'pru' and ROWID = 'AAAVXsAAEAAAAC3AAC';
  22.  
  23. WWL TEST03 insert into "WWL"."TEST03"("ID","NAME") values ('4','pru');
  24. delete from "WWL"."TEST03" where "ID" = '4' and "NAME" = 'pru' and ROWID = 'AAAVXsAAEAAAAC3AAD';
  25.  
  26. WWL TEST03 update "WWL"."TEST03" set "NAME" = 'woo' where "NAME" = 'wwl' and ROWID = 'AAAVXsAAEAAAAC3AAB';
  27. update "WWL"."TEST03" set "NAME" = 'wwl' where "NAME" = 'woo' and ROWID = 'AAAVXsAAEAAAAC3AAB';
  28.  
  29. WWL TEST03 delete from "WWL"."TEST03" where "ID" = '4' and "NAME" = 'pru' and ROWID = 'AAAVXsAAEAAAAC3AAD';
  30. insert into "WWL"."TEST03"("ID",'pru');
  31.  
  32. 7 rows selected.

8、完了之后记得结束LogMiner:

  1. sql> execute dbms_logmnr.end_logmnr;
  2. PL/sql procedure successfully completed.

注意:

使用logminer查询表v$logmnr_contents必须在同一个会话中进行,因为分析的那些信息存储在这个session的PGA中,在别的session里面是查不到的,如果在别的session中视图查询这个视图得到如下错误
  1. sql>select * from V$LOGMNR_CONTENTS;
  2. select* from V$LOGMNR_CONTENTS
  3. ERRORat line 1:
  4. ORA-01306: dbms_logmnr.start_logmnr() must be invoked before selectingfrom
  5. v$logmnr_contents

视图v$logmnr_contents中的分析结果仅在我们运行过程'dbms_logmrn.start_logmnr'这个会话的生命期中存在。这是因为所有的LogMiner存储都在PGA内存中,所有其他的进程是看不到它的,同时随着进程的结束,分析结果也随之消失。最后,使用过程DBMS_LOGMNR.END_LOGMNR终止日志分析事务,此时PGA内存区域被清除,分析结果也随之不再存在。

可以创建临时表解决这个问题

  1. sql>create table logmnr_tb1 as select *from V$LOGMNR_CONTENTS;
  2. Table created.

猜你在找的Oracle相关文章