You are on page 1of 2

Manual Tablespace Reorganization

This method can take one of two forms. It you are happy to change the datafile name do the following:
Create a new tablespace.
Move the segments to the new tablespace.
Drop the original tablespace.
Rename the new tablespace to match the original name.
If the datafile name must remain the same do the following:
Create a new tablespace.
Move the segments to the new tablespace.
Resize the original datafile.
Move the segments back to the original tablespace.
Drop the new tablespace.
Obviously the second method requires much more work as all segments are being moved twice.
The way to move segments depends on the type of segment being moved. Here are a few examples.
-- Move a table segment.
ALTER TABLE tab1 MOVE TABLESPACE new_ts;

-- Move an index segment.
ALTER INDEX ind1 REBUILD TABLESPACE new_ts;
ALTER INDEX ind1 REBUILD TABLESPACE new_ts ONLINE;

-- Move a table partition segment. (Remember to check for unusable indexes)
ALTER TABLE tab1 MOVE PARTITION part_1 TABLESPACE new_ts NOLOGGING;

-- Move an index partition segment.
ALTER INDEX ind1 REBUILD PARTITION ind1_part1 TABLESPACE new_ts;

-- Move LOB segments if we had them.
-- ALTER TABLE tab1 MOVE LOB(lob_column_name) STORE AS (TABLESPACE new_ts);
Of course, the tables and their respective indexes could be moved using the Online Table
Redefinition functionality.
The following example performs a manual reorganization where the datafile name is not retained.
Remember to recreate the test environment before starting this example.
First, create a new tablespace to hold the objects.
CONN / AS SYSDBA

CREATE TABLESPACE reclaim_ts_temp DATAFILE
'/u01/app/oracle/oradata/DB11G/reclaim02.dbf' SIZE 1M AUTOEXTEND ON NEXT 1M;
ALTER USER reclaim_user QUOTA UNLIMITED ON reclaim_ts_temp;
Move the objects to the new tablespace.
ALTER TABLE reclaim_user.t1 MOVE TABLESPACE reclaim_ts_temp;
ALTER INDEX reclaim_user.t1_pk REBUILD TABLESPACE reclaim_ts_temp;
ALTER TABLE reclaim_user.t2 MOVE TABLESPACE reclaim_ts_temp;
ALTER INDEX reclaim_user.t2_pk REBUILD TABLESPACE reclaim_ts_temp;
Drop the original tablespace and rename the new one back to the original name.
DROP TABLESPACE reclaim_ts INCLUDING CONTENTS AND DATAFILES;
ALTER TABLESPACE reclaim_ts_temp RENAME TO reclaim_ts;
Once again, the tablespace map shows we have removed the large section of free space in the middle of
the datafile associated with our tablespace.

We can also see the size of the datafile has been reduced from 26M to 13M.
CONN / AS SYSDBA

COLUMN name FORMAT A50

SELECT name, bytes/1024/1024 AS size_mb
FROM v$datafile
WHERE name LIKE '%reclaim%';

NAME SIZE_MB
-------------------------------------------------- ----------
/u01/app/oracle/oradata/DB11G/reclaim01.dbf 13

SQL>