我们都知道,要创建快速刷新的物化视图,必须先在MASTER SITE端创建物化视图日志。这里介绍一下Mview Log 的结构与江门NGBOSS和之前来电三期中出现的ORA-12034 materialized view log younger than last refresh问题的原因。
我们先来看一下物化视图日志的结构含义和用途:物化视图日志的名称为MLOG$_后面跟基表的名称,如果表名的长度超过20位,则只取前20位,当截短后出现名称重复时,Oracle会自动在物化视图日志名称后面加上数字作为序号。
物化视图日志的建立可以指定为PRIMARY KEY、ROWID、和OBJECT ID几种类型,同时还可以指定SEQUENCE或明确指定列名。每种物化视图的结构都会有一些差异,不过它们都会包含以下列:
SNAPTIME$$:用于表示刷新时间。
DMLTYPE$$:用于表示DML操作类型,I表示INSERT,D表示DELETE,U表示UPDATE。
OLD_NEW$$:用于表示这个值是新值还是旧值。(N)表示新值,(O)表示旧值,U表示UPDATE操作。
CHANGE_VECTOR$$表示修改矢量,用来表示被修改的是哪个或哪几个字段。
物化视图日志默认为PRIMARY KEY,这种类型的物化视图日志中会包含主键列。
如果WITH后面跟了ROWID,则物化视图日志中会包含:
M_ROW$$:用来存储发生变化的记录的ROWID。
如果WITH后面跟了OBJECT ID,则物化视图日志中会包含:
SYS_NC_OID$:用来记录每个变化对象的OBJECT ID。
如果WITH后面跟了SEQUENCE,则物化视图日子中会包含:
SEQUENCE$$:给每个操作一个SEQUENCE号,从而保证刷新时按照顺序进行刷新。
如果WITH后面跟了一个或多个COLUMN名称,则物化视图日志中会包含这些列。
官方解释:
OBJECT ID:Specify OBJECT ID to indicate that the system-generated or user-defined object identifier of every modified row should be recorded in the materialized view log.
Restriction on OBJECT ID:You can specify OBJECT ID only when creating a log on an object table, and you cannot specify it for storage tables.
PRIMARY KEY:Specify PRIMARY KEY to indicate that the primary key of all rows changed should be recorded in the materialized view log.
ROWID:Specify ROWID to indicate that the rowid of all rows changed should be recorded in the materialized view log.
SEQUENCE:Specify SEQUENCE to indicate that a sequence value providing additional ordering information should be recorded in the materialized view log. Sequence numbers are necessary to support fast refresh after some update scenarios.[@more@]接下来我们看一下物化视图日志中的内容:
SQL> create table t_ty(pid number(2),pname varchar2(20),constraint t_ty_pk primary key(pid));
Table created.
SQL> create materialized view log on t_ty;
Materialized view log created.
SQL> desc mlog$_t_ty;
Name Null? Type
----------------------------------------- -------- ----------------------------
PID NUMBER(2)
SNAPTIME$$ DATE
DMLTYPE$$ VARCHAR2(1)
OLD_NEW$$ VARCHAR2(1)
CHANGE_VECTOR$$ RAW(255)
XID$$ NUMBER
这里默认是with primary key的物化视图日志,所以这里把主键字段pid加到物化视图日志中来,其他类型的物化视图日志会换成m_row$$、sys_nc_oid$字段。这里如果with中加入sequece或者指定一个或者多个字段,物化视图日志中就会包含SEQUENCE$$或者这些指定的列。下面看一下对表进行增、删、改后物化视图日志的内容:
SQL> insert into t_ty values(1,'ty');
1 row created.
SQL> insert into t_ty values(2,'snc');
1 row created.
SQL> update t_ty set pname='shsnc' where pid=2;
1 row updated.
SQL> update t_ty set pid=3 where pid=1;
1 row updated.
SQL> select pid,snaptime$$ ,dmltype$$,old_new$$,change_vector$$ from mlog$_t_ty;
PID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
----- ------------------------- -------------- ------------------ -----------------------
1 4000-01-01 00:00:00 I N FE
2 4000-01-01 00:00:00 I N FE
2 4000-01-01 00:00:00 U U 04
1 4000-01-01 00:00:00 D O 00
3 4000-01-01 00:00:00 I N FF
可以看到普通字段的更新会在日志中记录一条更新记录,如果是更新主键字段,则会先删除后插入一条新的记录。DMLTYPE$$、OLD_NEW$$这两个字段上面已经介绍过了,结合这里的日志内容可以一目了然。这里先介绍一下CHANGE_VECTOR$$字段,SNAPTIME$$字段在后面结合江门NGBOSS和之前来电三期中出现的ORA-12034 materialized view log younger than last refresh一块介绍。
CHANGE_VECTOR$$列是RAW类型,用于记录修改矢量,上面有四个值FE、04、00、FF。插入操作:插入操作用FE表示,如果表中列的个数大于8个,则在右边添加FF即FEFF,大于16个时,则在后面添加FFFF即FEFFFF。其实oracle是bit来计算列是个数,大于8个列时,十六进制的FF转换成二进制11111111已经无法表示全部的列的状态了。
删除操作:删除操作则用00表示,如果列的个数大于8个时则在后面添加00,以此类推。更新操作:更新操作分为主键列更新和非主键列的更新,如果是更新主键列,在日志中记录一条删除和一条插入,这时插入操作的FE换成FF,其他的生成方式没变。当更新某些列时,如果更新第一个列则02,即00000010,如果列的个数则在后面补充00,如果更新第二个列则为04,即00000100,即第几个列被更新则对应的二进制+1位由0变为1;比如第三和第五位更新则为00101000即十六进制的28。这里需要注意的是,如果表的列大于8个,则在右边补充两位,但在计算时右边两位为高位,比如第11和第17列被更新则为00000010 00001000 00000000即十六进制的000802。
下面结合江门NGBOSS和之前来电三期中出现的ORA-12034 materialized view log younger than last refresh介绍一下SNAPTIME$$字段,这个字段其实也是物化视图刷新最主要的依据。
先描述一下江门NGBOSS和之前来电三期的场景和出现的问题,来电三期是从管理节点分别向两个呼叫节点分发数据,物化视图每10秒中刷新一次。江门NGBOSS是需要融合计费建一张物化视图到CRM生产用户下,后面由于测试需要另外在源表上建一张物化视图到CRM的性能用户下,刷新时间均为1分钟。从场景和需求来看都是没有问题的,但是在创建物化视图时,却都出现了ORA-12034 materialized view log younger than last refresh。经过分析发现两次问题出现的场景有一个共同特点,那就是物化视图日志都是被重建过。了解物化视图刷新的原理就可以很清楚的知道问题的原因了,而物化视图刷新的机制恰恰是隐藏在物化视图的SNAPTIME$$字段中。下面结合例子,其实也就是上面的场景重现来介绍SNAPTIME$$字段。
创建物化视图基表并插入数据:
SQL> create table t_mv(pid number(4),pname varchar2(20),pdept varchar2(30), constraint pk_t_mv primary key(pid));
Table created.
SQL> declare
2 begin
3 for i in 1..99 loop
4 insert into t_mv values (i,'snc'||i,'咨询测试部'||i);
5 commit;
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> create materialized view log on t_mv;
Materialized view log created.
模拟第一个物化视图端创建物化视图,创建一个1小时的物化视图:
SQL> create materialized view mv_1
2 refresh fast
3 start with sysdate
4 next sysdate + 1/24 /*1h*/
5 with primary key
6 as
7 select * from t_mv;
Materialized view created.
SQL> insert into t_mv values (21,'shsnc','咨询');
1 row created.
这里看一下SNAPTIME$$字段
SQL> select snaptime$$ from mlog$_t_mv;
SNAPTIME$$
-------------------
4000-01-01 00:00:00
创建第二个物化视图
SQL> create materialized view mv_2
2 refresh fast
3 start with sysdate
4 next sysdate + 1/24 /*10s*/
5 with primary key
6 as
7 select * from t_mv;
Materialized view created.
SNAPTIME$$字段的值已经修改为第二个物化视图创建的时间(这里也可以解释后面为什么会出现ORA-12034的错误),这是因为第一个物化视图的最后刷新时间比第二个物化创建时间早,用于第一个物化视图刷新。
SQL> select snaptime$$ from mlog$_t_mv;
SNAPTIME$$
-------------------
2012-05-06 01:23:34
SQL> select distinct owner, name mview, master_owner master_owner, last_refresh from dba_mview_refresh_times;
OWNER MVIEW MASTER_OWNER LAST_REFRESH
---------- -------------- ------------------------ ---------------------
TY MV_1 TY 06-MAY-12 01:19:10
TY MV_2 TY 06-MAY-12 01:23:35
SQL> insert into t_mv values (22,'shsnc','咨询');
1 row created.
SQL> select snaptime$$ from mlog$_t_mv;
SNAPTIME$$
---------------------
06-MAY-12 01:23:34
01-JAN-00 00:00:00
这里为了清晰,手动刷新物化视图,模拟物化视图正常刷新。
SQL> exec dbms_mview.refresh('MV_1','F');
PL/SQL procedure successfully completed.
SQL> select snaptime$$ from mlog$_t_mv;
SNAPTIME$$
---------------------
06-MAY-12 01:33:04
SQL> select distinct owner, name mview, master_owner master_owner, last_refresh from dba_mview_refresh_times;
OWNER MVIEW MASTER_OWNER LAST_REFRESH
---------- -------------- ------------------------ ---------------------
TY MV_1 TY 06-MAY-12 01:33:04
TY MV_2 TY 06-MAY-12 01:23:35
SQL> select snaptime$$ from mlog$_t_mv;
SNAPTIME$$
---------------------
06-MAY-12 01:33:04
SQL> exec dbms_mview.refresh('MV_2','F');
PL/SQL procedure successfully completed.
SQL> select distinct owner, name mview, master_owner master_owner, last_refresh from dba_mview_refresh_times;
OWNER MVIEW MASTER_OWNER LAST_REFRESH
---------- -------------- ------------------------ ---------------------
TY MV_1 TY 06-MAY-12 01:33:04
TY MV_2 TY 06-MAY-12 01:38:47
SQL> select snaptime$$ from mlog$_t_mv;
no row selected
这里可以很清楚的看到多个物化视图都是根据同一个物化视图日志来进行刷新的,根据对物化视图日志和物化视图的最后刷新时间来对物化视图刷新进行管理,当基于基表的所有物化视图都刷新后,物化视图日志就会被清除。
SQL> drop materialized view log on t_mv;
Materialized view log dropped.
SQL> exec dbms_mview.refresh('MV_1','F');
BEGIN dbms_mview.refresh('MV_1','F'); END;
*
ERROR at line 1:
ORA-23413: table "TY"."T_MV" does not have a materialized view log
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2563
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2776
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2745
ORA-06512: at line 1
SQL> select distinct owner, name mview, master_owner master_owner, last_refresh from dba_mview_refresh_times;
OWNER MVIEW MASTER_OWNER LAST_REFRESH
---------- -------------- ------------------------ ---------------------
TY MV_1 TY 06-MAY-12 01:48:41
TY MV_2 TY 06-MAY-12 01:38:47
当物化视图日志被删除,此时在刷新物化视图,会报找不到物化视图日志,但是此时物化视图的最后刷新时间也会修改。
SQL> create materialized view log on t_mv;
Materialized view log created.
SQL> exec dbms_mview.refresh('MV_1','F');
BEGIN dbms_mview.refresh('MV_1','F'); END;
*
ERROR at line 1:
ORA-12034: materialized view log on "TY"."T_MV" younger than last refresh
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2563
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2776
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2745
ORA-06512: at line 1
物化视图日志时间不能小于物化视图的最后刷新时间。当我们重新创建物化视图日志,此时物化视图日志时间为4000-01-01 00:00:00,但是物化视图的最后刷新时间为06-MAY-12 01:48:41,此时就会报ORA-12034: materialized view log younger than last refresh。
==========End========================================================

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24930246/viewspace-1058178/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/24930246/viewspace-1058178/

