Shrinking Smallfile Tablespaces in Oracle 23.7

As you may know, starting from Oracle 23ai, we can shrink permanent tablespaces. However, that was limited to bigfile tablespaces, and shrinking smallfile tablespaces was not possible. Although, by default, tablespaces are created as bigfile tablespace.

Now, in Oracle 23.7, shrinking smallfile tablespaces is possible and we can shrink these tablespaces using the dbms_space.tablespace_shrink procedure. This procedure executes familiar commands such as ‘alter table move online’ and ‘alter index rebuild’ to shrink smallfile tablespaces.

PROCEDURE SHRINK_TABLESPACE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 TS_NAME                        VARCHAR2                IN
 SHRINK_MODE                    NUMBER                  IN     DEFAULT
 TARGET_SIZE                    NUMBER                  IN     DEFAULT
 SHRINK_RESULT                  CLOB                    OUT
 ITERATIONS                     NUMBER                  IN     DEFAULT  

Test Scenario

To demonstrate this feature, let’s create a smallfile tablespace and populate it with some tables , drop a few tables and finally shrink the tablespace.

Step 1: Create a Tablespace with 3 Datafiles (Autoextend OFF)

SQL> create smallfile tablespace small_app_tbs datafile 'table1.dbf' size 2g , 'table2.dbf' size 2g, 'table3.dbf' size 2g;
Tablespace created

Step 2: Create Four Tables of Equal Size

SQL> create table vahid.tb1 tablespace small_app_tbs as select * from sys.tbl1;
Table created
SQL> create table vahid.tb2 tablespace small_app_tbs as select * from sys.tbl1;
Table created
SQL> create table vahid.tb3 tablespace small_app_tbs as select * from sys.tbl1;
Table created
SQL> create table vahid.tb4 tablespace small_app_tbs as select * from sys.tbl1;
Table created

Step 3: Check the Table Sizes

SQL> select round(bytes/1024/1024) SEG_SIZE_MB,segment_name,tablespace_name from dba_segments where tablespace_name=upper('SMALL_APP_TBS');
SEG_SIZE_MB SEGMENT_NAME    TABLESPACE_NAME
----------- --------------- ------------------------------
        456 TB1             SMALL_APP_TBS
        456 TB2             SMALL_APP_TBS
        456 TB3             SMALL_APP_TBS
        456 TB4             SMALL_APP_TBS

Step 4: Check the Used Space for Each Datafile

SQL>@datafile_size.sql
FILE_NAME                           TOTALSIZEMB     USEDMB AUTOEXTENSIBLE
----------------------------------  ----------- ---------- --------------
/oracle23.7/base/oradata/table1.dbf            2048        600 NO
/oracle23.7/base/oradata/table2.dbf            2048        596 NO
/oracle23.7/base/oradata/table3.dbf            2048        628 NO

Step 5: Analyze the Tablespace for Shrinking

Before making any changes, we run the DBMS_SPACE.TS_MODE_ANALYZE to determine how much space can be reclaimed:

SQL> set serveroutput on;
SQL> execute dbms_space.shrink_tablespace(TS_NAME=>'SMALL_APP_TBS', shrink_mode =>DBMS_SPACE.TS_MODE_ANALYZE);
-------------------ANALYZE RESULT-------------------
Total Movable Objects: 4
Total Movable Size(GB): .61
Original Datafile Size(GB): 6
Suggested Target Size(GB): 2.01
Process Time: +00 00:00:06.702488
PL/SQL procedure successfully completed

As you can see, shrinking of this tablespace, can reduce tablespace size from 6 GB to 2GB.

Step 6: Perform the Shrink Operation

Run the shrink procedure to reclaim space:

SQL> execute dbms_space.shrink_tablespace(TS_NAME=>'SMALL_APP_TBS');
-------------------SHRINK RESULT-------------------
Total Moved Objects: 4
Total Moved Size(GB): .61
Original Datafile Size(GB): 6
New Datafile Size(GB): 2.17
Process Time: +00 00:02:34.071108
PL/SQL procedure successfully completed.

Step 7: Verify the Results

After shrinking, we can see all four tables have moved to two datafiles and one the datafiles was removed.

SQL>@datafile_size.sql
FILE_NAME                           TOTALSIZEMB     USEDMB AUT
----------------------------------- ----------- ---------- ---
/oracle23.7/base/oradata/table1.dbf            2048       1810 NO
/oracle23.7/base/oradata/table2.dbf             174         16 NO

Before running the above command, I enabled trace for that session, and in the trace file, we can see the procedure running the following commands:

