Oracle 11.2.0.3 重做日志的问题
Trouble with Oracle 11.2.0.3 redo logs
我在 oracle 11.2.0.3 中有一个 table,我想在重做日志中捕获它。问题是它有一个 sdo_geometry 字段。这是我无法更改的遗产 table。但好消息是我不需要 sdo_geometry 字段。
所以我创建了一个物化视图,如下所示。
CREATE MATERIALIZED VIEW LOG ON LEGACY_TABLE_NAME
WITH PRIMARY KEY
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW LEGACY_TABLE_NAME_MV
NOLOGGING
NOCACHE
BUILD IMMEDIATE
REFRESH FAST ON COMMIT
WITH PRIMARY KEY
AS
SELECT <List of non sdo_gemoetry columns> FROM LEGACY_TABLE_NAME;
当我进行更新并查看重做日志时,问题出现了。我没有看到更新语句,而是看到了删除和插入语句。由于我使用的是主键,因此我希望看到更新语句。
有谁知道我需要做什么才能确保在重做日志中看到更新语句。
谢谢
我认为您误解了 redolog
存储的内容和 materiliazed view log
的存储内容。
让我们尝试对这两种情况进行测试:
- LogMiner 验证重做日志文件的内容,我们可以使用 v$LOGMNR_CONTENTS.
查看
- 实体化视图日志和更新操作示例
甲骨文版本:12.2
重做日志内容
SQL> create table cpl_rep.test_redo_logs ( c1 number primary key , c2 number ) ;
Table created.
SQL> insert into cpl_rep.test_redo_logs values ( 1 , 1 );
1 row created.
SQL> insert into cpl_rep.test_redo_logs values ( 2 , 2 );
1 row created.
SQL> commit ;
Commit complete.
SQL> update cpl_rep.test_redo_logs set c1=3 , c2=3 where c1 = 2 ;
1 row updated.
SQL> commit ;
Commit complete.
SQL> select * from cpl_rep.test_redo_logs ;
C1 C2
---------- ----------
1 1
3 3
SQL> exit
Disconnected from Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit
Production
$ sqlplus / as sysdba
SQL*Plus: Release 12.2.0.1.0 Production on Sat Aug 8 21:53:05 2020
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
SQL> alter system switch logfile ;
System altered.
SQL> exit
Disconnected from Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit
Production
现在让我们通过将重做日志文件加载到 LogMiner 来启动 LogMiner 会话:
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo1/redo11.ora' , 1);
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo2/redo21.ora' , 1);
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo1/redo12.ora' , 1);
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo2/redo22.ora' , 1);
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo1/redo13.ora' , 1);
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo2/redo23.ora' , 1);
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
SQL> exec dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
PL/SQL procedure successfully completed.
SQL> select count(*) from v$logmnr_contents where seg_name = upper('test_redo_logs') ;
COUNT(*)
----------
4
SQL> select sql_redo , seg_name from v$logmnr_contents where seg_name = upper('test_redo_logs') ;
SQL_REDO
--------------------------------------------------------------------------------
SEG_NAME
--------------------------------------------------------------------------------
create table cpl_rep.test_redo_logs ( c1 number primary key , c2 number ) ;
TEST_REDO_LOGS
insert into "CPL_REP"."TEST_REDO_LOGS"("C1","C2") values ('1','1');
TEST_REDO_LOGS
insert into "CPL_REP"."TEST_REDO_LOGS"("C1","C2") values ('2','2');
TEST_REDO_LOGS
SQL_REDO
--------------------------------------------------------------------------------
SEG_NAME
--------------------------------------------------------------------------------
update "CPL_REP"."TEST_REDO_LOGS" set "C1" = '3', "C2" = '3' where "C1" = '2' an
d "C2" = '2' and ROWID = 'AAGKh2AAAAAJIH1AAB';
TEST_REDO_LOGS
正如您在上面看到的,UPDATE
与 V$LOGMNR_CONTENTS
的 SQL_REDO
列中的任何其他 DML
操作一样正常显示。所以,很明显,只要操作是在日志模式下完成的,或者数据库是在强制日志模式下,重做文件就会存储任何更新操作,在这种情况下,操作是什么模式并不重要,因为它总是存储。
物化视图日志
让我们像您在问题中所做的那样创建一个 materialized view log
和一个 materialized view
。但是,为了验证 MLOG$ tables 的内容,我将按需刷新,而不是在提交时刷新。
SQL> create table x ( c1 number primary key , c2 number ) ;
Table created.
SQL> insert into x values ( 1 , 1 ) ;
1 row created.
SQL> insert into x values ( 2 , 2 );
1 row created.
SQL> commit ;
Commit complete.
SQL> create materialized view log on x with primary key including new values ;
Materialized view log created.
SQL> create materialized view mv_x nologging nocache build immediate refresh fast on demand with primary key as select c1 , c2 from x ;
Materialized view created.
SQL> select * from x ;
C1 C2
---------- ----------
1 1
2 2
SQL> select * from mv_x ;
C1 C2
---------- ----------
1 1
2 2
SQL> insert into x values ( 3 , 3 );
1 row created.
SQL> commit ;
Commit complete.
SQL> update x set c1=4 , c2=4 where c1=3 ;
1 row updated.
SQL> commit ;
Commit complete.
由于我们确实创建了按需刷新的物化视图,现在让我们来看看 MLOG$
table
的内容
SQL> select * from x ;
C1 C2
---------- ----------
1 1
2 2
4 4
SQL> select * from mv_x ;
C1 C2
---------- ----------
1 1
2 2
SQL> select * from mlog$_x
C1 SNAPTIME$ D O CHANGE_VEC XID$$
---------- --------- - - ---------- ----------------------------
3 01-JAN-00 I N FE 39406677128122001
3 01-JAN-00 D O 00 44473269658586765
4 01-JAN-00 I N FF 44473269658586765
那我刷新
SQL> select * from x ;
C1 C2
---------- ----------
1 1
2 2
4 4
SQL> select * from mv_x ;
C1 C2
---------- ----------
1 1
2 2
SQL> exec dbms_mview.refresh('MV_X') ;
PL/SQL procedure successfully completed.
SQL> select * from mv_x ;
C1 C2
---------- ----------
1 1
2 2
4 4
SQL> select * from mlog$_x
2 ;
no rows selected
您在 DMLTYPE$$
上看不到 UPDATE
的原因是您在实体化视图创建中选择主键作为 WITH 子句。在这种情况下,只有 D 或 I 会出现在列 DMLTYPE$$
中,但是当它是更新时,你会得到两行具有相同事务 ID(上例中的 XID$$
字段具有相同的价值)
但是,请检查当我使用 ROWID
而不是 PRIMARY KEY
时会发生什么
SQL> create materialized view log on x with rowid including new values ;
Materialized view log created.
SQL> create materialized view mv_x nologging nocache build immediate refresh fast on demand with rowid as select c1 , c2 from cpl_rep.x ;
Materialized view created.
SQL> select * from cpl_rep.mv_x ;
C1 C2
---------- ----------
1 1
2 2
3 3
SQL> select * from x ;
C1 C2
---------- ----------
1 1
2 2
3 3
SQL> insert into x values ( 4 , 4 ) ;
1 row created.
SQL> commit ;
Commit complete.
SQL> insert into x values ( 5 , 5 );
1 row created.
SQL> commit ;
Commit complete.
SQL> update x set c1=6 , c2=6 where c1=5 ;
1 row updated.
SQL> commit ;
Commit complete.
SQL> select * from x ;
C1 C2
---------- ----------
1 1
2 2
3 3
4 4
6 6
SQL> select * from mv_x ;
C1 C2
---------- ----------
1 1
2 2
3 3
现在来看看M$LOG
table的内容
SQL> col m_row$$ for a18
SQL> select * from mlog$_x ;
M_ROW$$ SNAPTIME$ D O CHANGE_VEC XID$$
------------------ --------- - - ---------- ----------------------------
AAGKh/AAAAAJJWnAAD 01-JAN-00 I N FE 3659458165104006
AAGKh/AAAAAJJWnAAE 01-JAN-00 I N FE 44754731750395757
AAGKh/AAAAAJJWnAAE 01-JAN-00 U U 06 12948119511653544
AAGKh/AAAAAJJWnAAE 01-JAN-00 U N 06 12948119511653544
我现在有 4 行,2 行用于插入,1 行用于字段 C1,另一行用于字段 C2,它们实际上是同一事务(字段 XID$$
)
我希望它能阐明当您选择 ROWID 或 PRIMARY KEYY 时如何填充 MLOG$ table。请注意,使用主键的物化视图日志 tables 也有 rupd$_
tables。 rupd$_ table 支持可更新的物化视图,这只能在具有主键的日志 tables 上实现。
我在 oracle 11.2.0.3 中有一个 table,我想在重做日志中捕获它。问题是它有一个 sdo_geometry 字段。这是我无法更改的遗产 table。但好消息是我不需要 sdo_geometry 字段。 所以我创建了一个物化视图,如下所示。
CREATE MATERIALIZED VIEW LOG ON LEGACY_TABLE_NAME
WITH PRIMARY KEY
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW LEGACY_TABLE_NAME_MV
NOLOGGING
NOCACHE
BUILD IMMEDIATE
REFRESH FAST ON COMMIT
WITH PRIMARY KEY
AS
SELECT <List of non sdo_gemoetry columns> FROM LEGACY_TABLE_NAME;
当我进行更新并查看重做日志时,问题出现了。我没有看到更新语句,而是看到了删除和插入语句。由于我使用的是主键,因此我希望看到更新语句。
有谁知道我需要做什么才能确保在重做日志中看到更新语句。
谢谢
我认为您误解了 redolog
存储的内容和 materiliazed view log
的存储内容。
让我们尝试对这两种情况进行测试:
- LogMiner 验证重做日志文件的内容,我们可以使用 v$LOGMNR_CONTENTS. 查看
- 实体化视图日志和更新操作示例
甲骨文版本:12.2
重做日志内容
SQL> create table cpl_rep.test_redo_logs ( c1 number primary key , c2 number ) ;
Table created.
SQL> insert into cpl_rep.test_redo_logs values ( 1 , 1 );
1 row created.
SQL> insert into cpl_rep.test_redo_logs values ( 2 , 2 );
1 row created.
SQL> commit ;
Commit complete.
SQL> update cpl_rep.test_redo_logs set c1=3 , c2=3 where c1 = 2 ;
1 row updated.
SQL> commit ;
Commit complete.
SQL> select * from cpl_rep.test_redo_logs ;
C1 C2
---------- ----------
1 1
3 3
SQL> exit
Disconnected from Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit
Production
$ sqlplus / as sysdba
SQL*Plus: Release 12.2.0.1.0 Production on Sat Aug 8 21:53:05 2020
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
SQL> alter system switch logfile ;
System altered.
SQL> exit
Disconnected from Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit
Production
现在让我们通过将重做日志文件加载到 LogMiner 来启动 LogMiner 会话:
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo1/redo11.ora' , 1);
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo2/redo21.ora' , 1);
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo1/redo12.ora' , 1);
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo2/redo22.ora' , 1);
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo1/redo13.ora' , 1);
SQL> exec dbms_logmnr.add_logfile('/bbdd_odcgrc1r/redo2/redo23.ora' , 1);
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
SQL> exec dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
PL/SQL procedure successfully completed.
SQL> select count(*) from v$logmnr_contents where seg_name = upper('test_redo_logs') ;
COUNT(*)
----------
4
SQL> select sql_redo , seg_name from v$logmnr_contents where seg_name = upper('test_redo_logs') ;
SQL_REDO
--------------------------------------------------------------------------------
SEG_NAME
--------------------------------------------------------------------------------
create table cpl_rep.test_redo_logs ( c1 number primary key , c2 number ) ;
TEST_REDO_LOGS
insert into "CPL_REP"."TEST_REDO_LOGS"("C1","C2") values ('1','1');
TEST_REDO_LOGS
insert into "CPL_REP"."TEST_REDO_LOGS"("C1","C2") values ('2','2');
TEST_REDO_LOGS
SQL_REDO
--------------------------------------------------------------------------------
SEG_NAME
--------------------------------------------------------------------------------
update "CPL_REP"."TEST_REDO_LOGS" set "C1" = '3', "C2" = '3' where "C1" = '2' an
d "C2" = '2' and ROWID = 'AAGKh2AAAAAJIH1AAB';
TEST_REDO_LOGS
正如您在上面看到的,UPDATE
与 V$LOGMNR_CONTENTS
的 SQL_REDO
列中的任何其他 DML
操作一样正常显示。所以,很明显,只要操作是在日志模式下完成的,或者数据库是在强制日志模式下,重做文件就会存储任何更新操作,在这种情况下,操作是什么模式并不重要,因为它总是存储。
物化视图日志
让我们像您在问题中所做的那样创建一个 materialized view log
和一个 materialized view
。但是,为了验证 MLOG$ tables 的内容,我将按需刷新,而不是在提交时刷新。
SQL> create table x ( c1 number primary key , c2 number ) ;
Table created.
SQL> insert into x values ( 1 , 1 ) ;
1 row created.
SQL> insert into x values ( 2 , 2 );
1 row created.
SQL> commit ;
Commit complete.
SQL> create materialized view log on x with primary key including new values ;
Materialized view log created.
SQL> create materialized view mv_x nologging nocache build immediate refresh fast on demand with primary key as select c1 , c2 from x ;
Materialized view created.
SQL> select * from x ;
C1 C2
---------- ----------
1 1
2 2
SQL> select * from mv_x ;
C1 C2
---------- ----------
1 1
2 2
SQL> insert into x values ( 3 , 3 );
1 row created.
SQL> commit ;
Commit complete.
SQL> update x set c1=4 , c2=4 where c1=3 ;
1 row updated.
SQL> commit ;
Commit complete.
由于我们确实创建了按需刷新的物化视图,现在让我们来看看 MLOG$
table
SQL> select * from x ;
C1 C2
---------- ----------
1 1
2 2
4 4
SQL> select * from mv_x ;
C1 C2
---------- ----------
1 1
2 2
SQL> select * from mlog$_x
C1 SNAPTIME$ D O CHANGE_VEC XID$$
---------- --------- - - ---------- ----------------------------
3 01-JAN-00 I N FE 39406677128122001
3 01-JAN-00 D O 00 44473269658586765
4 01-JAN-00 I N FF 44473269658586765
那我刷新
SQL> select * from x ;
C1 C2
---------- ----------
1 1
2 2
4 4
SQL> select * from mv_x ;
C1 C2
---------- ----------
1 1
2 2
SQL> exec dbms_mview.refresh('MV_X') ;
PL/SQL procedure successfully completed.
SQL> select * from mv_x ;
C1 C2
---------- ----------
1 1
2 2
4 4
SQL> select * from mlog$_x
2 ;
no rows selected
您在 DMLTYPE$$
上看不到 UPDATE
的原因是您在实体化视图创建中选择主键作为 WITH 子句。在这种情况下,只有 D 或 I 会出现在列 DMLTYPE$$
中,但是当它是更新时,你会得到两行具有相同事务 ID(上例中的 XID$$
字段具有相同的价值)
但是,请检查当我使用 ROWID
而不是 PRIMARY KEY
SQL> create materialized view log on x with rowid including new values ;
Materialized view log created.
SQL> create materialized view mv_x nologging nocache build immediate refresh fast on demand with rowid as select c1 , c2 from cpl_rep.x ;
Materialized view created.
SQL> select * from cpl_rep.mv_x ;
C1 C2
---------- ----------
1 1
2 2
3 3
SQL> select * from x ;
C1 C2
---------- ----------
1 1
2 2
3 3
SQL> insert into x values ( 4 , 4 ) ;
1 row created.
SQL> commit ;
Commit complete.
SQL> insert into x values ( 5 , 5 );
1 row created.
SQL> commit ;
Commit complete.
SQL> update x set c1=6 , c2=6 where c1=5 ;
1 row updated.
SQL> commit ;
Commit complete.
SQL> select * from x ;
C1 C2
---------- ----------
1 1
2 2
3 3
4 4
6 6
SQL> select * from mv_x ;
C1 C2
---------- ----------
1 1
2 2
3 3
现在来看看M$LOG
table的内容
SQL> col m_row$$ for a18
SQL> select * from mlog$_x ;
M_ROW$$ SNAPTIME$ D O CHANGE_VEC XID$$
------------------ --------- - - ---------- ----------------------------
AAGKh/AAAAAJJWnAAD 01-JAN-00 I N FE 3659458165104006
AAGKh/AAAAAJJWnAAE 01-JAN-00 I N FE 44754731750395757
AAGKh/AAAAAJJWnAAE 01-JAN-00 U U 06 12948119511653544
AAGKh/AAAAAJJWnAAE 01-JAN-00 U N 06 12948119511653544
我现在有 4 行,2 行用于插入,1 行用于字段 C1,另一行用于字段 C2,它们实际上是同一事务(字段 XID$$
)
我希望它能阐明当您选择 ROWID 或 PRIMARY KEYY 时如何填充 MLOG$ table。请注意,使用主键的物化视图日志 tables 也有 rupd$_
tables。 rupd$_ table 支持可更新的物化视图,这只能在具有主键的日志 tables 上实现。