update操作會產生幾條mlog$日誌?

space6212發表於2019-03-07
我們知道,在快速重新整理物化檢視中,源表必須建立物化檢視日誌來記錄源表資料的變化,從而使得物化檢視能夠快速重新整理。
今天以前一位同事提出這樣一個問題:做一個update操作會產生兩個mlog$日誌。這與我印象中產生一條記錄不同。
下面重現這個過程:


首先建立測試資料表:
SQL> create table k(id int primary key,name varchar2(10));

Table created

SQL> create materialized view log on k;

Materialized view log created

SQL> insert into k values(1,'suk');

1 row inserted

SQL> commit;

Commit complete

SQL> create materialized view mv_t as select * from k;

Materialized view created


SQL> select * from mlog$_k;

ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
---------- ----------- --------- --------- ----------------------

SQL> select * from mv_t;

ID NAME
--------------------------------------- ----------
1 suk

--執行一個更新操作
SQL> update k set name='new' where id=1;

1 row updated

SQL> select * from mlog$_k;

ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
---------- ----------- --------- --------- ---------------------
1 4000-1-1 U U 04

--產生一條mlog記錄,DML型別為U

SQL> rollback;

Rollback complete

SQL> select * from mlog$_k;

ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
---------- ----------- --------- --------- ---------------------

--再更新一條記錄,不過這次更新內容包含主鍵
SQL> update k set name='new',id=2 where id=1;

1 row updated

SQL> select * from mlog$_k;

ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
---------- ----------- --------- --------- --------------------
1 4000-1-1 D O 00
2 4000-1-1 I N FF


--可以看出,更新列包含主鍵的話會產生2條mlog記錄。在這種情況下,一個update操作實際上是由一個DELETE操作和一個INSERT操作組成的。
--其實oracle這樣做有它的道理,如果MV是基於主鍵重新整理的,如果主鍵被update了,如果它不記錄下來原來主鍵ID的話,MV段就不知道那條記錄被update了
--那麼是不是更新內容包含主鍵的話都會產生2條mlog記錄呢?再看看下面的測試:

SQL> rollback;

Rollback complete

SQL> select * from mlog$_k;

ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
---------- ----------- --------- --------- --------------------

--更新主鍵,但是鍵值與之前一樣
SQL> update k set name='new',id=1 where id=1;

1 row updated

SQL> select * from mlog$_k;

ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
---------- ----------- --------- --------- ---------------------
1 4000-1-1 U U 04

--可以看到,oracle還是比較聰明的,已經把這種更新情況考慮進去了
--這種方式下,它實際上與更新非主鍵產生操作的mlog是一樣的

總結:
1、更新列都是非主鍵時
每更新一條記錄,在MLOG$會產生一個型別為U的記錄。
2、更新列包含主鍵時
如果鍵值變化,每更新一條記錄,在MLOG$會產生兩條記錄:D和I。
如果鍵值不發生變化,每更新一條記錄,在MLOG$會產生一個型別為U的記錄。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/231499/viewspace-63797/,如需轉載,請註明出處,否則將追究法律責任。

相關文章