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# STATUSITPUB个人空间$X4@V:b0DiH
---------- ---------- ----------------ITPUB个人空间'M:^o6o3~
1 239 CURRENTITPUB个人空间:~HV!S qi*h8d
2 237 INACTIVE
HkJ9EIn
E0 3 238 ACTIVE
SQL>COLMEMBER FORMAT A60
4SBfo.~3]g0SQL> SELECT GROUP#, MEMBER FROM V$LOGFILE;
GROUP# MEMBERITPUB个人空间q-S-j$nvA
to(Y'q;?
---------- ------------------------------------------------------------
-d\ J&N(pY0 3 E:\ORACLE\ORADATA\YTK102\REDO03.LOG
d5x1H9T/[^1i0 2 E:\ORACLE\ORADATA\YTK102\REDO02.LOGITPUB个人空间X(A.g4|
h3|
m
d)j
1 E:\ORACLE\ORADATA\YTK102\REDO01.LOG
SQL> ALTER SYSTEM SWITCH LOGFILE;
系统已更改。
SQL> EXEC SYS.DBMS_LOGMNR.ADD_LOGFILE('E:\ORACLE\ORADATA\YTK102\REDO01.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
)\.l"c;~pnF!F0 2 WHERE SEG_OWNER = USERITPUB个人空间-V]C4p~ao%m c-R-sY
3 AND TABLE_NAME = 'T'ITPUB个人空间8T3_"QoPeU|Q
4 AND PERATION = 'UPDATE';
COUNT(*)
.K4|TZ5H A#A9~3F)@0----------
o2^
TDqr ]0 50620
返回的记录数太多,而我们只关心其中FLAG字段被更新为0的记录。而V$LOGMNR_CONTEXTS视图中是不会包含列的值的,如果直接使用SQL_REDO LIKE的方式,一是效率比较差,二是得到的结果不准确。
最方便的方法就是利用DBMS_LOGMNR提供的MINE_VALUE函数:
SQL> SELECT SQL_REDO FROM V$LOGMNR_CONTENTS