如何管理物化視圖的磁碟空間分配?
摘要:我在 oracle 11g 中實現了似乎佔用磁碟空間的視圖,這與將行標記為已刪除並且統計資訊最終將它們顯示為可用空間(分配給表,允許重用)的普通表不同。與原始表的統計資訊不同,表空間使用量僅針對物化視圖增加。在 Oracle 12c 中測試,結果相同。如何確保 MV 重用已刪除行的空間?
我做了什麼? 我將這些分區物化視圖設置在單獨的模式中,將表空間與原始表分開(我知道它們可以動態創建分區,稱之為技術債務)。
CREATE MATERIALIZED VIEW replication_schema.origin_table PARTITION BY RANGE(tbl_timestamp) ( PARTITION tbl_before_2016 VALUES LESS THAN (TO_TIMESTAMP('2016-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS')), PARTITION tbl_2016_01 VALUES LESS THAN (TO_TIMESTAMP('2016-02-01 00:00:00','YYYY-MM-DD HH24:MI:SS')), PARTITION tbl_2016_02 VALUES LESS THAN (TO_TIMESTAMP('2016-03-01 00:00:00','YYYY-MM-DD HH24:MI:SS')), ... PARTITION tbl_after_2025 VALUES LESS THAN (MAXVALUE) ) REFRESH FORCE ON DEMAND START WITH SYSDATE NEXT sysdate+1/1440 AS SELECT * FROM origin_schema.table;
他們也有一些索引,一些是全球性的,一些是本地的。
CREATE INDEX tbl_account_index ON replication_schema.origin_table (tbl_account DESC) LOCAL; CREATE INDEX tbl_column1_index ON replication_schema.origin_table (tbl_column1 DESC) LOCAL; CREATE INDEX tbl_column2_index ON replication_schema.origin_table (tbl_column2 DESC) LOCAL; CREATE INDEX tbl_column3_index ON replication_schema.origin_table (tbl_column3 DESC); CREATE INDEX tbl_column4_index ON replication_schema.origin_table (tbl_column4 DESC);
大多數情況下,他們會獲得新行(大約 4M/月),但使用者已經設置了一個流程,每兩週從原始表中刪除舊行。他們每次最多可以從每個複製表中刪除 500K/1M 行。
此模式中有七個物化視圖。每一個都從一個原始表中提取數據。
我們看到的是,與原始表發生的情況相反,表中報告為空閒的空間
dba_
不會隨著時間而改變,表空間使用量只會從這些物化視圖中增長。如果我在刪除行後等待一段時間並執行此查詢:
select df.tablespace_name "Tablespace", totalusedspace "Used MB", (df.totalspace - tu.totalusedspace) "Free MB", df.totalspace "Total MB", round(100 * ( (df.totalspace - tu.totalusedspace)/ df.totalspace)) "Pct. Free" from (select tablespace_name, round(sum(bytes) / 1048576) TotalSpace from dba_data_files group by tablespace_name) df, (select round(sum(bytes)/(1024*1024)) totalusedspace, tablespace_name from dba_segments group by tablespace_name) tu where df.tablespace_name = tu.tablespace_name and df.totalspace <>0 ;
它顯示原始表空間的
Free MB
列(dba_data_files 中的空間減去 dba_segment 中聲明的分配)增加,但用於複製的 MB 從未減少,僅在新行上增加(現在超過三年)Tablespace Used MB Free MB Total MB Pct. Free SYSTEM 491 9 500 2 SYSAUX 1628 162 1790 9 UNDOTBS1 0 9645 9645 100 ORIGIN_DATA 2705 1391 4096 34 ORIGIN_REP_DATA **1975** 2121 4096 52
該表空間僅保存這些物化視圖。沒有其他對像被使用。
我嘗試了顧問,看看我能做什麼:
variable id number; begin declare name varchar2(100); descr varchar2(500); obj_id number; begin name:='REPCHECK'; descr:='Replication advisory'; dbms_advisor.create_task ( advisor_name => 'Segment Advisor', task_id => :id, task_name => name, task_desc => descr); dbms_advisor.create_object ( task_name => name, object_type => 'TABLE', attr1 => 'REPLICATION_SCHEMA', attr2 => 'ORIGIN_TABLE', attr3 => NULL, attr4 => NULL, attr5 => NULL, object_id => obj_id); dbms_advisor.set_task_parameter( task_name => name, parameter => 'recommend_all', value => 'TRUE'); dbms_advisor.execute_task(name); end; end; /
它說
對 origin_table 對象執行 re-org,估計節省 xxx 個字節
如果我嘗試通過程序查詢建議:
select tablespace_name, allocated_space, used_space reclaimable_space from table(dbms_space.asa_recommendations('TRUE', 'TRUE', 'ALL'))
它返回
ORIGIN_REP_DATA 100663296 38419844
但我只在嘗試執行 SHRINK SPACE 或 COMPRESS 選項時出錯
ORA-10635:無效的段或表空間類型 10635。00000 -“無效的段或表空間類型” *原因:無法收縮段,因為它不在自動段空間管理的表空間中,或者它不是數據、索引或 lob 段。*操作:檢查表空間和段類型並重新發出語句
長話短說:我可以做些什麼來避免在這個物化視圖中浪費磁碟空間?如何對它們進行維護?我應該放棄它們並重新創建它們嗎?表空間中的數據文件使用量每月增長約 10GB,我的時間(和空間)已用完。謝謝。
好吧,我嘗試了很多選項,其中大多數都不允許我修改 MV 分區中的任何內容。
最終釋放空間的原因(從原始表中不再可用的分區和數據也不再存在)正在執行 MV 的完整刷新以及 MLOG 表上的 TRUNCATE(確保沒有從計劃的作業執行刷新過程),與每個查詢具有足夠權限的使用者一起執行這些操作。
EXECUTE DBMS_MVIEW.REFRESH('REPLICATION_SCHEMA.ORIGIN_TABLE', 'C', '', TRUE, FALSE, 0, 0, 0, FALSE, FALSE); truncate table origin_schema.mlog$_origin_table;