概要:Oracle 11gにマテリアライズドビューがあり、行を削除済みとしてマークする通常のテーブルとは異なり、統計には最終的に空きスペースとして表示されます(テーブルに割り当てられ、再利用が可能です)。 Originテーブルの統計とは異なり、テーブルスペースの使用量はマテリアライズドビューでのみ増加します。 Oracle 12cでテストされ、同じ結果が得られました。 MVが削除された行からスペースを再利用することを保証する方法は?
私は何をしましたか?これらのパーティション化されたマテリアライズドビューを別のスキーマ、Originテーブルとは別のテーブルスペースにセットアップしました(動的にパーティションを作成できることを知っているため、技術的負債と呼んでいます)。
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)を取得しますが、ユーザーは2週間ごとにOriginテーブルから古い行を削除するプロセスを設定しています。毎回、レプリケートされた各テーブルから最大500K/1M行を削除できます。
このスキーマには7つのマテリアライズドビューがあります。それぞれが1つのOriginテーブルからデータを抽出します。
Originテーブルで発生するのとは逆に、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 ;
これは、Origin表領域のFree MB
列(dba_data_filesの領域からdba_segmentで宣言された割り当てを差し引いたもの)の増加を示していますが、レプリケーションに使用されるMBは決して減少せず、新しい行(現在は3年以上)でのみ増加します。
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オブジェクトで再編成を実行します。節約量の見積もりは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セグメントではないため、セグメントを縮小できません。 *処置:表スペースとセグメント・タイプを確認して、ステートメントを再発行してください。
簡単に言えば、このマテリアライズドビューでディスクスペースの浪費を回避するにはどうすればよいですか?それらのメンテナンスを行う方法は?それらをドロップして再作成しますか?テーブルスペースでのデータファイルの使用量は1か月あたり約10GB増加しており、時間(およびスペース)が不足しています。ありがとう。
ええと、私は多くのオプションを試しましたが、それらのほとんどは、MVのパーティション分割で何かを変更することに近づくことを許可していませんでした。
(Originテーブルで使用できなくなったパーティションとそこからデータがなくなったため)スペースを解放することになったのは、MLOGテーブルでTRUNCATEとともにMVの完全なリフレッシュを実行していた(スケジュールされたジョブから実行されるリフレッシュプロセスがないことを確認する) )、各クエリに対して十分な権限を持つユーザーでこれらを実行します。
EXECUTE DBMS_MVIEW.REFRESH('REPLICATION_SCHEMA.Origin_TABLE', 'C', '', TRUE, FALSE, 0, 0, 0, FALSE, FALSE);
truncate table Origin_schema.mlog$_Origin_table;