问题起源是在10g的版本上使用LOGMNR找不到刚刚执行的DML操作:
SQL> SELECT GROUP#, SEQUENCE#, STATUS FROM V$LOG;
GROUP# SEQUENCE# STATUS
---------- ---------- ----------------
1 245 INACTIVE
2 246 INACTIVE
3 247 CURRENT
SQL> SELECT GROUP#, MEMBER FROM V$LOGFILE;
GROUP# MEMBER
---------- --------------------------------------------------
3 E:ORACLEORADATAYTK102REDO03.LOG
2 E:ORACLEORADATAYTK102REDO02.LOG
1 E:ORACLEORADATAYTK102REDO01.LOG
SQL> DROP TABLE T PURGE;
表已删除。
SQL> CREATE TABLE T (ID NUMBER);
表已创建。
SQL> INSERT INTO T VALUES (1);
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> ALTER SYSTEM SWITCH LOGFILE;
系统已更改。
SQL> EXEC SYS.DBMS_LOGMNR.ADD_LOGFILE('E:ORACLEORADATAYTK102REDO03.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 SQL_REDO FROM V$LOGMNR_CONTENTS WHERE SEG_OWNER = USER AND TABLE_NAME = 'T';
SQL_REDO
------------------------------------------------------------------
CREATE TABLE T (ID NUMBER);
SQL> EXEC SYS.DBMS_LOGMNR.END_LOGMNR
PL/SQL 过程已成功完成。
SQL> SELECT * FROM V$VERSION;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
本来一直是认为是没有设置FORCE_LOGGING,导致部分记录没有在REDO文件中被记录,结果查询V$DATABASE确发现当前正是FORCE LOGGING状态:
SQL> SELECT FORCE_LOGGING FROM V$DATABASE;
FOR
---
YES
同样的问题从没有在9i上发生过,说明应该是Oracle10g的某些改变导致了问题的产生。
查询了metalink,Oracle在文档Doc ID: Note:291574.1中对这个问题进行了详细说明,如果希望LOGMNR可以得到记录,应该设置SUPPLEMENTAL LOG DATA PRIMARY KEY和UNIQUE INDEX,这样Oracle才能确保LOGMNR可以获取SQL语句:
SQL> SELECT SUPPLEMENTAL_LOG_DATA_PK, SUPPLEMENTAL_LOG_DATA_UI FROM V$DATABASE;
SUP SUP
--- ---
NO NO
SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE INDEX) COLUMNS;
数据库已更改。
SQL> SELECT SUPPLEMENTAL_LOG_DATA_PK, SUPPLEMENTAL_LOG_DATA_UI FROM V$DATABASE;
SUP SUP
--- ---
YES YES
SQL> SELECT GROUP#, SEQUENCE#, STATUS FROM V$LOG;
GROUP# SEQUENCE# STATUS
---------- ---------- ----------------
1 248 CURRENT
2 246 INACTIVE
3 247 INACTIVE
SQL> DROP TABLE T PURGE;
表已删除。
SQL> CREATE TABLE T (ID NUMBER);
表已创建。
SQL> INSERT INTO T VALUES (1);
已创建 1 行。
SQL> COMMIT;
提交完成。
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 SQL_REDO FROM V$LOGMNR_CONTENTS WHERE SEG_OWNER = USER AND TABLE_NAME = 'T';
SQL_REDO
----------------------------------------------------------------------------------
DROP TABLE T PURGE;
CREATE TABLE T (ID NUMBER);
insert into "YANGTK"."T"("ID") values ('1');
SQL> EXEC SYS.DBMS_LOGMNR.END_LOGMNR
PL/SQL 过程已成功完成。
可以看到,在10g中默认情况下LOGMNR已经不是一个可靠的数据获取的方式,希望通过这种方式获取丢失数据,则需要提前设置SUPPLEMENTAL LOG DATA。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/235507/viewspace-673056/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/235507/viewspace-673056/