硬盤空間不足,打算刪除數據庫中的多餘數據,但刪除數據後,硬盤硬盤空間不能釋放。
【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'