物化视图多用户数据仓库,数据复制等环境,自己接触的还是主要是用于简单的查询,让其利用所谓的空间换取时间,提高系统的性能。刷新机制和查询重写是物化视图最重要的功能。
下面结合自己碰到的一则物化视图的ora处理来简要说一下物化视图和日志和fast刷新机制。
mview_tab01表是主表,下面的mv01是mview_tab01的物化视图。先来看看下面的物化视图日志的表的结构。
SQL> alter table mview_tab01 add primary key(id);
Table altered
SQL> create materialized view log on mview_tab01;
Materialized view log created
SQL> create materialized view mv01
2 build immediate
3 refresh fast
4 start with sysdate
5 next sysdate+5/1440
6 enable query rewrite
7 as
8 select * from mview_tab01;
Materialized view created
SQL> insert into mview_tab01 values(5,'ORCL');
1 row inserted
SQL> commit;
Commit complete
SQL> col change_vector$$ for a10
SQL> col change_vector$$ for a10
SQL> select * from mlog$_mview_tab01;
ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VEC XID$$
---------- ----------- --------- --------- ---------- ----------
5 4000/1/1 I N FE 2815995307
SQL> insert into mview_tab01 values(8,'ORACLE');
1 row inserted
SQL> select * from mlog$_mview_tab01;
ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VEC XID$$
---------- ----------- --------- --------- ---------- ----------
5 4000/1/1 I N FE 2815995307
8 4000/1/1 I N FE 1.97036349
SQL> commit;
Commit complete
Dbms_mview.refresh刷新一下物化视图,然后再查看物化视图的日志。
SQL> select * from mlog$_mview_tab01;
ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VEC XID$$
---------- ----------- --------- --------- ---------- ----------
物化视图已经刷新修改,且物化视图的日志也已经再次清空。
SQL> delete from mview_tab01 where id=8;
1 row deleted
SQL> select * from mlog$_mview_tab01;
ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VEC XID$$
---------- ----------- --------- --------- ---------- ----------
8 4000/1/1 D O 00 1.12602016
SQL> execute dbms_mview.refresh('MV01');
PL/SQL procedure successfully completed
SQL> select * from mlog$_mview_tab01;
ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VEC XID$$
---------- ----------- --------- --------- ---------- ----------
这里注意一下mlog$_mview_tab01视图的column的含义
SQL> desc mlog$_mview_tab01;
Name Type Nullable Default Comments
--------------- ----------- -------- ------- --------
ID NUMBER Y
SNAPTIME$$ DATE Y
DMLTYPE$$ VARCHAR2(1) Y
OLD_NEW$$ VARCHAR2(1) Y
CHANGE_VECTOR$$ RAW(255) Y
XID$$ NUMBER Y
上述是主键物化视图的日志,id主键,snaptime$$刷新时间,dmltype$$表示dml操作类型,上述的I表示insert,d表示delete,change_vector$$修改矢量,用于表示修改的字段值是哪些,不过内部算法比较复杂暂时不做深究。
如果是rowid和object的物化视图日志的视图有少许不同,这里就不列举。
物化视图之所以能fast refresh是利用视图的日志来传递信息到物化视图中更新,refresh前物化视图会先根据基表是否发生变化,如果不发生变化,即使物化视图日志有记录信息,物化视图也不会刷新数据。
先读取基表是否发生变化是refresh的第一步,然后才会传递日志记录到物化视图刷新数据。
今天碰到一则materialized view fast的案例,物化视图无法刷新,手动刷新也出现下列错误。
SQL> execute dbms_mview.refresh('MV_ARTICLE');
BEGIN dbms_mview.refresh('MV_ARTICLE'); END;
*
ERROR at line 1:
ORA-12034: materialized view log on "DESKTOP"."ARTICLE" younger than last refresh
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2255
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2461
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2430
ORA-06512: at line 1
[oracle@server119 ~]$ oerr ora 12034
12034, 0000, "materialized view log on "%s"."%s" younger than last refresh"
// *Cause: The materialized view log was younger than the last refresh.
// *Action: A complete refresh is required before the next fast refresh.
根据物化视图的刷新机制会刷新snaptime$$大于物化视图上次refresh时间的记录(上次refresh的时间可以查看user_mviews等视图),刷新完成后将修改数据字典中last_refresh_date刷新时间.下次refresh就会根据snaptime$$l来refresh上次的刷新时间后的数据,也就是记录到mlog$_mview_tab01的日志记录信息,并清除已经refresh的snaptime$$的信息记录。
(不过上述的ora错误出现时,mlog视图中会出现早于上次refresh的snaptime记录,这个也是错误的进一步表象)
根据提示materialized view log比上次的article刷新还早,那么再次刷新时要利用view log的,由于日志snaptime$$早于上次refresh导致无法利用log刷新,此种情况可以重建物化视图或者完全刷新来解决,多发生于对物化视图和基表,物化视图日志做过相应的ddl操作引起。
[@more@]来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/25362835/viewspace-1058718/ ,如需转载,请注明出处,否则将追究法律责任。