我们知道,在快速刷新物化视图中,源表必须建立物化视图日志来记录源表数据的变化,从而使得物化视图能够快速刷新。
今天以前一位同事提出这样一个问题:做一个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/,如需转载,请注明出处,否则将追究法律责任。