(轉) Delete/Truncate刪除,釋放表空間、下降高水位線、resize釋放磁盤空間相關優化

硬盤空間不足,打算刪除數據庫中的多餘數據,但刪除數據後,硬盤硬盤空間不能釋放。
【delete後用:alter table table_name move    truncate後用:alter table table_name deallocate unused 均不可解決】數據庫

解決方法:測試

--delete/truncate刪除,釋放表空間、下降高水位線、resize釋放磁盤空間相關優化彙總
--查詢DBF文件、數據庫空間、高水位線佔用狀況優化

select /*+ ordered use_hash(a,b,c) */
 a.file_id,
 a.file_name,
 a.tablespace_name,
 a.filesize,
 b.freesize,
 (a.filesize - b.freesize) usedsize,--使用空間
 c.hwmsize,
 c.hwmsize - (a.filesize - b.freesize) unsedsize_belowhwm,--未使用空間
 a.filesize - c.hwmsize canshrinksize--文件大小
  from (select tablespace_name,file_id, file_name, round(bytes / 1024 / 1024) filesize
          from dba_data_files) a,
       (select file_id, round(sum(dfs.bytes) / 1024 / 1024) freesize
          from dba_free_space dfs
         group by file_id) b,
       (select file_id, round(max(block_id) * 8 / 1024) HWMsize--高水位線
          from dba_extents
         group by file_id) c
 where a.file_id = b.file_id
   and a.file_id = c.file_id
 order by unsedsize_belowhwm desc

--查詢【各用戶】【表空間】數據存儲空間佔用大小(用戶與表空間對應關係)ui

select owner,tablespace_name ,sum(bytes)/1024/1024 from dba_segments group by owner,tablespace_name

--查詢當前用戶【表】數據存儲空間佔用大小spa

select segment_name, bytes/1024/1024 
from user_segments 
where segment_type = 'TABLE';

--查詢當前用戶【全部對象】數據存儲空間佔用大小code

select segment_type, Segment_Name, Sum(bytes) / 1024 / 1024
  From User_Extents
 Group By Segment_Name, segment_type

--查詢【表空間】與【DBF】對應關係與存儲狀況對象

select tablespace_name, file_id, file_name,
round(bytes/(1024*1024),0) total_space
from dba_data_files
order by tablespace_name;

--刪除表數據blog

truncate table ZW_FZHSZD
TRUNCATE TABLE JC_ASSETS_ADD  --DROP STORAGE

--分析(不分析,會致使下面步驟查詢表的高水位線時候數值會不許)索引

ANALYZE TABLE ZW_FZHSZD ESTIMATE STATISTICS;

--查詢表的水位分配狀況hash

SELECT blocks, empty_blocks, num_rows 
 FROM user_tables 
 WHERE table_name = 'ZW_FZHSZD';

--TRUNCATE後可釋放表數據庫空間,表默認把TRUNCATE數據前的空間大小做爲初始空間大小,表的高水位線不會下降,須要Shring收縮表的大小(下面詳解)後方可下降表的水位線

--釋放/收縮表數據庫空間

--alter table tablename move --選擇性操做,delete後可經過此方法釋放數據庫空間,但此操做MOVE時須要雙倍的表空間,大表有可能會致使高水位線提升,並且若是表上有索引的

話,須要重構索引,不建議使用

alter table tablename deallocate unused keep 0;--成功釋放數據庫空間,但高水位線不下降(表的高水位線下降,表空間的不下降??)

alter table JC_ASSETS_CHANGE enable row movement;--開啓movement功能
alter index xx rebuild--movement後須要重建索引(未驗證可行性)
ALTER TABLE USERS SHRINK SPACE --cascade --成功收縮表的數據庫空間爲最小值,但【表空間】水位有時下降、有時不下降,緣由不詳

--回縮索引爲最小值(選擇性操做)

ALTER INDEX INDEXINDEX1_FZHSZD  SHRINK SPACE

--查詢最大可resize空間

select a.file#,
a.name,
a.bytes / 1024 / 1024 CurrentMB,
ceil(HWM * a.block_size / 1024 / 1024) Resizeto,
(a.bytes - HWM * a.block_size) / 1024 / 1024 releaseMB,
'alter database datafile ''' || a.name || ''' resize ' ||
ceil(HWM * a.block_size / 1024 / 1024) || 'M;' ResizeCmd
from v$datafile a,
(select file_id, max(block_id + blocks - 1) HWM
from dba_extents
group by file_id) b
where a.file# = b.file_id(+)
and (a.bytes - HWM * a.block_size) > 0
order by 5


--Resize釋放硬盤空間(resize值必須大於高水位線,因此下降水位線很是重要)

ALTER DATABASE DATAFILE 'C:\APP\ADMINISTRATOR\ORADATA\ORCL\USERS01.DBF' resize 1000M;

--釋放HWM上面的未使用空間,可是並不會釋放HWM下面的自由空間,也不會移動HWM的位置.

 Alter  table table_name deallocate unused

終極方法:把表空間A內全部對象(表、索引)移動到表空間B,而後Resize 表空間A爲最少值(表空間內全部對象移走後高水位線會降到最低),而後再把對象從表空間B移回表空間A(測試可用,但不知道有沒反作用)

PS:
【清理臨時表空間方法】

ALTER TABLESPACE 臨時表空間名 SHRINK SPACE KEEP 512M
EMP:ALTER TABLESPACE TEMP_FMMS2 SHRINK SPACE KEEP 512M

--表空間DBF文件大小

select bytes/1024/1024  free_size from dba_data_files where tablespace_name='USERS';

--表空間空閒空間

select  SUM(BYTES/1024/1024) total_size from dba_free_space where tablespace_name='USERS';

--表空間水位線

select max(block_id)*8/1024 "m size" from dba_extents where tablespace_name='USERS'
相關文章
相關標籤/搜索