表空間的管理---回收數據文件

對於一些比較大的數據文件,想回收一般就採用:先清除這個數據文件的數據,然後resize大小

實驗:

先創建一個測試表空間

create tablespace test datafile '/u01/app/oracle/oradata/U01/datafile/test.dbf'  size 10M autoextend on next 50M;

然後爲這個表空間創建一個表

create table test1 tablespace test as select * from dba_objects;

現在查看這個表空間數據文件大小

select BYTES/1024/1024,MAXBYTES/1024/1024 from Dba_Data_Files where tablespace_name ='TEST';

現在查看文件大小還是開始的10M

接着添加數據:

insert into   test1   select * from dba_objects ;

然後 commit;

現在再查看這個數據文件的大小,看看是不是成了60M了

再查看一下,數據文件具體用的大小情況:

SELECT UPPER(F.TABLESPACE_NAME) "表空間名",
  D.TOT_GROOTTE_MB "表空間大小(M)",
  D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空間(M)",
  TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') || '%' "使用比",
  F.TOTAL_BYTES "當前空閒空間(M)",
(SELECT free_space_mb+free_allocate_mb FROM dba_tablespace_free a where a.tablespace_name= f.tablespace_name) "總剩餘空間",
  F.MAX_BYTES "最大塊(M)"
  FROM (SELECT TABLESPACE_NAME,
  ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES,
  ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES
  FROM SYS.DBA_FREE_SPACE
  GROUP BY TABLESPACE_NAME) F,
  (SELECT DD.TABLESPACE_NAME,
  ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB
  FROM SYS.DBA_DATA_FILES DD
  GROUP BY DD.TABLESPACE_NAME) D
  WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME
and f.tablespace_name='TEST'
  ORDER BY 3 desc;

從這個看出實際用的並沒有那麼多,然後再把這個文件增加,接着添加數據

insert into TEST1   select * from test1 ;
commit;

現在再查看下數據文件具體的大小

然後根據這個實際佔用大小回收數據文件

select FILE_ID from dba_data_files where tablespace_name='TEST';
alter database datafile X resize XX M;

現在是可以回收的。

回收之後再查看下,數據文件佔用的具體大小。

這時大小是肯定改變了。

然後再創建一個表2

create table test2 tablespace test as select * from dba_objects;

再看下具體佔用空間,看看是不是已經改變了。

然後清除表1的數據

truncate table test1;

清除之後,接着再查看數據文件具體的大小

SELECT UPPER(F.TABLESPACE_NAME) "表空間名",
  D.TOT_GROOTTE_MB "表空間大小(M)",
  D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空間(M)",
  TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') || '%' "使用比",
  F.TOTAL_BYTES "當前空閒空間(M)",
(SELECT free_space_mb+free_allocate_mb FROM dba_tablespace_free a where a.tablespace_name= f.tablespace_name) "總剩餘空間",
  F.MAX_BYTES "最大塊(M)"
  FROM (SELECT TABLESPACE_NAME,
  ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES,
  ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES
  FROM SYS.DBA_FREE_SPACE
  GROUP BY TABLESPACE_NAME) F,
  (SELECT DD.TABLESPACE_NAME,
  ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB
  FROM SYS.DBA_DATA_FILES DD
  GROUP BY DD.TABLESPACE_NAME) D
  WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME
and f.tablespace_name='TEST'
  ORDER BY 3 desc;

這個和上面的一樣。。。。

看下執行結果實際佔用的大小是不是已經改變。

然後現在執行回收數據

alter database datafile X resize XXM;

是不是報錯了。。。。

爲什麼呢?

因爲現在在文件中只是數據沒有了,但是塊號還沒有改變,也就是block_id還沒有改變,可以通過查到

select  segment_name,block_id,blocks FROM dba_extents where Tablespace_name ='TEST' order by block_id desc;

這個返回結果意思是:block_id 是這個segment_name段所對應的一個區的起始塊號,對應的這個區裏面有連續的blocks個塊

然後總共的塊數就是這個段所佔用的空間,也就是總共有多少個塊。

現在塊的編號還沒有改變,所以不能回收大小。

需要執行:

alter table test2 move;

這個意思就是說重新分佈表2的塊號,使高水位線降低。然後回收數據文件的大小

再執行:

alter database datafile X resize XXM;

現在就可以回收了。。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章