oracle logmnr 分析归档日志介绍

 dba有时候需要被数据丢失的锅,去找回或者找到数据是否“丢失”的原因,这个时候如果归档还在,我们就可以用oracle自带的logmnr来分析归档日志了。


一.安装LogMiner

$ sqlplus /nolog

SQL*Plus: Release 10.2.0.3.0 - Production on Tue Apr 15 12:30:58 2008

Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.

SQL> conn / as sysdba;
Connected to an idle instance.
SQL> startup
ORACLE instance started.

Total System Global Area 1392508928 bytes
Fixed Size                  2072808 bytes
Variable Size             738201368 bytes
Database Buffers          637534208 bytes
Redo Buffers               14700544 bytes
Database mounted.
Database opened.

SQL>@?/rdbms/admin/dbmslm.sql

Package created.

Grant succeeded.

--dbmslm.sql是用来创建DBMS_LOGMNR的package,这个包是用来分析日志的.

SQL>@?/rdbms/admin/dbmslmd.sql

Package created.

--dbmslmd.sql是用来创建DBMS_LOGMNR_D的package的,这个包是用来创建数据字典文件的.

注意以上两个包都是需要在sysdba权限的user下创建.

二.使用LogMiner

安装LogMiner确实很简单,现在来看看如何使用我们安装好的东东

1.首先需要创建数据字典文件(data-dictionary):

为什么要创建数据字典文件呢?
引用一位网友的话就是:让LogMiner引用涉及到内部数据字典中的部分时为他们实际的名字,而不是系统内部的16进制。数据字典文件是一个文本文件,使用包 DBMS_LOGMNR_D来创建。如果我们要分析的数据库中的表有变化,影响到库的数据字典也发生变化,这时就需要重新创建该字典文件。另外一种情况是在分析另外一个数据库文件的重作日志时,也必须要重新生成一遍被分析数据库的数据字典文件。 在使用LogMiner工具分析redo log文件之前,可以使用DBMS_LOGMNR_D 包将数据字典导出为一个文本文件。该字典文件是可选的,但是如果没有它,LogMiner解释出来的语句中关于数据字典中的部分(如表名、列名等)和数值都将是16进制的形式,我们是无法直接理解的。

在pfile或者spfile中,我们通过设定UTL_FILE_DIR参数来指定数据字典文件的位置目录

对于UTL_FILE_DIR参数在10g的文档中有这样的解释:
----------------------------------------------
UTL_FILE_DIR lets you specify one or more directories that Oracle should use for PL/SQL file I/O. If you are specifying multiple directories, you must repeat the UTL_FILE_DIR parameter for each directory on separate lines of the initialization parameter file.
All users can read or write to all files specified by this parameter. Therefore all PL/SQL users must be trusted with the information in the directories specified by this parameter.
Note:
If you list multiple values, all entries of this parameter must be on contiguous lines of the parameter file. If you separate them with other parameters, Oracle will read only the last (contiguous) lines.

开始设置UTL_FILE_DIR参数并创建数据字典文件:
SQL> show parameter spfile;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
spfile                               string      /opt/oracle/product/10g/dbs/sp
                                                 fileirmdb.ora

SQL> alter system set UTL_FILE_DIR='/opt/oracle/product/10g/logmnr' scope=spfile;

System altered.

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area 1392508928 bytes
Fixed Size                  2072808 bytes
Variable Size             738201368 bytes
Database Buffers          637534208 bytes
Redo Buffers               14700544 bytes
Database mounted.
Database opened.

SQL> show parameter UTL_FILE_DIR

NAME                                 TYPE        VALUE
------------------------------------ ----------- ----------------------------
utl_file_dir                         string      /opt/oracle/product/10g/logmnr

现在开始创建数据字典:
SQL> show user;
USER is "SYS"

SQL>exec dbms_logmnr_d.build(dictionary_filename=>'alan_dict.ora',dictionary_location=>'/opt/oracle/product/10g/logmnr');

PL/SQL procedure successfully completed.

SQL> !
$ cd $ORACLE_HOME/logmnr
$ ls
alan_dict.ora

2.其次需要创建分析的日志文件列表:
首先看一下dbms_logmnr包的内容:
SQL> desc dbms_logmnr;
PROCEDURE ADD_LOGFILE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 LOGFILENAME                    VARCHAR2                IN
 OPTIONS                        BINARY_INTEGER          IN     DEFAULT
FUNCTION COLUMN_PRESENT RETURNS BINARY_INTEGER
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SQL_REDO_UNDO                  NUMBER                  IN     DEFAULT
 COLUMN_NAME                    VARCHAR2                IN     DEFAULT
PROCEDURE END_LOGMNR
FUNCTION MINE_VALUE RETURNS VARCHAR2
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SQL_REDO_UNDO                  NUMBER                  IN     DEFAULT
 COLUMN_NAME                    VARCHAR2                IN     DEFAULT
