物化檢視快速重新整理與ORA-00001
今天上班收到告警郵件,是一個定時重新整理物化檢視的job引起的錯誤:
ORA-00001: unique constraint (NDMAIN.I_GPO_USR_USER_IDXU_CODE) violated
檢查兩邊約束,發現完全一致,經過10046跟蹤,發現根本原因。
下面舉例重現錯誤:
SQL> create table test(id int,code varchar2(10));
Table created
SQL> alter table test add constraint pk_test primary key(id);
Table altered
SQL> alter table test add constraint un_test_code unique(code);
Table altered
SQL> create materialized view log on test;
Materialized view log created
SQL> insert into test values(1,'code1');
1 row inserted
SQL> insert into test values(2,'code2');
1 row inserted
SQL> commit;
Commit complete
--建立快速重新整理的物化檢視
SQL> create materialized view mv_test refresh fast as select * from test;
Materialized view created
SQL> alter table mv_test add constraint un_mv_test_code unique(code);
Table altered
SQL> create materialized view log on mv_test;
Materialized view log created
--把code1和code2對換
SQL> update test set code='code3' where id=1;
1 row updated
SQL> update test set code='code1' where id=2;
1 row updated
SQL> update test set code='code2' where id=1;
1 row updated
SQL> commit;
Commit complete
SQL> select * from mlog$_test;
ID SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
---------- ----------- --------- --------- --------------------
1 2008-3-31 2 U U 04
2 2008-3-31 2 U U 04
1 2008-3-31 2 U U 04
--快速重新整理物化檢視
SQL> exec dbms_mview.refresh('mv_test')
begin dbms_mview.refresh('mv_test'); end;
ORA-12008: 實體化檢視的重新整理路徑中存在錯誤
ORA-00001: 違反唯一約束條件 (SUK.UN_MV_TEST_CODE)
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
從後臺跟蹤的10046trade檔案可以看到下面的資訊:
--原始trace內容
=====================
PARSING IN CURSOR #18 len=64 dep=2 uid=29 ct=6 lid=29 tim=10217293845 hv=3019709084 ad='204ef138'
UPDATE "SUK"."MV_TEST" SET "ID" = :1,"CODE" = :2 WHERE "ID" = :1
END OF STMT
PARSE #18:c=0,e=172,p=0,cr=0,cu=0,mis=1,r=0,dep=2,og=1,tim=10217293838
BINDS #18:
kkscoacd
Bind#0
acdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
acflg=13 fl2=0001 frm=00 csi=00 siz=24 ff=0
kxsbbbfp=0789b014 bln=22 avl=02 flg=09
value=1 --ID的值
Bind#1
acdty=01 mxl=32(10) mxlc=00 mal=00 scl=00 pre=00
acflg=13 fl2=0001 frm=01 csi=852 siz=32 ff=0
kxsbbbfp=0789b02c bln=32 avl=05 flg=09
value="code2" --code的值
Bind#2
No oacdef for this bind.
--格式化後的trace內容
UPDATE "SUK"."MV_TEST" SET "ID" = :1,"CODE" = :2
WHERE
"ID" = :1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.01 0.00 0 1 5 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.01 0.00 0 1 5 0
--只執行一次
分析以上內容可以得到如下結論:對ID=1的資料重新整理只做了一次。
其實oracle這樣做是很有道理的:如果oracle完全根據MLOG$記錄的日誌順序重新整理資料,對於那些被多次更新的資料,不得不重新整理多次,這對效率影響很大。
實際上,MLOG$只是記錄對基表的那些列執行了那些操作,並不記錄更新前後的值,所以無法也沒必要完全重演主表的資料更新歷史,所以,對於相同主鍵的資料執行了多次更新,只需要根據主鍵和主表同步一次資料即可實現與主表的資料同步。
這個機制也是導致文中開頭錯誤的根源:
mv_test重新整理資料時,對於ID=1的資料,只執行一次資料重新整理:update mv_test set name='code2' where id=1;
此時,mv_test中id=2的name='code2'(還沒有變成code1),這必然違反code上的唯一性約束。
為了避免這個錯誤,可以有以下解決方法:
1、如果是唯一性約束,把這個約束設定為延遲性約束(在提交時才檢驗資料的合法性)
2、如果是唯一性索引,則先建立一個普通索引,然後用這個索引建立一個延遲唯一性約束。
3、如果不考慮效能或者執行計劃問題,則物化檢視端的約束都可以去掉,再主表保證資料的合法性即可。
這個錯誤只會出現在快速重新整理中,完全重新整理是不存在這樣的問題的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/231499/viewspace-220514/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- StarRocks 物化檢視重新整理流程及原理
- StarRocks 物化檢視重新整理流程和原理
- Postgres使用trigger自動重新整理物化檢視
- 物化檢視
- hg_job配置定時重新整理物化檢視
- 物化檢視如何快速完成資料聚合操作?
- 物化檢視(zt)
- calcite物化檢視詳解
- Oracle普通檢視和物化檢視的區別Oracle
- 資料庫的物化檢視資料庫
- 物化檢視分割槽實驗
- 物化檢視幾個知識點
- ClickHouse 物化檢視學習總結
- Oracle物化檢視的建立及使用(二)Oracle
- Oracle物化檢視的建立及使用(一)Oracle
- ClickHouse 效能優化?試試物化檢視優化
- ClickHouse效能優化?試試物化檢視優化
- 基於ROWID更新的物化檢視測試
- 使用Materialise物化檢視解耦微服務架構解耦微服務架構
- 火山引擎ByteHouse:如何最佳化ClickHouse物化檢視能力?
- 物化檢視日誌無法正常清除的解決方法
- 資料泵匯出匯入物化檢視(ORA-39083)
- 【MVIEW】Oracle通過物化檢視同步表資料及簡介ViewOracle
- 基於圖神經網路的動態物化檢視管理神經網路
- 用exp、imp遷移包含物化檢視日誌的資料
- 【SQL】Oracle查詢轉換之物化檢視查詢重寫SQLOracle
- 快速檢視dll的publickeytoken
- 使用SpringBoot+PostgreSQL物化檢視實現微服務設計模式 - vinsguruSpring BootSQL微服務設計模式
- 兼顧高效能與低成本,淺析 Apache Doris 非同步物化檢視原理及典型場景Apache非同步
- ORACLE 物化檢視維護中相關基表發生欄位長度類DDL變更後需要重建或者全量重新整理Oracle
- 快速影像檢視器:EdgeView 4 for MacViewMac
- EdgeView 3 for Mac(快速影像檢視器)ViewMac
- 如何快速檢視 Mac 的溫度Mac
- 汽車之家基於 Apache Flink 的跨資料庫實時物化檢視探索Apache資料庫
- [20230225]12c Real-time materialized view 實時物化檢視的應用.txtZedView
- [重慶思莊每日技術分享]-建立物化檢視時出現ORA-7445錯誤
- 一個快速檢視trace的小指令碼指令碼
- 快速檢視 Mac 應用程式是否與 M1相容的方法Mac