首页 > 代码库 > oracle logminer全解析

oracle logminer全解析

今天写篇原创的,把在工作中遇到的logminer问题总结下

(1)简介:

logminer 工具即可以用来分析在线,也可以用来分析离线日志文件,即可以分析本身自己数据库的重作日志文件,也可以用来分析其他数据库的重作日志文件。 
总的说来,logminer工具的主要用途有: 
  1. 跟踪数据库的变化:可以离线的跟踪数据库的变化,而不会影响在线系统的性能。 
  2. 回退数据库的变化:回退特定的变化数据,减少point-in-time recovery的执行。 
  3. 优化和扩容计划:可通过分析日志文件中的数据以分析数据增长模式。 

说到这里,不得不提一下oracle日志的问题,oracle日志分为在线redo日志和离线归档日志两种,在线redo日志是必须的,离线归档日志可以设置是否归档,从而离线归档日志可以不存在,但如果没有离线归档日志,那么是没有什么实际价值的,如果数据库崩溃,就不能进行回滚和回复了

(1)可以通过select * from v$log查看在线redo日志。

 
其中archived字段显现的是否开启归档,如上所示,未开启归档模式,实际就没有实际价值,可以启动归档日志,可以看另一篇博客,在此不再说明
在线redo日志,有current,active和inactive字段,在线redo日志的切换原理是,正在修改的日志会标记为current,例如redo1,redo2,redo3,当redo1是current时,会一直写redo1日志,当该日志写满后会修改redo2日志为current,redo1日志标记变为active,此时会对redo1进行归档,当归档完成后,变为inactive标记,current会循环着变化,当在变到redo1时就会覆盖掉以前的内容。因此说开启归档日志非常重要。
(2) 用select * from v$logfile;确定在线redo日志位置
注意:这里提示一点,在linux和windows系统的oracle中,在线redo日志为。。。。。.log,以.log后缀结尾,而在AIX中是没有后缀的,在后面我会说这回有问题。
(3)使用select * from v$archived_log;查看离线归档日志位置。
 归档日志在linux下是以.dbf后缀结尾
(4)开始介绍使用logminer工具(整个logminer都必须是sysdba运行)
 要安装logminer工具,必须首先要运行下面这样两个脚本, 
   l  $ORACLE_HOME/rdbms/admin/dbmslm.sql
   2 $ORACLE_HOME/rdbms/admin/dbmslmd.sql
        3 $ORACLE_HOME/rdbms/admin/dbmslms.sql
  这两个脚本必须均以SYS用户身份运行。其中第一个脚本用来创建DBMS_LOGMNR包,该包用来分析日志文件。第二个脚本用来创建DBMS_LOGMNR_D包,该包用来创建数据字典文件。 (即必须以sysdba运行)
 
设置生成数据字典位置:alter system set UTL_FILE_DIR=‘/oracle‘ scope=spfile;设置完成后必须重启数据库:shutdown immediate;        //如果不好用就shutdown abort; 或者shutdown force;强行关闭
startup;开启数据库
 
生成数据字典:execute dbms_logmnr_d.build(‘dict.ora‘,‘/oracle‘);运行后将在/oracle 下生成数据字典
 
添加日志文件:(这里添加的是AIX下的在线redo日志)
execute dbms_logmnr.add_logfile(LogFileName=>‘/dev/rredo1_1‘,Options=>dbms_logmnr.new);
execute dbms_logmnr.add_logfile(LogFileName=>‘/dev/rredo1_2‘,Options=>dbms_logmnr.addfile);
execute dbms_logmnr.start_logmnr(DictFileName=>‘/oracle/dict.ora‘);               //开启logminer工具
随后可以在v$logmnr_contents查看内容了,查看完成后使用:
execute dbms_logmnr.end_logmnr;   //关闭logminer日志
 
这里介绍下logminer原理,logminer的原理是以数据字典为基础加载redo日志文件,当运行dbms_logmnr.start_logmnr()后,会开启,但不会扫描分析日志,logminer是在单进程PGA中运行,也就是只有在运行logminer工具的窗口中v$logmnr_contents视图存在,新开启SQLwindows查询该表时不存在的,v$logminer生存期直到调用了end,会清空PGA。同时v$logmnr_contents采用的是动态扫描的方法,只有当有select 。。。。from v$log_contents动作时,logminer工具会开始从头加载添加的日志文件,直到所有日志文件添加完成,或者是达到指定的日期(这个在后面说),所以v$logmnr_contents是动态生成的,因为这个原理,如果想以create table my_logmnr_contents as select * from v$logmnr_contents,可能就会出现死循环问题,注意这里是分析的在线redo日志,create table my_logmnr_contents也会写到日志中,而v$logmnr_contents是动态的,也就是create table my_logmnr_contents的日志也会出现在v$logmnr_contents里,这就会造成死循环。注意,不是所有情况都会造成死循环。举例说明:
redo1                          current
redo2                          inactive
redo3                          inactive
redo4                          inactive
如果把四个日志都加载进去,就一定会造成死循环,会导致current非常快速的切换日志,这是非常严重的后果,redo日志切换频繁会出的问题可以自行查看,最终将导致create table my_logmnr_contents表的失败,
但是如果加载单独的日志,比如redo1日志,因为此时是current,logminer建自己的表后,current会切换,如果切换一圈又回到自身而create table还没建完,就会出错,而如果没有在切回来,就不会错,在举个例子,如果加载的是redo2日志,此时为inactive,忘了说了将v$logmnr_contents复制成静态表会大量增加日志,因此就会造成日志切换过快,加载redo2日志,current会很快切换redo2日志,这样logminer也会出错,总结就是如果一个日志在用logminer分析时,如果该日志标记改变,用create table就会不成功,这里有个例外就是如果不开启归档模式,不管如何切换,复制自己的logminer表都可以成功。(这些都是经验总结啊,说多了都是泪)
 
