← Space Management
Oracle · Space Management

How to shrink Oracle datafiles to their highwatermark

Generate ALTER DATABASE DATAFILE ... RESIZE statements to shrink each Oracle datafile down to just above its actual highwatermark.

Tested on11g12c18c19c21c23ai26ai

Compute the highest allocated block per datafile from DBA_EXTENTS and generate RESIZE statements that shrink each datafile to just above that point. This query itself is read-only — no changes happen until you copy the generated statements and execute them.

State-changing when the generated statements are run. RESIZE fails if the target is smaller than the highest extent, so review each statement first and consider MOVE / SHRINK on the largest segments before shrinking the datafile.

SELECT 'ALTER DATABASE DATAFILE ''' || file_name || ''' RESIZE '
       || ROUND(highwater + 2) || 'M;' AS ddl
FROM (
  SELECT /*+ RULE */
         a.tablespace_name,
         a.file_name,
         a.bytes / 1024 / 1024 AS file_size_mb,
         (b.maximum + c.blocks - 1) * d.db_block_size / 1024 / 1024 AS highwater
  FROM   dba_data_files a,
         (SELECT file_id, MAX(block_id) AS maximum
          FROM   dba_extents
          GROUP BY file_id) b,
         dba_extents c,
         (SELECT value AS db_block_size FROM v$parameter WHERE name = 'db_block_size') d
  WHERE  a.file_id  = b.file_id
  AND    c.file_id  = b.file_id
  AND    c.block_id = b.maximum
  ORDER BY a.tablespace_name, a.file_name
);
spacedatafileresizeshrinkstate-changing