PROCEDURE REMOVE_LOGFILE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 LOGFILENAME                    VARCHAR2                IN
PROCEDURE START_LOGMNR
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 STARTSCN                       NUMBER                  IN     DEFAULT
 ENDSCN                         NUMBER                  IN     DEFAULT
 STARTTIME                      DATE                    IN     DEFAULT
 ENDTIME                        DATE                    IN     DEFAULT
 DICTFILENAME                   VARCHAR2                IN     DEFAULT
 OPTIONS                        BINARY_INTEGER          IN     DEFAULT

SQL> select group#,status from v$log;

    GROUP# STATUS
---------- ----------------
         1 CURRENT
         2 INACTIVE
         3 INACTIVE

SQL> select member from v$logfile;

MEMBER
--------------------------------------------------------------------------------
/opt/oracle/oradata/irmdb/redo03.log
/opt/oracle/oradata/irmdb/redo02.log
/opt/oracle/oradata/irmdb/redo01.log

创建分析列表:
SQL>exec dbms_logmnr.add_logfile(LogFileName=>'/opt/oracle/oradata/irmdb/redo01.log',Options=>dbms_logmnr.new);

PL/SQL procedure successfully completed.

SQL>exec dbms_logmnr.add_logfile(LogFileName=>'/opt/oracle/oradata/irmdb/redo02.log',Options=>dbms_logmnr.ADDFILE);

PL/SQL procedure successfully completed.

SQL>exec dbms_logmnr.add_logfile(LogFileName=>'/opt/oracle/oradata/irmdb/redo03.log',Options=>dbms_logmnr.ADDFILE);

PL/SQL procedure successfully completed.
这样不仅仅创建了日志分析列表,同时还添加了两个日志成员文件。

通过观察v$logmnr_logs动态性能视图我们可以看到分析列表中目前的日志成员:
SQL>select filename from v$logmnr_logs;

FILENAME
--------------------------------------------------------------------------------
/opt/oracle/oradata/irmdb/redo02.log
/opt/oracle/oradata/irmdb/redo03.log
/opt/oracle/oradata/irmdb/redo01.log

SQL> exec dbms_logmnr.remove_logfile('/opt/oracle/oradata/irmdb/redo02.log');

PL/SQL procedure successfully completed.

SQL> select filename from v$logmnr_logs;

FILENAME
--------------------------------------------------------------------------------
/opt/oracle/oradata/irmdb/redo03.log
/opt/oracle/oradata/irmdb/redo01.log

SQL> exec dbms_logmnr.add_logfile(LogFileName=>'/opt/oracle/oradata/irmdb/redo02.log',Options=>dbms_logmnr.ADDFILE);

PL/SQL procedure successfully completed.

3.利用LogMnr进行日志挖掘和分析:
挖掘和分析分为两种情况,一种是利用数据字典文件对所有分析列表中的日志内容进行分析,另外一种是利用数据字典文件并带有某种的限制条件对日志内容进行分析,比如从某个时间点到某个时间点日志内容的分析:

这里列出一下dbms_logmnr.start_logmnr的结构:
PROCEDURE START_LOGMNR
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 STARTSCN                       NUMBER                  IN     DEFAULT
 ENDSCN                         NUMBER                  IN     DEFAULT
 STARTTIME                      DATE                    IN     DEFAULT
 ENDTIME                        DATE                    IN     DEFAULT
 DICTFILENAME                   VARCHAR2                IN     DEFAULT
 OPTIONS                        BINARY_INTEGER          IN     DEFAULT

对第一种情况进行分析:
-----------------------------------------
SQL>exec dbms_logmnr.start_logmnr(DictFileName=>'/opt/oracle/product/10g/logmnr/alan_dict.ora');

PL/SQL procedure successfully completed.
分析完毕后所有分析的内容都保存到了GV$LOGMNR_CONTENTS动态性能视图里面,我们可以通过如下SQL来查询我们感兴趣的内容。

select scn,timestamp,log_id,seg_owner,seg_type,
table_space,data_blk#,data_obj#,data_objd#,
session#,serial#,username,session_info,
sql_redo,sql_undo from GV$LOGMNR_CONTENTS t
where t.sql_redo like 'create%';

最后我们可以释放内存:
SQL> exec dbms_logmnr.end_logmnr;

PL/SQL procedure successfully completed.

对第二种情况进行分析:
----------------------------------------
同时我们可以利用scn或time做为分析的限制条件,比如我们要分析日志列表中时间从08.04.13从10:00到15:00的内容。
SQL>exec dbms_logmnr.start_logmnr
(startTime => to_date('20080413100000','yyyy-mm-dd hh24:mi:ss'),
endTime => to_date('20080413150000','yyyy-mm-dd hh24:mi:ss'),
DictFileName=>'/opt/oracle/product/10g/logmnr/alan_dict.ora');

PL/SQL procedure successfully completed

之后的操作就是查询v$logmnr_contents或者gv$logmnr_contents视图并进一步的分析

同时不要忘记最后释放内存:
SQL>exec dbms_logmnr.end_logmnr;


 

上一篇:mysql笔记1: 了解mysql


下一篇:dbms_lob 方法总结