物化视图日志结构与ORA-12034 Mview log younger than last refresh相关推荐

  1. Oracle物化视图与物化视图日志

    文章目录 物化视图 物化视图与普通视图的区别 创建一个存放person的表 创建一个存放person的address的表 初始化数据 创建物化视图的语句 1.build [immediate|defe ...

  2. Oracle 如何根据物化视图日志快速刷新物化视图 (不积跬步,无以至千里)

    Oracle物化视图的快速刷新机制是通过物化视图日志完成的.Oracle如何通过一个物化视图日志就可以支持多个物化视图的快速刷新呢,本文简单的描述一下刷新的原理. 首先,看一下物化视图的结构: SQL ...

  3. mysql 物化视图 更新_物化视图的快速刷新测试与物化视图日志

    前言:一般在创建物化视图的时候,在数据量不大的时候,刷新的方式都是采用完全刷新的.随着系统的使用一些物化视图的源表的数据量在不断的增长,原本采用完全方式几秒就能刷新完成的物化视图,现在需要等待很久的时 ...

  4. 物化视图是否可以exp导出_物化视图导出导入可能导致物化视图日志的失效

    SQL> create user yang identified by yang; 用户已创建. 已用时间:  00: 00: 00.10 SQL> grant resource,conn ...

  5. oracle including new values,物化视图日志加不加INCLUDING NEW VALUES有什么影响

    满意答案 ap.jil 2016.06.30 采纳率:58%    等级:9 已帮助:213人 NEW VALUES Clause The NEW VALUES clause lets you det ...

  6. oracle视图查询机制,物化视图及日志内部机制的一点研究

    Oracle物化视图的快速刷新机制是通过物化视图日志完成的.Oracle如何通过一个物化视图日志就可以支持多个物化视图的快速刷新呢,本文简单的描述一下刷新的原理. 首先,看一下物化视图的结构: SQL ...

  7. oracle雾化试图_ORACLE物化视图具体解释

    一.物化的一般使用方法物化视图是一种特殊的物理表,"物化"(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,不论什么对视图的查询,oracle ...

  8. oracle 物化视图、中间表的方案

    物化视图 有个项目因为有比较多的查询汇总,考虑到速度,所以使用了物化视图.简单的把用到的给整理了下.先看简单创建语句: create materialized view mv_materialized ...

  9. 数据库链、物化视图、高级复制方面

    数据库链相关内容: JOB自动执行出错,但手工执行正常--浅谈job和database link的一个特点 :描述了匿名数据库链的特点,以及和JOB配合使用时会出现的情况. 通过数据库链执行DDL语句 ...

最新文章

  1. 5、CC2541芯片中级教程-OSAL操作系统(PWM+看门狗)
  2. 深度学习(十六)基于2-channel network的图片相似度判别-CVPR 2015
  3. crypto-RSA-常用解密代码块
  4. CAS教程-第一篇-CAS单点登录原理解析
  5. html文本域 高度自适应,textarea高度自适应,textarea随着内容高度变化
  6. JavaScript 中的string 方法
  7. 自动化部署工具PUPPET介绍
  8. lucene 增量 全量 更新索引_10年+,阿里沉淀出怎样的搜索引擎?
  9. spark sql 性能优化
  10. 拖动卡顿_教你4招,让你的ps永不卡顿
  11. 疯狂游戏-研发一面-校招面经
  12. 利用 yEd 软件做元数据管理
  13. 告别996之Stream学习总结
  14. 人工智能 —— 语义网络推理
  15. MySQL字段名获取
  16. 7-3 拍7令三 (100 分)
  17. Docker部署Jenkins服务
  18. windows企微应用双开/多开
  19. 基于Basys2的分秒计时器的设计
  20. PaddleNLP实战:应用NeZha模型做微博情感6分类

热门文章

  1. Yii2 中添加全局函数
  2. 二十年后我发明了保姆机器人作文_未来的保姆机器人作文
  3. 我的世界服务器娘怎么修改配置,转【教学】Pixelmon配置文件修改指南
  4. 郭台铭为什么如此有魄力?
  5. linux对已有分区进行扩容
  6. android java pbo_Android OpenGL ES 3.0 PBO而不是glReadPixels()
  7. oracle导seq_ORACLE SEQUENCE用法(转)
  8. arm linux运行安卓app,Android x86 下运行纯ARM版APP
  9. 一个计算机毕业生的求职经验
  10. 南京烽火星空——企业移动信息化的“大白”