zoukankan      html  css  js  c++  java
  • 数据库进阶系列之三:使用Logminer解析Oracle日志

    有时候我们会被问到一个数据库对象的创建时间,这简单,可以查user_objects视图,不过如果再深入些,这个表的数据什么时候被什么人修改过?这个在没有工具帮助的情况下是不容易回答的,我们只知道这些记录存在于Redo日志中,但这些日志文件并不是人直接可读的,这个时候Logminer就能派上用场了。下面简单举例(实验环境:Windows Vista + Oracle 11.1.0.7.0):

    H:\>sqlplus / as sysdba
    SQL> alter database add supplemental log data;
    /*该命令用于启动supplemental logging功能,以使Logminer获得更加详细的信息。如果该功能未启用,Logminer解析结果中的username,session_info等信息都被置为‘UNKNOWN’,这样我们就无从得知操作是由哪个用户执行的了。另外,也可能导致某些操作无法解析出来,比如在测试中我发现如果该功能未启用,而我更新的表是一张未设置主键的表,那么在解析结果中我始终找不到对应的UPDATE操作。欲禁用此项功能:alter database drop supplemental log data;*/
    SQL> shutdown immediate
    SQL> startup
    SQL> alter system switch logfile;
    /*将日志切换到下一组以便在解析之后可以使用时间条件进行过滤,以免日志记录太多看花眼*/
    SQL> exit

    /*以下执行一些简单的操作,这些操作会被记录到切换过后的Redo日志中*/
    H:\>sqlplus morven3/morven3
    SQL> create table tab1(fid number,fval varchar(20));
    SQL> insert into tab1 values(1,'abc');
    SQL> /
    SQL> /
    SQL> /
    SQL> commit;
    SQL> update tab1 set fval='xyz' where fid=1;
    SQL> commit;
    SQL> delete from tab1;
    SQL> commit;
    SQL> exit

    H:\>sqlplus / as sysdba
    SQL> select * from v$log where status='CURRENT';
    /*查找当前使用的日志的组号*/
    SQL> SELECT MEMBER from v$logfile where group#=3;
    /*根据查到的当前日志组号,查找日志文件,得到日志文件路径,如“C:\DATABASE\ORADATA\SIDORCL\REDO03.LOG”*/
    SQL> exec dbms_logmnr.add_logfile('C:\DATABASE\ORADATA\SIDORCL\REDO03.LOG',dbms_logmnr.new);
    /*向Logminer指定要解析的日志文件*/
    SQL> exec dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
    /*向Logminer指定使用当前数据库的数据字典进行解析(只有根据数据字典才能将对象ID解析成对象名称,增加可读性)*/
    SQL> select t.* from v$logmnr_contents t where timestamp >sysdate-10/24/60 and username='MORVEN3';
    /*通过上面几个步骤,动态视图v$logmnr_contents就有了解析出来的日志记录。这里你可以简地通过时间过滤一下,比如像上面的查找10分钟内的操作,当然10分钟内可能还是有不少日志记录,你可以加其它的过滤条件,比如用户名。根据上面的语句,我们查到13条记录,可以看“SQL_REDO”字段,这些记录分别是:
    create table tab1(fid number,fval varchar(20));
    insert into "MORVEN3"."TAB1"("FID","FVAL") values ('1','abc');
    insert into "MORVEN3"."TAB1"("FID","FVAL") values ('1','abc');
    insert into "MORVEN3"."TAB1"("FID","FVAL") values ('1','abc');
    insert into "MORVEN3"."TAB1"("FID","FVAL") values ('1','abc');
    update "MORVEN3"."TAB1" set "FVAL" = 'xyz' where "FVAL" = 'abc' and ROWID = 'AAARJ1AAFAAAACFAAA';
    update "MORVEN3"."TAB1" set "FVAL" = 'xyz' where "FVAL" = 'abc' and ROWID = 'AAARJ1AAFAAAACFAAB';
    update "MORVEN3"."TAB1" set "FVAL" = 'xyz' where "FVAL" = 'abc' and ROWID = 'AAARJ1AAFAAAACFAAC';
    update "MORVEN3"."TAB1" set "FVAL" = 'xyz' where "FVAL" = 'abc' and ROWID = 'AAARJ1AAFAAAACFAAD';
    delete from "MORVEN3"."TAB1" where "FID" = '1' and "FVAL" = 'xyz' and ROWID = 'AAARJ1AAFAAAACFAAA';
    delete from "MORVEN3"."TAB1" where "FID" = '1' and "FVAL" = 'xyz' and ROWID = 'AAARJ1AAFAAAACFAAB';
    delete from "MORVEN3"."TAB1" where "FID" = '1' and "FVAL" = 'xyz' and ROWID = 'AAARJ1AAFAAAACFAAC';
    delete from "MORVEN3"."TAB1" where "FID" = '1' and "FVAL" = 'xyz' and ROWID = 'AAARJ1AAFAAAACFAAD';
    另外,通过“SESSION_INFO”字段,我们还能定位出具体是哪个用户在哪台机器上执行的操作,我们可以看一个“SESSION_INFO”的例子:
    login_username=MORVEN3 client_info= OS_username=domain1\hmy Machine_name=domain1\EV001EEC1FF000 OS_terminal=EV001EEC1FF000 OS_process_id=4064:2560 OS_program_name=sqlplus.exe
    v$logmnr_contents视图中还有其它一系列的字段,SEG_TYPE_NAME,TABLE_SPACE,SQL_UNDO等等*/
    SQL> exec dbms_logmnr.end_logmnr
    /*退出Logminer*/

  • 相关阅读:
    NHibernate 入门必看——NHibernate Made Simple
    ASP.NET 的多线程
    asp.net 禁止用户二次登录(转)
    marquee标记用法及在asp.net中的应用(转)
    解决Visual Studio 2005显示中文乱码(zhuan)
    ms sql 触发器( 转)
    Asp.net 页面导航的几种方法与比较
    ASP.NET1.1(VB):DataGrid中"加入序号列"和"截取定长字符串追加'...
    解决“Internet Explorer 无法打开 Internet站点已终止操作”问题(转)
    ASP.NET 2.0的页面指令集(转)
  • 原文地址:https://www.cnblogs.com/morvenhuang/p/1721327.html
Copyright © 2011-2022 走看看