发表于: 2008.06.10 23:57
分类: ORACLE
出处: http://yangtingkun.itpub.net/post/468/464136
---------------------------------------------------------------
LOGMNR的一个很实用的小功能,简单记录一下。
手工进行LOGMNR分析,大多数是为了寻找被意外修改的数据,或者寻找哪条SQL修改了哪些数据。
一般这种情况,关注点都比较明确,甚至可以确定到字段的值,比如需要找到字段A从1变成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搜索数据的效率。











