安装LogMiner(默认是安装的):
SQL>@$ORACLE_HOME/rdbms/admin/dbmslm.sql
SQL>@$ORACLE_HOME/rdbms/admin/dbmslmd.sql
这两个脚本必须均以SYS用户身份运行。其中第一个脚本用来创建DBMS_LOGMNR包,该包用来分析日志文件。第二个脚本用来创建DBMS_LOGMNR_D包,该包用来创建数据字典文件。
执行日志挖掘的赋权语句:
SQL> GRANT EXECUTE ON DBMS_LOGMNR TO test;
DBMS_LOGMNR_D:
BUILD(),用于提取数据字典信息;
SET_TABLESPACE(),用于设置LogMiner表的表空间,默认是建在SYSTEM表空间下的。
DBMS_LOGMNR:
ADD_LOGFILE(NAME VARCHAR2,OPTIONS NUMBER) ,用来添加或删除用于分析的日志文件;
START_LOGMNR(START_SCN NUMBER,END_SCN NUMBER,START_TIME NUMBER,END_TIME NUMBER,
DICTFILENAME VARCHAR2,OPTIONS NUMBER) 用来开启日志分析,同时确定分析的时间或SCN窗口以及确认是否使用提取出来的数据字典信息;
END_LOGMNR(),用于终止分析会话,它将回收LogMiner所占用的内存。
与LogMiner相关的数据字典视图:
V$LOGHIST:显示历史日志文件的一些信息
V$LOGMNR_DICTIONARY:因为LOGMINER可以有多个字典文件,所以该视图显示字典文件信息
V$LOGMNR_PARAMETERS:显示LOGMINER的参数
V$LOGMNR_LOGS:显示用于分析的日志列表信息
V$LOGMNR_CONTENTS:LOGMINER结果
三种获取字典文件的方法:
1)将字典文件提取为一个Flat File:
设置参数UTL_FILE_DIR
alter system set utl_file_dir='/home/oracle/logmgr' scope=spfile;
begin
dbms_logmnr_d.build(dictionary_filename => 'dictionary.ora',
dictionary_location => '/home/oracle/logmgr');
end;
2)将字典文件提取为Redo Log:
为了将字典文件提取为Redo日志,数据库必须处于OPEN状态,并且处于归档模式。将字典提取为Redo日志的过程中,数据库系统不能有DDL语句被执行。为了将字典提取为Redo日志,需要使用带有STORE_IN_REDO_FILES参数的DBMS_LOGMNR_D.BUILD程序:
begin
DBMS_LOGMNR_D.BUILD(OPTIONS => DBMS_LOGMNR_D.STORE_IN_REDO_LOGS);
end;
需要注意的是,将字典文件提取为Redo文件的时候需要开启附加日志:
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
在这些Redo日志被归档之后,可以通过查询V$ARCHIVED_LOG视图来查询:
SELECT *
FROM V$ARCHIVED_LOG A WHERE A.NAME IS NOT NULL
AND (A.DICTIONARY_BEGIN = 'YES' ORA.DICTIONARY_END = 'YES');
如果将字典信息提取为Redo文件,那么在使用DBMD_LOGMNR.ADD_LOGFILE指定所需要分析的日志文件时,需要将这些包含字典信息的Redo文件也添加进去。同时在使用START_LOGMNR开始分析时,需要指定DICT_FROM_REDO_LOGS的参数
3)使用Online Catalog
为了使LogMiner直接使用数据库当前使用的字典,在开始LogMiner时可以指定将联机目录作为字典源:
begin
DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);
end;
使用联机目录,意味着不需要再提取字典文件,是开始分析日志的最快的方式。除了可以分析联机Redo日志外,还可以在和产生归档日志文件相同的系统上分析归档日志文件。然而,记住联机目录只能重建应用于表的最新版本上的SQL语句。一旦表被修改,联机目录就无法反映出表之前的版本。这就意味着LogMiner不能重建执行于表的旧版本上的SQL语句。
开始LogMiner:
添加文件:
BEGIN
dbms_logmnr.add_logfile(logfilename => '/u01/app/arch/1_9_995538989.dbf',
options => dbms_logmnr.NEW);
END;
BEGIN
dbms_logmnr.add_logfile(logfilename => '/u01/app/oradata/orcl/redo01.log',
options => dbms_logmnr.NEW);
END;
开启LogMinor:
begin
dbms_logmnr.start_logmnr(dictfilename=>'/home/oracle/logmgr/dictionary.ora');
end;
关闭LogMinor:
begin
dbms_logmnr.end_logmnr;
end;
我的实验:
create table c_test_5
(
userid number(8) primary key,
USERNAME varchar2(16),
comments varchar2(20));
declare
cur number(8);
begin
cur := 1;
for cur in 1 .. 1000 loop
insert into c_test_5 values (cur, dbms_random.string('x', 4), '');
end loop;
commit;
end;
SELECT * FROM v$logmnr_contents a where a.SEG_OWNER='TEST';