解析Oracle 10g中的Logmnr使用一例
很多时候我们在Oracle中执行操作时,需要对Oracle执行的DDL语句或者DML语句的操作过程做出一些分析;或者当某一个用户误删除了一张表或者误删除了一些数据时,DBA需要在事后找回误操作的数据,这时,可以通过对操作日志的分析,从而找到数据库中发生的一些变化。分析日志的工具就是Oracle所提供的Logmnr工具。
在Oracle9i中,Logmnr工具是DBA用来找回被删除数据的好办法,利用Logmnr可以完成以下的任务:
1、 查明数据库的变更记录,或者是进行变化分析,如有的用户怀疑自己的应用有什么问题,产生了大量的失误,可以用Logmnr来分析这些事务,看看到底发生了些什么事情。
2、 查明并更正用户的误操作,如有的用户一不小心误删除了某个表,但是并不承认,这个时候就可以利用Logmnr来分析是谁执行的DML或者是DDL操作。
3、 找回丢失的数据,当不能使用flashback或者使用flashback受到限制的时候,可以考虑使用Logmnr工具来找回数据,这个时候,只需要有归档日志即可。
Logmnr工具包含的内容与数据字典
dbms_logmnr_d包:用于提取字典信息到外部文件或者是联机日志中去。
dbms_logmnr包:包含三个过程:
(1) add_logfile:用来添加/删除用于分析的日志文件。
(2) start_logmnr:用来开启日志分析,而且在9i/10g中,可以开启很多不同的分析选项。
(3) end_logmnr:用来终止分析会话,它将回收LogMiner所占用的内存。
如果普通用户想使用以上的包,必须现在sys中授权才可以使用,如:
sys用户执行授权: SQL> grant execute on dbms_logmnr to scott;
|
与LogMiner相关的数据字典如下:
u v$logmnr_dictionary:LogMiner可能使用的数据字典信息
u v$logmnr_parameters:当前LogMiner所设定的参数信息
u v$logmnr_logs:当前用于分析的日志列表
u v$logmnr_contents:日志分析结果
Logmnr分析过程演示
创建一张表,然后插入一些数据,再删除这些数据。
连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options
SQL> alter system archive log current;
系统已更改。
SQL> create table mytesttab as select * from scott.dept;
表已创建。
SQL> insert into mytesttab values(80,'IT','WA');
已创建 1 行。
SQL> insert into mytesttab values(90,'MGR','YR');
已创建 1 行。
SQL> commit;
提交完成。
SQL> delete from mytesttab;
已删除6行。
SQL> commit;
提交完成。
SQL> alter system archive log current;
系统已更改。 |
然后找出操作过程记录的日志文件
D:/oracle/flash_recovery_area/MYORACLE/ARCHIVELOG/2007_08_11目录下的
O1_MF_1_4_3CVHLKJM_.ARC
文件,我们需要对这个文件进行分析处理。
SQL> exec sys.dbms_logmnr.add_logfile(LogFileName=>'D:/oracle/flash_recovery_area/MYORACLE/ARCHIVELO G/2007_08_11/O1_MF_1_4_3CVHLKJM_.ARC',options=>dbms_logmnr.new);
PL/SQL 过程已成功完成。
SQL> exec sys.dbms_logmnr.start_logmnr(options=>sys.dbms_logmnr.dict_from_online_catalog);
PL/SQL 过程已成功完成。 |
OK,分析完成。
查看日志记录的内容
SQL> select t.scn,t.timestamp,t.seg_owner,t.operation 2 from v$logmnr_contents t where t.seg_name='MYTESTTAB';
SCN TIMESTAMP SEG_OWNE OPERATION ---------- -------------- -------- ---------- 5483840 11-8月 -07 SYS DDL 5483863 11-8月 -07 SYS INSERT 5483874 11-8月 -07 SYS INSERT 5483885 11-8月 -07 SYS DELETE 5483885 11-8月 -07 SYS DELETE 5483885 11-8月 -07 SYS DELETE 5483885 11-8月 -07 SYS DELETE 5483886 11-8月 -07 SYS DELETE 5483886 11-8月 -07 SYS DELETE
已选择9行。
SQL> select t.SQL_REDO from v$logmnr_contents t where t.seg_name='MYTESTTAB';
SQL_REDO ---------------------------------------------------------------------------------------------------- create table mytesttab as select * from scott.dept; insert into "SYS"."MYTESTTAB"("DEPTNO","DNAME","LOC") values ('80','IT','WA'); insert into "SYS"."MYTESTTAB"("DEPTNO","DNAME","LOC") values ('90','MGR','YR'); delete from "SYS"."MYTESTTAB" where "DEPTNO" = '10' and "DNAME" = 'ACCOUNTING' and "LOC" = 'NEW YORK delete from "SYS"."MYTESTTAB" where "DEPTNO" = '20' and "DNAME" = 'RESEARCH' and "LOC" = 'DALLAS' an delete from "SYS"."MYTESTTAB" where "DEPTNO" = '30' and "DNAME" = 'SALES' and "LOC" = 'CHICAGO' and delete from "SYS"."MYTESTTAB" where "DEPTNO" = '40' and "DNAME" = 'OPERATIONS' and "LOC" = 'BOSTON' delete from "SYS"."MYTESTTAB" where "DEPTNO" = '80' and "DNAME" = 'IT' and "LOC" = 'WA' and ROWID = delete from "SYS"."MYTESTTAB" where "DEPTNO" = '90' and "DNAME" = 'MGR' and "LOC" = 'YR' and ROWID =
已选择9行。
SQL> select t.SQL_UNDO from v$logmnr_contents t where t.seg_name='MYTESTTAB';
SQL_UNDO ----------------------------------------------------------------------------------------------------
delete from "SYS"."MYTESTTAB" where "DEPTNO" = '80' and "DNAME" = 'IT' and "LOC" = 'WA' and ROWID = delete from "SYS"."MYTESTTAB" where "DEPTNO" = '90' and "DNAME" = 'MGR' and "LOC" = 'YR' and ROWID = insert into "SYS"."MYTESTTAB"("DEPTNO","DNAME","LOC") values ('10','ACCOUNTING','NEW YORK'); insert into "SYS"."MYTESTTAB"("DEPTNO","DNAME","LOC") values ('20','RESEARCH','DALLAS'); insert into "SYS"."MYTESTTAB"("DEPTNO","DNAME","LOC") values ('30','SALES','CHICAGO'); insert into "SYS"."MYTESTTAB"("DEPTNO","DNAME","LOC") values ('40','OPERATIONS','BOSTON'); insert into "SYS"."MYTESTTAB"("DEPTNO","DNAME","LOC") values ('80','IT','WA'); insert into "SYS"."MYTESTTAB"("DEPTNO","DNAME","LOC") values ('90','MGR','YR');
已选择9行。 |
通过查看v$logmnr_contents视图中的一些列可以看到日志的记录详细信息。
注意其中:SQL_UNDO和SQL_REDO列记录的信息。这就是我们需要找回的内容!
可以将结果转存在一张用户表中
SQL> create table my_logmnr_contents 2 as 3 select * from v$logmnr_contents;
表已创建。 |
清空session内存信息
SQL> exec sys.dbms_logmnr.end_logmnr;
PL/SQL 过程已成功完成。 |