Проблемы с журналами повторного выполнения Oracle 11.2.0.3

У меня есть таблица в 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;

Проблема обнаруживается, когда я делаю обновление и просматриваю журналы повторов. Вместо оператора обновления я вижу операторы удаления и вставки. Поскольку я использую первичный ключ, я ожидаю увидеть оператор обновления.

Кто-нибудь знает, что мне нужно сделать, чтобы убедиться, что я вижу оператор обновления в журналах повтора.

Благодарность

1 ответ

Решение

Я думаю, вы неправильно понимаете, что за redolog магазины с чем materiliazed view log делает.

Попробуем провести тест для обоих сценариев:

  • LogMiner для проверки содержимого файлов журнала повторного выполнения, что мы можем увидеть с помощью v$LOGMNR_CONTENTS.
  • Пример материализованного представления операций журнала и обновления

Версия Oracle: 12.2

RedoLog Содержание

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 операция в SQL_REDO столбец V$LOGMNR_CONTENTS. Итак, очевидно, что файлы REDO хранят любую операцию обновления, пока операция выполняется в режиме ведения журнала, или база данных находится в режиме FORCE LOGGING MODE, и в этом случае не имеет значения, в каком режиме выполняется операция, потому что она всегда будет хранится.

Материализованный журнал просмотра

Создадим materialized view log и 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

Причина, по которой вы не видите UPDATE на DMLTYPE$$потому что вы выбираете первичный ключ как предложение WITH при создании материализованного представления. В этом случае в столбце будут отображаться только D или I.DMLTYPE$$, но когда это обновление, вы получите две строки с одинаковым идентификатором транзакции (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$$)

Надеюсь, он проясняет, как заполняются таблицы MLOG$, когда вы выбираете ROWID или PRIMARY KEYY. Обратите внимание, что таблицы журнала материализованного представления, использующие первичные ключи, также имеютrupd$_таблицы. Таблица rupd$_ поддерживает обновляемые материализованные представления, которые возможны только в таблицах журналов с первичными ключами.

Другие вопросы по тегам