解決物化檢視ORA-12034'實體化檢視日誌比上次重新整理後的內容新'的問題

531968912發表於2016-12-16
有個應用想使用物化檢視複製資料,為了應對將來可能遇到的問題,先做些異常測試。
 
搭建使用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,不再報錯了。

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

相關文章