总之,用logminer解析日志,如果想存成自己的静态表,会导致日志增加非常迅速,这点一定要注意。所以,一个方法就是只查询,不产生自己的静态表,二就是尽量加上日期等进行限制。加日期的方法如下:
    (1)无限制条件 
SQL> EXECUTE dbms_logmnr.start_logmnr( DictFileName=>‘ /oracle/dict.ora ‘); 

  (2)有限制条件 
  通过对过程DBMS_ LOGMNR.START_LOGMNR中几个不同参数的设置(参数含义见表1),可以缩小要分析日志文件的范围。通过设置起始时间和终止时间参数我们可以限制只分析某一时间范围的日志。如下面的例子,我们仅仅分析2004年9月18日的日志,: 
SQL> EXECUTE dbms_logmnr.start_logmnr( 
DictFileName => ‘ /oracle/dict.ora‘, 
StartTime => to_date(‘2004-9-18 00:00:00‘,‘YYYY-MM-DD HH24:MI:SS‘) 
EndTime => to_date(‘‘2004-9-18 23:59:59‘,‘YYYY-MM-DD HH24:MI:SS ‘)); 

  也可以通过设置起始SCN和截至SCN来限制要分析日志的范围: 
SQL> EXECUTE dbms_logmnr.start_logmnr( DictFileName => ‘/oracle/dict.ora‘, 
StartScn => 20, EndScn => 50); 

  表1 DBMS_LOGMNR.START__LOGMNR过程参数含义 
参数
参数类型
默认值
含义
StartScn
数字型(Number) 
0
分析重作日志中SCN≥StartScn日志文件部分
EndScn 
数字型(Number) 
0
分析重作日志中SCN≤EndScn日志文件部分
StartTime 

日期型(Date)
1998-01-01
分析重作日志中时间戳≥StartTime的日志文件部分
EndTime 
日期型(Date)
2988-01-01
分析重作日志中时间戳≤EndTime的日志文件部分
DictFileName 
字符型(VARCHAR2)
0
字典文件,该文件包含一个数据库目录的快照。使用该文件可以使得到的分析结果是可以理解的文本形式,

4、观察分析结果(v$logmnr_contents)
一共有四个表,详细说明如下
V$LOGMNR_DICTIONARY-------查询使用的数据字典文件 
V$LOGMNR_PARAMETERS-------查询当前LogMiner设定的参数 
V$LOGMNR_LOGS-------查询分析的日志文件 
V$LOGMNR_CONTENTS-------日志文件的内容 
 
用logminer解析离线归档日志就没有那么多事了,方法同上,而且也可以建自己的表保存v$logmnr_contents,但日志同样会暴增,而且归档日志一般是按照一定的规则生成,不像在线redo日志,就那么几个是固定的。
 
这里在说一下工作中遇到的问题,因为日志暴增的问题,想到的就是将服务器的字典文件,在线redo日志通过ssh或者ftp等方式,发送到远程的另一个机器中进行分析,同时在远程的服务器上生成自己的v$logmnr_contents日志,这样就可以避免生产库日志暴增的问题,但是也遇到了其他问题:
首先:原计划想分析在线日志文件,当一个日志由current变成非current时,说明该日志以满,通过scp发送到远程,但是AIX上的在线redo日志不知道什么原因,不能发送到windows服务器上,字典文件可以发送成功,但是日志怎么都不行,但是在centos上的oracle的在线redo日志就可以发送到windows服务器上,可能是由于没有后缀,不能识别该文件,用ftp也不可以。但是可以将归档日志成功发送到windows服务器端。
其次:发送文件将涉及到断网的情况,如何能够在判断归档日志发送到哪个,是否有新增归档日志,断网后连网如何保证同步传输,不会丢失的问题。这些还没有成功解答,成功后会有后续介绍。
 
这里写下远程分析logminer注意事项:
 我们可以利用logminer日志分析工具来分析其他数据库实例产生的重作日志文件,而不仅仅用来分析本身安装logminer的数据库实例的redo logs文件。使用logminer分析其他数据库实例时,有几点需要注意: 

  1. logminer必须使用被分析数据库实例产生的字典文件,而不是安装logminer的数据库产生的字典文件,另外必须保证安装logminer数据库的字符集和被分析数据库的字符集相同。 

  2. 被分析数据库平台必须和当前logminer所在数据库平台一样,也就是说如果我们要分析的文件是由运行在UNIX平台上的Oracle 9i产生的,那么也必须在一个运行在UNIX平台上的Oracle实例上运行logminer,而不能在其他如Microsoft NT上运行logminer。当然两者的硬件条件不一定要求完全一样。 

  3. logminer日志分析工具仅能够分析Oracle 8以后的产品,对于8以前的产品,该工具也无能为力