yangtingkun
===========================================================
LOGMINER的MINE_VALUE功能
===========================================================

LOGMNR的一个很实用的小功能,简单记录一下。


手工进行LOGMNR分析,大多数是为了寻找被意外修改的数据,或者寻找哪条SQL修改了哪些数据。

一般这种情况,关注点都比较明确,甚至可以确定到字段的值,比如需要找到字段A1变成0的所有修改。

而这种情况使用LOGMNR提供的MINE_VALUE就再合适不过了。

一个简单的例子:

SQL> CREATE TABLE T (ID NUMBER, NAME VARCHAR2(30), FLAG NUMBER(1));

表已创建。

SQL> INSERT INTO T SELECT ROWNUM, OBJECT_NAME, 1 FROM DBA_OBJECTS;

已创建50668行。

SQL> COMMIT;

提交完成。

SQL> UPDATE T SET FLAG = CASE MOD(ROWNUM, 10000) WHEN 0 THEN 0 ELSE 1 END;

已更新50668行。

SQL> COMMIT;

提交完成。

下面系统通过LOGMNR找到FLAG被更新为0的记录:

SQL> SELECT GROUP#, SEQUENCE#, STATUS FROM V$LOG;

GROUP# SEQUENCE# STATUS
---------- ---------- ----------------
1 239 CURRENT
2 237 INACTIVE
3 238 ACTIVE

SQL> COL MEMBER FORMAT A60
SQL> SELECT GROUP#, MEMBER FROM V$LOGFILE;

GROUP# MEMBER
---------- ------------------------------------------------------------
3 E:ORACLEORADATAYTK102REDO03.LOG
2 E:ORACLEORADATAYTK102REDO02.LOG
1 E:ORACLEORADATAYTK102REDO01.LOG

SQL> ALTER SYSTEM SWITCH LOGFILE;

系统已更改。

SQL> EXEC SYS.DBMS_LOGMNR.ADD_LOGFILE('E:ORACLEORADATAYTK102REDO01.LOG', SYS.DBMS_LOGMNR.NEW)

PL/SQL 过程已成功完成。

SQL> EXEC SYS.DBMS_LOGMNR.START_LOGMNR(OPTIONS => SYS.DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG)

PL/SQL 过程已成功完成。

SQL> SELECT COUNT(*) FROM V$LOGMNR_CONTENTS
2 WHERE SEG_OWNER = USER
3 AND TABLE_NAME = 'T'
4 AND OPERATION = 'UPDATE';

COUNT(*)
----------
50620

返回的记录数太多,而我们只关心其中FLAG字段被更新为0的记录。而V$LOGMNR_CONTEXTS视图中是不会包含列的值的,如果直接使用SQL_REDO LIKE的方式,一是效率比较差,二是得到的结果不准确。

最方便的方法就是利用DBMS_LOGMNR提供的MINE_VALUE函数:

SQL> SELECT SQL_REDO FROM V$LOGMNR_CONTENTS
2 WHERE SEG_OWNER = USER
3 AND TABLE_NAME = 'T'
4 AND OPERATION = 'UPDATE'
5 AND SYS.DBMS_LOGMNR.MINE_VALUE(REDO_VALUE, 'YANGTK.T.FLAG') = 0;

SQL_REDO
-----------------------------------------------------------------------------------------
update "YANGTK"."T" set "FLAG" = '0' where "FLAG" = '1' and ROWID = 'AAAN4SAAGAAABhvAB/';
update "YANGTK"."T" set "FLAG" = '0' where "FLAG" = '1' and ROWID = 'AAAN4SAAGAAABmaAB3';
update "YANGTK"."T" set "FLAG" = '0' where "FLAG" = '1' and ROWID = 'AAAN4SAAIAAABUtAAH';
update "YANGTK"."T" set "FLAG" = '0' where "FLAG" = '1' and ROWID = 'AAAN4SAAIAAABViAAA';
update "YANGTK"."T" set "FLAG" = '0' where "FLAG" = '1' and ROWID = 'AAAN4SAAGAAABjAABA';

SQL> EXEC SYS.DBMS_LOGMNR.END_LOGMNR

PL/SQL 过程已成功完成。

使用MINE_VALUE函数,可以有效的提高LOGMNR搜索数据的效率。

yangtingkun 发表于:2008.06.10 23:57 ::分类: ( ORACLE ) ::阅读:(583次) :: 评论 (2)
re: LOGMINER的MINE_VALUE功能 [回复]

能够精确定位到那条记录被更新的确很好,能否配合其他视图获取更新这些记录的原始SQL,以及操作时间?

我看 SYS.DBMS_LOGMNR.START_LOGMNR 默认不是启动的,是否会造成很大很大很大的日志文件?

kylin 评论于: 2008.06.11 07:55
re: LOGMINER的MINE_VALUE功能 [回复]

操作时间可以获取,但是原始SQL一般来说没有办法,除非这个SQL还在共享池中没有被清除出去,即使如此,找到原始SQL也是比较麻烦的。

yangtingkun 评论于: 2008.06.11 16:38

发表评论
标题

在此添加评论
表情符号: smile laughing tongue angry crying sad wassat wink

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


切换风格
新闻聚合
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
Blog信息
网站链接...