0

我在 oracle 11.2.0.3 中有一个表,我想在重做日志中捕获它。问题是它有一个 sdo_geometry 字段。这是我无法更改的旧表。但好消息是我不需要那个 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;

当我进行更新并查看重做日志时,问题就会出现。我没有看到更新语句,而是看到了删除和插入语句。由于我使用的是主键,我希望看到更新语句。

有谁知道我需要做什么来确保我在重做日志中看到更新语句。

谢谢

4

1 回答 1

0

我认为您误解了 a redologstores 的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正常显示为任何其他DML操作。所以,很明显,只要操作是在 Logging 模式下完成的,或者数据库处于 FORCE LOGGING MODE 下,REDO 文件就会存储任何更新操作,在这种情况下,无论操作是什么模式,因为它总是会存储。SQL_REDOV$LOGMNR_CONTENTS

物化视图日志

让我们像您在问题中所做的那样创建 amaterialized view log和 a 。materialized view但是,为了验证 MLOG$ 表的内容,我将按需进行刷新,而不是在提交时进行。

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$表格的内容

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

您看不到UPDATEonDMLTYPE$$的原因是您在物化视图创建中选择 Primary Key 作为 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表格的内容

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$ 表。请注意,使用主键的物化视图日志表也有rupd$_表。rupd$_ 表支持可更新的物化视图,这仅适用于具有主键的日志表。

于 2020-08-08T20:51:26.687 回答