(轉) 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

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

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

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

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

--查詢當前用戶【所有對象】數據存儲空間占用大小

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;

--刪除表數據

truncate table ZW_FZHSZD
TRUNCATE TABLE JC_ASSETS_ADD  --DROP STORAGE

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

ANALYZE TABLE ZW_FZHSZD ESTIMATE STATISTICS;

--查詢表的水位分配情況

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'


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM