清理物化視圖日誌步驟:
以scott用戶下的一張mview_1爲基表建立兩個物化視圖,然後unregister其中一個(EXEC DBMS_MVIEW.UNREGISTER_MVIEW('MING', 'TARGET_MVIEW_1', 'OGG1')。向基表中出入三條數據,提交後查看日誌表:
創建dblink
create database link scott_link_1
connect to scott
identified by oracle
using 'systest';
create database link scott_link_2
connect to scott
identified by oracle
using 'systest';
scott用戶創建物化視圖日誌:
SQL> sho user
USER is "SCOTT"
SQL> desc mview_1
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
NAME VARCHAR2(20)
SQL> create materialized view log on mview_1 with primary key;
Materialized view log created.
SQL> select table_name from user_tables where table_name like 'MLOG$%';
TABLE_NAME
------------------------------
MLOG$_MVIEW_1
創建物化視圖:
SQL> sho user
USER is "MING"
SQL> create materialized view target_mview_1 on prebuilt table refresh fast on demand with primary key start with sysdate next
2 to_date(concat(to_char(sysdate+1,'dd-mm-yyyy'),'10:25:00'),'dd-mm-yyyy hh24:mi:ss') as
3 select * from scott.mview_1@scott_link_1;
Materialized view created.
SQL> create materialized view target_mview_2 build immediate refresh fast on demand with primary key start with sysdate next
2 to_date(concat(to_char(sysdate+1,'dd-mm-yyyy'),'10:25:00'),'dd-mm-yyyy hh24:mi:ss') as
3 select * from scott.mview_1@scott_link_2;
Materialized view created.
scott用戶向mview_1中插入4條數據,然後查詢日誌表:
SQL> select count(*) from scott.MLOG$_MVIEW_1;
COUNT(*)
----------
4
存在了4條記錄。
物化視圖日誌存儲在"MLOG$_"爲開頭的表名中。
首先查看有多少物化視圖註冊到了刷新機制中
SQL> select OWNER,NAME,MVIEW_SITE,MVIEW_ID from DBA_REGISTERED_MVIEWS;
OWNER NAME MVIEW_SITE MVIEW_ID
--------------- ------------------------------ ------------------------------ ----------
SYSMAN MGMT_ECM_MD_ALL_TBL_COLUMNS SEEDDATA 0
SH CAL_MONTH_SALES_MV OGG1 21
SH FWEEK_PSCAT_SALES_MV OGG1 22
MING TARGET_MVIEW_1 OGG1 87
MING TARGET_MVIEW_2 OGG1 88
現在刪掉一條db_link:
SQL> drop database link scott_link_2;
Database link dropped.
查看基表上的物化視圖刷新依賴
SQL> SELECT * FROM DBA_BASE_TABLE_MVIEWS;
OWNER MASTER MVIEW_LAST_REFRESH_ MVIEW_ID
--------------- ------------------------------ ------------------- ----------
SCOTT MVIEW_1 2018-01-21 04:00:02 87
SCOTT MVIEW_1 2018-01-21 04:06:12 88
增量刷新兩個物化視圖
SQL> exec dbms_mview.refresh('TARGET_MVIEW_1');
PL/SQL procedure successfully completed.
SQL> exec dbms_mview.refresh('TARGET_MVIEW_2');
BEGIN dbms_mview.refresh('TARGET_MVIEW_2'); END;
*
ERROR at line 1:
ORA-02019: connection description for remote database not found
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2558
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2771
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2740
ORA-06512: at line 1
這時候TARGET_MVIEW_2已經不能刷新了;
物化視圖日誌:
SQL> select count(*) from scott.MLOG$_MVIEW_1;
COUNT(*)
----------
4
正常來說,基於一張表的所有物化視圖刷新以後日誌表會被清空,現在因爲有一個物化視圖因爲db_link刪除而導致刷新失敗,物化視圖日誌是不會自動清除的。
這時候的解決思路通常是:
1.刪除無法刷新的物化視圖
2.刪除無法刷新的物化視圖的註冊信息
這裏我採用第二種方法;
SQL> EXEC DBMS_MVIEW.UNREGISTER_MVIEW('MING', 'TARGET_MVIEW_2', 'OGG1');
PL/SQL procedure successfully completed.
SQL> select OWNER,NAME,MVIEW_SITE,MVIEW_ID from DBA_REGISTERED_MVIEWS;
OWNER NAME MVIEW_SITE MVIEW_ID
--------------- ------------------------------ ------------------------------ ----------
SYSMAN MGMT_ECM_MD_ALL_TBL_COLUMNS SEEDDATA 0
SH CAL_MONTH_SALES_MV OGG1 21
SH FWEEK_PSCAT_SALES_MV OGG1 22
MING TARGET_MVIEW_1 OGG1 87
可以看到MVIEW_ID=88的物化視圖已經沒有了。
清除日誌,注意千萬不要寫錯mview_id,不然後續刷新會報錯。
SQL> EXEC DBMS_MVIEW.PURGE_MVIEW_FROM_LOG(88);
PL/SQL procedure successfully completed.
這是查詢日誌:
SQL> select count(*) from scott.MLOG$_MVIEW_1;
COUNT(*)
----------
0
發現物化視圖日誌已經清空了。
基表再插入一條數據:
SQL> /
COUNT(*)
----------
1
SQL> exec dbms_mview.refresh('TARGET_MVIEW_1');
PL/SQL procedure successfully completed.
再次查詢發現物化視圖日誌,已經自動被清除了:
SQL> /
COUNT(*)
----------
0
再次查詢刷新時間:
SQL> SELECT * FROM DBA_BASE_TABLE_MVIEWS;
OWNER MASTER MVIEW_LAST_REFRESH_ MVIEW_ID
--------------- ------------------------------ ------------------- ----------
SCOTT MVIEW_1 2018-01-21 04:26:20 87
已經沒有88那條信息了。
當然了,表還是在的,只是數據不對了。
SQL> select count(*) from TARGET_MVIEW_2;
COUNT(*)
----------
9
這時重建一下刪除的db_link,再嘗試刷新一下TARGET_MVIEW_2:
SQL> exec dbms_mview.refresh('TARGET_MVIEW_2');
BEGIN dbms_mview.refresh('TARGET_MVIEW_2'); END;
*
ERROR at line 1:
ORA-12034: materialized view log on "SCOTT"."MVIEW_1" younger than last refresh
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2558
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2771
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2740
ORA-06512: at line 1
還是報錯,報錯跟SYS.DBMS_SNAPSHOT有關;DBMS_MVIEW是DBMS_SNAPSHOT的同義詞,所以應該是清楚了註冊信息的原因。
重新註冊,以下摘自官方文檔:
DBMS_MVIEW.REGISTER_MVIEW (
mviewowner IN VARCHAR2,
mviewname IN VARCHAR2,
mviewsite IN VARCHAR2,
mview_id IN DATE | BINARY_INTEGER,
flag IN BINARY_INTEGER,
qry_txt IN VARCHAR2,
rep_type IN BINARY_INTEGER := DBMS_MVIEW.REG_UNKNOWN);
但是按照官方文檔的寫法總是報錯:
execute DBMS_MVIEW.REGISTER_MVIEW('MING', 'TARGET_MVIEW_2', 'OGG1',88,33, 'select * from scott.mview_1@scott_link_2', 'DBMS_MVIEW.REG_UNKNOWN');
以下摘自MOS:
How to REGISTER and UNREGISTER a Materialized View - Testcase (文檔 ID 1393276.1)
SQL> select s.sowner OWNER, s.vname NAME, snapid,
2 decode(bitand(s.flag,1), 0, 'NO', 'YES') CAN_USE_LOG,
3 decode(bitand(s.flag,2), 0, 'NO', 'YES') UPDATABLE,
4 decode(bitand(s.flag,16), 16, 'ROWID',
5 (decode(bitand(s.flag,32), 32, 'PRIMARY KEY',
6 (decode(bitand(s.flag,536870912), 536870912, 'OBJECT ID',
7 'UNKNOWN'))))) REFRESH_METHOD
8 from sys.snap$ s where s.vname='TARGET_MVIEW_2';
OWNER NAME SNAPID CAN UPD REFRESH_METHOD
--------------- ------------------------------ ---------- --- --- ---------------
MING TARGET_MVIEW_2 88 YES NO PRIMARY KEY
So if we have an mview with primary key, and NOT UPDATABLE and FAST refreshable then this will be:
can_use_log yes 1
updatable no 0
primary key yes 32
So we add these together and get 33 so this is the value for the FLAG column.
註冊:
execute dbms_MVIEW.register_mview(-
'MING', -
'TARGET_MVIEW_2',-
'OGG1',-
88,-
33,-
'select * from scott.mview_1@scott_link_2');
PL/SQL procedure successfully completed.
再次查詢註冊信息,發現已經註冊回來了,如下:
21:19:38 SQL> col mview_site for a20
21:19:53 SQL> select OWNER,NAME,MVIEW_SITE,MVIEW_ID from DBA_REGISTERED_MVIEWS;
OWNER NAME MVIEW_SITE MVIEW_ID
------------------------------ ------------------------------ -------------------- ----------
SYSMAN MGMT_ECM_MD_ALL_TBL_COLUMNS SEEDDATA 0
SH CAL_MONTH_SALES_MV OGG1 21
SH FWEEK_PSCAT_SALES_MV OGG1 22
MING TARGET_MVIEW_2 OGG1 88
MING TARGET_MVIEW_1 OGG1 87
5 rows selected.
基表插入幾行數據,再次嘗試刷新:
21:23:07 SQL> EXEC dbms_mview.REFRESH('TARGET_MVIEW_1')
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.37
21:25:34 SQL> EXEC dbms_mview.REFRESH('TARGET_MVIEW_2')
BEGIN dbms_mview.REFRESH('TARGET_MVIEW_2'); END;
*
ERROR at line 1:
ORA-12034: materialized view log on "SCOTT"."MVIEW_1" younger than last refresh
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2558
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2771
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2740
ORA-06512: at line 1
這個報錯也很容易理解:
因爲unregister之後,數據量變化過,我們清除來了一次物化視圖日誌,所以有gap,這裏執行一次完全刷新應該就可以了,試一下:
21:29:31 SQL> exec dbms_mview.refresh('TARGET_MVIEW_2','C');
PL/SQL procedure successfully completed.
驗證一下:
基表:
21:27:14 SQL> select count(*) from mview_1;
COUNT(*)
----------
17
1 row selected.
物化視圖:
21:30:05 SQL> select count(*) from target_mview_1 union all select count(*) from target_mview_2;
COUNT(*)
----------
17
17
2 rows selected.
在查看官方文檔的時候發現有兩個purge log相關的存儲過程,
DBMS_MVIEW.PURGE_MVIEW_FROM_LOG (
mview_id IN BINARY_INTEGER);
DBMS_MVIEW.PURGE_MVIEW_FROM_LOG (
mviewowner IN VARCHAR2,
mviewname IN VARCHAR2,
mviewsite IN VARCHAR2);
上面兩個是一個。
DBMS_MVIEW.PURGE_LOG (
master IN VARCHAR2,
num IN BINARY_INTEGER := 1,
flag IN VARCHAR2 := 'NOP');
第二個存儲過程執行以後,與基表有關的所有的物化視圖需要完全刷新;
第一個存儲過程隻影響指定的物化視圖,這個被影響的物化視圖也需要完全刷新;
具體的用法不是很清楚,歡迎交流。
oracle 物化視圖日誌不自動清除
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.