--日志挖掘器(LogMiner)
日志挖掘器的3个主要组成部分:v$logmnr_contents视图、pl/sql 的 的dbms_logmnr 、dbms_logmnr_d
v$logmnr_contents视图是 LogMiner 挖掘日志的接口,每当该视图被访问时,重做日志就会被读取,即挖掘日志实际上就是对
该视图的查询操作,前提是必须启动日志挖掘会话。
该视图包含的其中重要的字段有:
1、sql_redo、2、sql_undo、3、xid、4、operation、5、seg_owner、6、seg_name、7、row_id、8、username
9、os_username、10、machine_name、11、session_info、12、info、13、scn、14、timestamp
LogMiner的基本元素: 源数据库、挖掘数据库(可以是源库也可以是其他库)、LogMiner字典、重做日志
挖掘数据库指 启动挖掘会话的数据库,如果挖掘库与源库不是同一个数据库,那么其硬件平台和字符集必须与源库一致
或字符集必须是源库的超集 即源库的字符集是 挖掘库的一个子集。挖掘库的版本还必须大于等于源库的版本。
LogMiner字典 是指 将重做记录中的ORACLE内部对象翻译为可读信息的转换字典。在重做记录中被更改的对象被记载为编号形式,
变更的数据被记载为ORACLE数据类型的编码形式。如无LogMiner字典的帮助,编号形式以 十进制数字显示,编码形式以十六
进制显示。
重做日志 指 由源库产生的 归档日志或在线日志。
LogMiner 字典的位置有两种: 源库日志字典、源库在线数据字典、将字典载入一个文本文件。它们不能同时使用。
源库日志字典是指 调用 dbms_logmnr_d.build 存储过程 将 LogMiner 字典提取至源库的重做日志里。
sql>begin dbms_logmnr_d.build(options=>dbms_logmnr_d.store_in_redo_logs) end;
查看v$archived_log视图 可以确定 LogMiner 字典在哪些日志中。
select sequence#,name ,dictionary_begin,dictionary_end
from v$archied_log where dictionary_begin='YES' or dictionary_end='YES';
如果一个归档日志文件中无法容纳LogMiner字典,Oracle会采用多个连续的归档日志作为LogMiner字典的载体。
日志字典的好处:1、不要求挖掘库和源库是同一个库、2、DDL命令可以更新字典,这样挖掘出来的信息能够完全体现
DDL命令操作的结果。
源库在线数据字典:直接在启动挖掘会话时通过 start_logmnr 存储过程的 options 参数指定即可。
源库数据字典好处:挖掘库与源库为同库;DDL命令无法更新字典;
字典载入文本文件:首先将 utl_file_dir 初始化参数指定一个路径;然后重启实例;最后调用 dbms_logmnr_d.build存储过程
时为 options 参数指定 store_in_flat_file常量。
alter system set utl_file_dir='path' scope=spfile;
startup force;
begin dbms_logmnr_d.build(dictionary_filename=>'name',
dictionary_location=>'path',
options=>dbms_logmnr_d.store_in_flat_file); end;
注册重做日志
分为:手动注册、自动注册
手动注册:即手动注册需要重做日志使用 dbms_logmnr.add_logfile 存储过程。可以注册多个源库日志,并且日志不一定需要
按照序号依次添加,日志序列号也不必是连续的。
begin
dbms_logmnr.add_logfile(logfilename=>'path',
options=>dbms_logmnr.addfile);
end;
挖掘库与源库为同库:
begin
for rec in (select name from v$archied_log where resetlogs_change#=(select resetlogs_change# from v$database) and name is not null)
loop
DBMS_LOGMNR.ADD_LOGFILE(logfilename=rec.name,options=>dbms_logmnr.addfile);
end loop;
end;
注册之后 查看已经成功注册的日志 v$logmnr_logs
select * from v$logmnr_logs order by 1,2,3;
自动注册:
自动注册不需要调用 dbms_logmnr.add_logifle 存储过程。而在在通过调用 dbms_logmnr.start_logmnr 启用挖掘会话时 对 options 参数
传入 contrinuous_mine 常量声明。没有了手动注册过程中的所谓 ”注册日志“的操作。
自动注册的限制:
挖掘库与源库必须为同一个库
启动挖掘会话时必须指定搜索日志的时间窗口,该窗口可以是由SCN 或 时间戳表示
控制文件内必须具有所需日志的记录,即搜索日志的范围不能超过 v$archived_log视图所显示的归档日志及 v$logfile视图性能显示
的直线日志。
启动挖掘会话
dbms_logmnr.start_logmnr 存储过程是启动挖掘会话的入口,成功调用该存储过程必须符合两个条件中的一个至少:
1、在会话中曾经使用 dbms_logmnr.add_logfile 存储过程手动注册过至少一个重做日志。
2、在调用 DBMS_LOGMNR.START_LOGMNR 存储过程时 使用 continuous_mine 选项。
源库与挖掘库同库,并以在线数据字典作为 LogMiner 字段启动挖掘会话。
begin
dbms_logmnr.add_logfile(logfilename=>reclog.name,options=>dbms_logmnr.addfile);
end;
begin
DBMS_LOGMNR.START_LOGMNR(options=>dbms_logmnr.dict_from _online_catalog);
end;
源库与挖掘库同库,并利用控制文件自动向 LogMiner 注册 SCN 范围 0001018 到 0000200 之间的重做日志;
begin
dbms_logmnr.start_logmnr(startscn=>00001018,
endscn=>0000200,
options=>dbms_logmnr.dict_from_online_catalog+ dbms_logmnr.continuous.mine);
end;
源库与挖掘库同库,以在线数据字典作为 LogMiner 字典启动挖掘会话,并利用控制文件自动向 LogMiner 注册时间为
2012年01月03日 10:03 到 2012年01月03日 10:10 之间重做日志:
begin
dbms_logmnr.start_logmnr(starttime=>to_date('2012-10-03 10:03:00','YYYY-MM-DD HH24:MI:SS'),
endtime=>to_date('2012-01-03 10:10:00','YYYY-MM-DD HH24:MI:SS'),
options=>dbms_logmnr.dict_from_online_catalog + dbms_logmnr.continuous_mine);
end;
以日志字典作为 LogMiner 字典启动挖掘会话,并在之前成功注册了重做日志。即
begin
DBMS_LOGMNR.ADD_LOGFILE(logfilename=>reclog.name,options=>dbms_logmnr.addfile);
end;
begin
dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_redo_logs);
end;
以日志字典 作为 LogMiner 字典启动挖掘会话,并利用控制文件自动向 LogMiner 注册 SCN 为 000010234 到 000020000
之间的重做日志,挖金库与源库为同一个库。
begin
dbms_logmnr.start_logmnr(startscn=>000010234,
endscn=>000020000,
options=>dbms_logmnr.dic_from_redo_logs+ DBMS_LOGMNR.CONTINUOUS_MINE.mine);
end;
以日志字典作为 LogMiner 字典启动挖掘会话,并利用控制文件自动向 LogMiner 注册时间范围在 2012年01月03日 10:03 到
2012年01月03日 10:10 之间重做日志。挖掘库与源库为同一个库
begin
dbms_logmnr.start_logmnr(starttime=>to_date('2012-01-03 10:03:00','YYYY-MM-DD HH24:MI:SS'),
endtime=>to_date('2012-01-03 10:10:00','YYYY-MM-DD HH24:MI:SS'),
options=>dbms_logmnr.dict_from_redo_logs+DBMS_LOGMNR.continuous_mine);
end;
options 参数的值决定了挖掘会话的属性及在挖掘时 V$LOGMNR_CONTENTS 视图的行为特征,该参数中传入的常量是NUMBER类型
,其值为 2的幂。
select text from dba_source where owner='SYS' and name='DBMS_LOGMNR' AND TYPE='PACKAGE' START WITH TEXT
LIKE 'COMMITTED_DATA_ONLY%CONSTANT%';
LogMiner 挖掘
挖掘会话被成功打开后,就可以在同一个会话中查询 v$logmnr_contents 视图了。
比如:
select '('||rownum||')'as SQL#,SQL_REDO,SQL_UNDO FROM V$LOGMNR_CONTENTS WHERE SEG_OWNER='TEST_USER'
AND SEG_NAME='TT';
利用 column_present 函数和 redo_value 字段挖掘感兴趣的字段的变更
column_present 函数可以用来判断特定的字段是否被变更(变更则为1,否则为0)
select '('||rownum||')' as SQL#,sql_redo,sql_undo from v$logmnr_contents where seg_owner='test_user' and seg_name='tt'
and DBMS_LOGMNR.COLUMN_PRESENT(redo_value,'test_user.tt.city')=1;---- 这里的 =1 表示对特定的字段感兴趣。
利用 mine_value 函数和 redo_value 和 undo_value 字段更能正规显示 新 值 和 旧 值
select '('||rownum||')' as SQL#,sql_redo,sql_undo from v$logmnr_contents where seg_owner='test_user' and seg_name='tt'
and DBMS_LOGMNR.COLUMN_PRESENT(redo_value,'test_user.tt.city')=1 and
dbms_logmnr.mine_value(redo_value,'test_user.tt.city') / dbms_logmnr.mine_value(undo_value,'test_user.tt.city') >1.1;
关闭挖掘会话
可以显示或隐式的方式结束。
显示则是调用 dbms_logmnr.end_lognr 存储过程。
隐式方式则是 调用 dbms_logmnr.add_logfile 存储过程时对 options 参数传入 dbms_logmnr.new 常量
begin
DBMS_LOGMNR.ADD_LOGFILE(logfilename=>'log_path',
options=>dbms_logmnr.new);
----即使用隐式方式时还将logfilename 参数指定的日志更换为注册的日志。
end;