小議物化檢視與基表資料不一致的消除(二)

dbhelper發表於2015-01-08

這篇文章主要討論如何透過修改物化檢視日誌來同步INSERT和DELETE操作。

小議物化檢視與基表資料不一致的消除(一):http://yangtingkun.itpub.net/post/468/326751


對於物化檢視和基表的差別,一共存在三種情況。記錄在基表中存在,但是在物化檢視中不存在;記錄在基表中不存在,但是在物化檢視中存在;記錄在基表和物化檢視中都存在,但是二者不一致。

前面兩種情況相當於DELETE和INSERT語句沒有應用到物化檢視中,而後面一種情況相當於UPDATE語句沒有應用到物化檢視中。

這裡先討論相對簡單的DELETE和INSERT的情況。如果物化檢視和基表的資料如下:

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T');

PL/SQL 過程已成功完成。

SQL> SELECT * FROM T;

ID NAME AGE
---------- ------------------------------ ----------
2 TEST 20
3 ABC 15
4 INSERT 30

SQL> SELECT * FROM MV_T;

ID NAME AGE
---------- ------------------------------ ----------
1 DELETE 10
2 TEST 20
3 ABC 15

基表中記錄1已經被刪除,而物化檢視中仍然存在。基表中插入了記錄4,而沒有同步到物化檢視中。

對於上面這兩種情況,只需要手工修改物化檢視日誌就可以實現物化檢視資料的同步:

SQL> INSERT INTO MLOG$_T VALUES (4, TO_DATE('4000-1-1', 'YYYY-MM-DD'), 'I', 'N', 'FE');

已建立 1 行。

SQL> INSERT INTO MLOG$_T VALUES (1, TO_DATE('4000-1-1', 'YYYY-MM-DD'), 'D', 'O', '00');

已建立 1 行。

SQL> COMMIT;

提交完成。

第一個欄位表示發生變化的記錄的ID。

第二個是時間戳填入4000年1月1日,表示任何物化檢視還沒有對這個記錄進行重新整理。

第三個欄位表示INSERT/UPDATE/DELETE。

第四個欄位表示新值(N)/舊值(O)/修改(U)。

最後一個欄位表示修改列的向量。用FE表示INSERT,用00表示DELETE。

關於物化檢視日誌欄位的詳細描述可以參考:http://yangtingkun.itpub.net/post/468/20498

關於物化檢視是如何利用物化檢視日誌進行快速重新整理的可以參考:http://yangtingkun.itpub.net/post/468/20584

修改MLOG後馬上重新整理並不會導致資料同步到物化檢視:

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T');

PL/SQL 過程已成功完成。

SQL> SELECT * FROM T;

ID NAME AGE
---------- ------------------------------ ----------
2 TEST 20
3 ABC 15
4 INSERT 30

SQL> SELECT * FROM MV_T;

ID NAME AGE
---------- ------------------------------ ----------
1 DELETE 10
2 TEST 20
3 ABC 15

SQL> SELECT * FROM MLOG$_T;

ID SNAPTIME$$ D O CHANGE_VECTOR$$
---------- ---------- - - ----------------------------------------
4 01-1月 -00 I N FE
1 01-1月 -00 D O 00

這是由於Oracle在快速重新整理的時候發現基表自上次重新整理完成後並未發生修改,因此根本沒有去讀取物化檢視日誌。

只要基表資料發生改變,下次物化檢視重新整理時,會自動將修改同步到物化檢視上:

SQL> UPDATE T SET NAME = 'ABC' WHERE ID = 3;

已更新 1 行。

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T');

PL/SQL 過程已成功完成。

SQL> SELECT * FROM T;

ID NAME AGE
---------- ------------------------------ ----------
2 TEST 20
3 ABC 15
4 INSERT 30

SQL> SELECT * FROM MV_T;

ID NAME AGE
---------- ------------------------------ ----------
2 TEST 20
3 ABC 15
4 INSERT 30

透過手工修改物化檢視日誌,物化檢視和基表資料同步完成。需要注意的是,這個方法適用於僅包含一個物化檢視的情況或者包含多個物化檢視且全部物化檢視都出現資料不一致的情況。

對於包含多個物化檢視,但是隻有個別物化檢視資料不一致的情況,需要對這種方法進行適當的改進。這裡就不詳細介紹了。

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

相關文章