Oracle

如何管理物化視圖的磁碟空間分配?

  • December 18, 2019

摘要:我在 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/月),但使用者已經設置了一個流程,每兩週從原始表中刪除舊行。他們每次最多可以從每個複製表中刪除 50​​0K/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;

引用自:https://dba.stackexchange.com/questions/255376