Oracle10G LOGMNR捕獲不到記錄(二)
很早以前就碰到這個問題,一直以為是由於沒有設定FORCE_LOGGING的問題,今天才發現不是這個問題。
上一篇文章介紹了問題的現象,並給出瞭解決方法,這裡簡單說明一下問題產生的原因。
Oracle10G LOGMNR捕獲不到記錄(一):http://yangtingkun.itpub.net/post/468/464865
上一篇文章說明了LOGMNR找不到資料的現象和對應的解決方法,但是並沒有說明導致問題產生的原因。
而Oracle在METALINK的另一篇文章中對這個問題進行簡單的說明:Bug No. 3877515。
根據這篇文章的描述,在沒有設定SUPPLEMENTAL LOG DATA時,10g使用記憶體UNDO技術IMU(IN-MEMORY UNDO),而這種技術是LOGMNR所不支援的。因此透過LOGMNR分析10g的記錄是得不到結果的。而9i則沒有這種情況。
如果確實如METALINK所說,Oracle使用的是IN MEMORY UNDO技術,那麼重啟資料庫後第一次操作肯定是要被記錄到日誌中的:
SQL> SELECT SUPPLEMENTAL_LOG_DATA_PK, SUPPLEMENTAL_LOG_DATA_UI FROM V$DATABASE;
SUP SUP
--- ---
YES YES
SQL> ALTER DATABASE DROP SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE INDEX) COLUMNS;
資料庫已更改。
SQL> SELECT SUPPLEMENTAL_LOG_DATA_PK, SUPPLEMENTAL_LOG_DATA_UI FROM V$DATABASE;
SUP SUP
--- ---
NO NO
SQL> ALTER SYSTEM SWITCH LOGFILE;
系統已更改。
SQL> SELECT GROUP#, SEQUENCE#, STATUS FROM V$LOG;
GROUP# SEQUENCE# STATUS
---------- ---------- ----------------
1 248 INACTIVE
2 249 ACTIVE
3 250 CURRENT
SQL> SELECT GROUP#, MEMBER FROM V$LOGFILE;
GROUP# MEMBER
---------- --------------------------------------------------
3 E:\ORACLE\ORADATA\YTK102\REDO03.LOG
2 E:\ORACLE\ORADATA\YTK102\REDO02.LOG
1 E:\ORACLE\ORADATA\YTK102\REDO01.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:\ORACLE\ORADATA\YTK102\REDO03.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);
SQL> EXEC SYS.DBMS_LOGMNR.END_LOGMNR
PL/SQL 過程已成功完成。
改變SUPPLEMENTAL LOG DATA的狀態,回到預設情況下,這時透過LOGMNR沒有獲取到DML操作,下面重啟資料庫:
SQL> CONN / AS SYSDBA
已連線到空閒例程。
SQL> SHUTDOWN IMMEDIATE
資料庫已經關閉。
已經解除安裝資料庫。
ORACLE 例程已經關閉。
SQL> STARTUP
ORACLE 例程已經啟動。
Total System Global Area 603979776 bytes
Fixed Size 1249332 bytes
Variable Size 226496460 bytes
Database Buffers 369098752 bytes
Redo Buffers 7135232 bytes
資料庫裝載完畢。
資料庫已經開啟。
下面重新執行上面的指令碼,檢查是否可以在LOGMNR中獲取DML:
SQL> CONN YANGTK/YANGTK@YTK102
已連線。
SQL> SELECT GROUP#, SEQUENCE#, STATUS FROM V$LOG;
GROUP# SEQUENCE# STATUS
---------- ---------- ----------------
1 251 CURRENT
2 249 INACTIVE
3 250 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:\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 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);
SQL> EXEC SYS.DBMS_LOGMNR.END_LOGMNR
PL/SQL 過程已成功完成。
仍然無法獲取DML,看來這種IN-MEMORY UNDO和資料庫重啟沒有關係。那麼建立一個從未建立過的表,插入一條新的記錄,是否能捕獲到呢:
SQL> CREATE TABLE T_NO_EXISTS_BEFORE (ID NUMBER, NAME VARCHAR2(30));
表已建立。
SQL> INSERT INTO T_NO_EXISTS_BEFORE VALUES (281082347, 'NAME NEVER BEEN INSERTED');
已建立 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT GROUP#, SEQUENCE#, STATUS FROM V$LOG;
GROUP# SEQUENCE# STATUS
---------- ---------- ----------------
1 251 ACTIVE
2 252 CURRENT
3 250 INACTIVE
SQL> ALTER SYSTEM SWITCH LOGFILE;
系統已更改。
SQL> EXEC SYS.DBMS_LOGMNR.ADD_LOGFILE('E:\ORACLE\ORADATA\YTK102\REDO02.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_NO_EXISTS_BEFORE';
SQL_REDO
---------------------------------------------------------------------
CREATE TABLE T_NO_EXISTS_BEFORE (ID NUMBER, NAME VARCHAR2(30));
SQL> EXEC SYS.DBMS_LOGMNR.END_LOGMNR
PL/SQL 過程已成功完成。
同樣無法捕獲,看來IMU和名稱上表示出來的含義還是有一定差距的。不過值得欣慰的是,Oracle11g中,即使不設定SUPPLEMENTAL LOG DATA,也可以透過LOGMNR獲取DML,Oracle的LOGMNR預設狀態又恢復到了9I的情況:
SQL> CONN YANGTK/yangtk@TEST11G
已連線。
SQL> SELECT GROUP#, SEQUENCE#, STATUS FROM V$LOG;
GROUP# SEQUENCE# STATUS
---------- ---------- ----------------
1 1279 CURRENT
2 1277 INACTIVE
3 1278 INACTIVE
SQL> SELECT GROUP#, MEMBER FROM V$LOGFILE;
GROUP# MEMBER
---------- --------------------------------------------------
1 /data/oracle/oradata/test11g/redo01.log
2 /data/oracle/oradata/test11g/redo02.log
3 /data/oracle/oradata/test11g/redo03.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('/data/oracle/oradata/test11g/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 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 過程已成功完成。
SQL> SELECT * FROM V$VERSION;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
PL/SQL Release 11.1.0.6.0 - Production
CORE 11.1.0.6.0 Production
TNS for Solaris: Version 11.1.0.6.0 - Production
NLSRTL Version 11.1.0.6.0 - Production
SQL> SELECT SUPPLEMENTAL_LOG_DATA_PK, SUPPLEMENTAL_LOG_DATA_UI FROM V$DATABASE;
SUP SUP
--- ---
NO NO
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1064086/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle10G LOGMNR捕獲不到記錄Oracle
- Oracle10G LOGMNR捕獲不到記錄(一)Oracle
- 記錄Javascript 異常捕獲JavaScript
- 記錄使用 guzzlehttp 異常捕獲踩坑記錄HTTP
- 捕獲不到異常嘗試除以0
- oracle10g logmnr的使用Oracle
- 如何捕獲和記錄SQL Server中發生的死鎖SQLServer
- STREAMS筆記(10) 同步捕獲筆記
- 【筆記】forall 異常捕獲筆記
- JavaScript事件捕獲冒泡與捕獲JavaScript事件
- 捕獲NSLog日誌小記
- Oracle10g新特性——記錄DML錯誤日誌(二)Oracle
- 小程式雲開發獲取不到資料庫的記錄資料庫
- jQuery捕獲jQuery
- C# winform NLog AOP 記錄全域性未捕獲的異常到日誌C#ORM
- JavaScript 事件捕獲JavaScript事件
- 錯誤捕獲
- Oracle10g新特性——LOG ERRORS記錄DML錯誤日誌(二)OracleError
- php 正規表示式捕獲組與非捕獲組PHP
- Capture One mac教程:如何匯入捕獲一個目錄APTMac
- Oracle10g RAC設定記錄Oracle
- 捕獲 React 異常React
- 捕獲cookie的值Cookie
- iOS異常捕獲iOS
- Swift速成:捕獲列表Swift
- 管理捕獲程式——流
- 【Mysql】捕獲線上sqlMySql
- 【目標區域捕獲-2】目標區域捕獲簡介
- WIP_PERIOD_BALANCE 中找不到記錄
- javascript捕獲組如何使用JavaScript
- python異常捕獲Python
- 事件冒泡 和 事件捕獲事件
- C++ lambda 捕獲列表C++
- #每日一記#通過 GIF 理解 addEventListener、捕獲和冒泡dev
- 正規表示式中的捕獲和反向引用筆記筆記
- WPF捕獲事件即使這個事件被標記為Handled事件
- 工具介紹 - 捕獲Windows CE的記憶體洩露Windows記憶體洩露
- @SentinelResource踩坑記錄:blockHandler兜底方法找不到BloC