Friday, 23 May 2025

Filled under:

SET SERVEROUTPUT ON

SET LINESIZE 200

SET PAGESIZE 1000


DECLARE

    v_tablespace    VARCHAR2(30) := 'USERS'; -- << CHANGE YOUR TABLESPACE NAME HERE

    v_block_size    NUMBER;

    v_file_id       NUMBER;

    v_file_name     VARCHAR2(512);

    v_current_bytes NUMBER;

    v_hwm_blocks    NUMBER;

    v_hwm_bytes     NUMBER;

    v_new_size_bytes NUMBER;

    v_autoextensible VARCHAR2(3);

    v_min_resize_bytes NUMBER;

    v_buffer_mb     NUMBER := 10; -- Safety margin in MB

BEGIN

    -- Get block size of the tablespace

    SELECT block_size INTO v_block_size

    FROM dba_tablespaces

    WHERE tablespace_name = UPPER(v_tablespace);


    -- Loop through datafiles of the tablespace

    FOR r IN (

        SELECT file_id, file_name, bytes, autoextensible

        FROM dba_data_files

        WHERE tablespace_name = UPPER(v_tablespace)

    ) LOOP

        v_file_id := r.file_id;

        v_file_name := r.file_name;

        v_current_bytes := r.bytes;

        v_autoextensible := r.autoextensible;


        -- Get highest block used in this file

        SELECT NVL(MAX(block_id + blocks), 0)

        INTO v_hwm_blocks

        FROM dba_extents

        WHERE file_id = v_file_id;


        v_hwm_bytes := v_hwm_blocks * v_block_size;

        v_min_resize_bytes := v_hwm_bytes + (v_buffer_mb * 1024 * 1024);


        -- Only suggest resize if current size is more than the HWM + buffer

        IF v_current_bytes > v_min_resize_bytes THEN

            v_new_size_bytes := FLOOR(v_min_resize_bytes / (1024*1024)) * 1024*1024; -- aligned to MB

            DBMS_OUTPUT.PUT_LINE(

                'ALTER DATABASE DATAFILE ''' || v_file_name || ''' RESIZE ' || ROUND(v_new_size_bytes / (1024*1024)) || 'M;'

            );

        ELSE

            DBMS_OUTPUT.PUT_LINE('-- No reclaimable space in file: ' || v_file_name);

        END IF;


    END LOOP;

END;

/


0 comments:

Post a Comment