Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2896493
  • 博文数量: 599
  • 博客积分: 16398
  • 博客等级: 上将
  • 技术积分: 6875
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-30 12:04
个人简介

WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606

文章分类

全部博文(599)

文章存档

2014年(12)

2013年(56)

2012年(199)

2011年(105)

2010年(128)

2009年(99)

分类: Oracle

2010-01-14 10:36:52

    很早以前就碰到这个问题,一直以为是由于没有设置FORCE_LOGGING的问题,今天才发现不是这个问题。
上一篇文章介绍了问题的现象,并给出了解决方法,这里简单说明一下问题产生的原因。
Oracle10GLOGMNR捕获不到记录(一):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
已连接。
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
已连接。
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 Database11gEnterprise Edition Release11.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

 
阅读(806) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~