PARSING IN CURSOR #139815671265616 len=39 dep=1 uid=135 oct=1 lid=135 tim=4073208427751 hv=997212054 ad='688b2ec8' sqlid='fkx0630xr0gwq'
alter table "VAHID"."TB1" move  online
PARSING IN CURSOR #139815677584744 len=39 dep=1 uid=135 oct=1 lid=135 tim=4073174850219 hv=2522059658 ad='70fd73a0' sqlid='4dgz14yb574wa'
alter table "VAHID"."TB2" move  online
PARSING IN CURSOR #139815674335544 len=39 dep=1 uid=135 oct=1 lid=135 tim=4073139135319 hv=2132665791 ad='6d50bcf0' sqlid='0hvkcg5zjvtdz'
alter table "VAHID"."TB3" move  online 
END OF STMT
PARSING IN CURSOR #139815677576928 len=39 dep=1 uid=135 oct=1 lid=135 tim=4073103914906 hv=3658805126 ad='6bf236c0' sqlid='3u2hhh3d19vw6'
alter table "VAHID"."TB4" move  online 
END OF STMT

Verified the alert log messages and observed the following results:

2025-02-04T15:36:01.979306+03:30
VANAK(3):alter database datafile '/oracle23.7/base/oradata/table1.dbf' resize 2147483648
VANAK(3):Completed: alter database datafile '/oracle23.7/base/oradata/table1.dbf' resize 2147483648
VANAK(3):alter database datafile '/oracle23.7/base/oradata/table2.dbf' resize 182452224
VANAK(3):Resize operation completed for file# 31, fname /oracle23.7/base/oradata/table2.dbf, old size 2097152K, new size 178176K
VANAK(3):Completed: alter database datafile '/oracle23.7/base/oradata/table2.dbf' resize 182452224
VANAK(3):alter tablespace "SMALL_APP_TBS" drop datafile '/oracle23.7/base/oradata/table3.dbf'
2025-02-04T15:36:02.950573+03:30
VANAK(3):Deleted file /oracle23.7/base/oradata/table3.dbf
2025-02-04T15:36:03.012876+03:30
VANAK(3):Completed: alter tablespace "SMALL_APP_TBS" drop datafile '/oracle23.7/base/oradata/table3.dbf'
2025-02-04T15:36:13.954782+03:30
VANAK(3):ORA-01652 addlInfo tsn:9 objn:72805 objd:72834 user:VAHID obj:TB1 subobj: type:2
VANAK(3):ORA-01652: unable to grow table VAHID.TB1 in tablespace SMALL_APP_TBS [VANAK] by 8MB during operation with SQL ID:fkx0630xr0gwq, temp space used by session : 0 (MB)
2025-02-04T15:36:15.792791+03:30
VANAK(3):alter database datafile '/oracle23.7/base/oradata/table1.dbf' resize 2147483648
VANAK(3):Completed: alter database datafile '/oracle23.7/base/oradata/table1.dbf' resize 2147483648
VANAK(3):alter database datafile '/oracle23.7/base/oradata/table2.dbf' resize 182452224
VANAK(3):Completed: alter database datafile '/oracle23.7/base/oradata/table2.dbf' resize 182452224
2025-02-04T15:36:21.573052+03:30
VANAK(3):ORA-01652 addlInfo tsn:9 objn:72805 objd:72838 user:VAHID obj:TB1 subobj: type:2
VANAK(3):ORA-01652: unable to grow table VAHID.TB1 in tablespace SMALL_APP_TBS [VANAK] by 8MB during operation with SQL ID:fkx0630xr0gwq, temp space used by session : 0 (MB)
2025-02-04T15:36:23.317894+03:30
VANAK(3):alter database datafile '/oracle23.7/base/oradata/table1.dbf' resize 2147483648
VANAK(3):Completed: alter database datafile '/oracle23.7/base/oradata/table1.dbf' resize 2147483648
VANAK(3):alter database datafile '/oracle23.7/base/oradata/table2.dbf' resize 182452224
VANAK(3):Completed: alter database datafile '/oracle23.7/base/oradata/table2.dbf' resize 182452224

Conclusion

The ability to shrink smallfile tablespaces in Oracle 23.7 provides more flexibility for managing storage. However, note that dropping segments such as tables and indexes impacts the shrink operation, while simply deleting data from tables does not reclaim space within tablespaces.

ارائه خدمات مشاوره ، پشتیبانی و نصب و راه اندازی پایگاه داده اوراکل در سراسر کشور...................... تلفن: 09128110897 ایمیل:vahidusefzadeh@gmail.com

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *