有个应用想使用物化视图复制数据,为了应对将来可能遇到的问题,先做些异常测试。
搭建使用rowid 创建物化视图 实现快速更新的环境:
创建用户a, b
grant connect to a;
grant resource to a;
grant connect to b;
grant resource to b;
grant drop any materialized view to b;
grant create materialized view to b;
grant select any dictionary to a;
create table a.test1 as select rownum as bh ,t.*
from user_tablespaces t where rownum<2
演示数据:
declare
j number;
i number;
begin
select max(bh) into j from test1;
-- delete from test1 where rownum<1000
-- alter table test1 move
-- update test1 set logging='abcd' where rownum<100
for i in 1 .. 1000 loop
insert into test1
select j i, t.* from user_tablespaces t where rownum<5;
commit;
end loop;
end;
查看变化:
select '数据量 '||count(0) from test1 union
select '需更新量 '||count(0) from mlog$_test1;
为实现快速更新,创建物化视图日志,授权:
drop materialized view log on test1;
create materialized view log on test1 with rowid;
grant select on a.test1 to b;
grant select on a.mlog$_test1 to b;
创建物化视图:
drop materialized view mv_test1;
create materialized view mv_test1
refresh fast
with rowid
as select * from a.test1;
开始测试
用 truncate table test1后 刷新物化视图时提示:
ora-12034: "a"."test1" 上的实体化视图日志比上次刷新后的内容新
ora-06512: 在 "sys.dbms_snapshot", line 2255
ora-06512: 在 "sys.dbms_snapshot", line 2461
ora-06512: 在 "sys.dbms_snapshot", line 2430
ora-06512: 在 line 2
解决:需要完全刷新,即 exec dbms_mview.refresh('mv_test1','cf');
truncate后 实体化视图日志表mlog$_test1 中的内容全空了
用alter table test1 move; 后 刷新物化视图时也报错:
第 1 行出现错误:
ora-12034: "a"."test1" 上的实体化视图日志比上次刷新后的内容新
ora-06512: 在 "sys.dbms_snapshot", line 2255
ora-06512: 在 "sys.dbms_snapshot", line 2461
ora-06512: 在 "sys.dbms_snapshot", line 2430
ora-06512: 在 line 1
解决:需要完全刷新,应该是因为使用了with rowid选项创建的物化视图。
如果修改了基表结构 (删除字段)报错:
ora-12008: 实体化视图的刷新路径中存在错误
ora-00904: "test1"."buffer_pool": 标识符无效
ora-06512: 在 "sys.dbms_snapshot", line 2255
ora-06512: 在 "sys.dbms_snapshot", line 2461
ora-06512: 在 "sys.dbms_snapshot", line 2430
ora-06512: 在 line 1
解决:按基表结构改正即可(如果兼容类型,仍可更新成功)
对物化视图 alter table mv_test1 move; 后报错:
ora-12008: 实体化视图的刷新路径中存在错误
ora-01502: 索引 'b.i_snap$_mv_test1' 或这类索引的分区处于不可用状态
ora-06512: 在 "sys.dbms_snapshot", line 2255
ora-06512: 在 "sys.dbms_snapshot", line 2461
ora-06512: 在 "sys.dbms_snapshot", line 2430
ora-06512: 在 line 1
解决:rebuild 这个索引即可
用 exec dbms_mview.explain_mview('mv_test1'); 分析时报错:
ora-30377: 未找到表 b.mv_capabilities_table
ora-00942: 表或视图不存在
ora-06512: 在 "sys.dbms_xrwmv", line 22
ora-06512: 在 "sys.dbms_snapshot", line 3008
ora-06512: 在 line 2
解决:???
一阵乱搞后 alert.log 中发现如下一个job 异常 正好综合使用一遍前面的异常处理方法,有信心。
errors in file d:\oracle\product\10.2.0\admin\orcl\udump\orcl_ora_2112.trc:
ora-12012: 自动执行作业 21 出错
ora-12031: 不能使用 "a"."t1" 上实体化视图日志中的主键列
ora-06512: 在 "sys.dbms_snapshot", line 2255
ora-06512: 在 "sys.dbms_snapshot", line 2461
ora-06512: 在 "sys.dbms_irefresh", line 683
ora-06512: 在 "sys.dbms_refresh", line 195
ora-06512: 在 line 1
解决:
这个job的what是 exec dbms_refresh.refresh('"sys"."mv_t1_pk"');
对象mv_t1_pk是个物化视图
创建a.t1上的物化视图日志 提示已有 看了一下结构 是用with rowid 选项创建的 删除,
t1也没主键 于是创建主键 用with primary key 重新创建物化视图日志
发现对象mv_t1_pk处于无效状态 重新编译后,手工刷新
sql> exec dbms_refresh.refresh('"sys"."mv_t1_pk"');
begin dbms_refresh.refresh('"sys"."mv_t1_pk"'); end;
ora-12034: "a"."t1" 上的实体化视图日志比上次刷新后的内容新
ora-06512: 在 "sys.dbms_snapshot", line 2255
ora-06512: 在 "sys.dbms_snapshot", line 2461
ora-06512: 在 "sys.dbms_irefresh", line 683
ora-06512: 在 "sys.dbms_refresh", line 195
ora-06512: 在 line 2
这就好办了,执行一次完全更新:
sql> exec dbms_mview.refresh('mv_t1_pk','c');
pl/sql procedure successfully completed
sql>
手工run那个job,不再报错了。
阅读(12231) | 评论(0) | 转发(0) |