For more information about freelists and how they can be used to minimize contention, see the Oracle7 Parallel Server Concepts and Administration manual. 12.1.2.2 The DBMS_SPACE.UNUSED_SPACE procedure The UNUSED_SPACE procedure returns information about the unused space and the position of the highwater mark in a table, index, or cluster segment. Specifications for Oracle7 and Oracle8 differ as follows. Here is the Oracle 7.x specification: PROCEDURE DBMS_SPACE.UNUSED_SPACE (segment_owner IN VARCHAR2 ,segment_name IN VARCHAR2 ,segment_type IN VARCHAR2 ,total_blocks OUT NUMBER ,total_bytes OUT NUMBER ,unused_blocks OUT NUMBER ,unused_bytes OUT NUMBER ,last_used_extent_file_id OUT NUMBER ,last_used_extent_block_id OUT NUMBER ,last_used_block OUT NUMBER); Here is the Oracle 8.0 specification: PROCEDURE DBMS_SPACE.UNUSED_SPACE (segment_owner IN VARCHAR2 ,segment_name IN VARCHAR2 ,segment_type IN VARCHAR2 ,total_blocks OUT NUMBER ,total_bytes OUT NUMBER ,unused_blocks OUT NUMBER ,unused_bytes OUT NUMBER ,last_used_extent_file_id OUT NUMBER ,last_used_extent_block_id OUT NUMBER ,last_used_block OUT NUMBER ,partition_name IN VARCHAR2 DEFAULT NULL); Parameters are summarized in the following table. Name Description segment_owner Schema of segment segment_name Name of segment segment_type Type of segment total_blocks Total data blocks in segment total_bytes Total bytes in segment unused_blocks Total unused blocks in segment unused_bytes Total unused bytes in segment last_used_extent_file_id File id of last used extent last_used_extent_block_id Block id of last used extent last_used_block Last used block in extent partition_name Name of partition (8.0 only) [Appendix A] What's on the Companion Disk? 12.1.2 The DBMS_SPACE Interface 551 12.1.2.2.1 Exceptions The UNUSED_SPACE procedure does not raise any package exceptions. UNUSED_SPACE will raise the following Oracle exception if invalid segment data is passed in or if the executing user does not have privileges to use the procedure on the segment: ORA−00942 Table or view does not exist. 12.1.2.2.2 Restrictions Note the following restrictions on calling the UNUSED_SPACE procedure: • The user must have the ANALYZE ANY system privilege to use UNUSED_SPACE on segments from schemas other than the current session schema. • The program does not assert a purity level with the RESTRICT_REFERENCES pragma. 12.1.2.2.3 Example The following is a simple SQL*Plus report on space utilization by tables in the current session schema. It displays total space allocated, total unused space, and the percentage of allocated space that is unused. //* Filename on companion disk: spcex1.sql */* DECLARE total_blocks NUMBER; total_bytes NUMBER; unused_blocks NUMBER; unused_bytes NUMBER; last_extent_file NUMBER; last_extent_block NUMBER; last_block NUMBER; grand_total_blocks NUMBER := 0; grand_total_unused NUMBER := 0; BEGIN FOR user_tables_rec IN (SELECT table_name FROM user_tables) LOOP DBMS_SPACE.UNUSED_SPACE (segment_owner => USER ,segment_name => user_tables_rec.table_name ,segment_type => 'TABLE' ,total_blocks => total_blocks ,total_bytes => total_bytes ,unused_blocks => unused_blocks ,unused_bytes => unused_bytes ,last_used_extent_file_id => last_extent_file ,last_used_extent_block_id => last_extent_block ,last_used_block => last_block ); grand_total_blocks := grand_total_blocks + total_blocks; grand_total_unused := grand_total_unused + unused_blocks; END LOOP; DBMS_OUTPUT.PUT_LINE('Space utilization (TABLES) '); DBMS_OUTPUT.PUT_LINE('total blocks: '|| [Appendix A] What's on the Companion Disk? 12.1.2 The DBMS_SPACE Interface 552 TO_CHAR(grand_total_blocks) ); DBMS_OUTPUT.PUT_LINE('unused blocks: '|| TO_CHAR(grand_total_unused) ); DBMS_OUTPUT.PUT_LINE('pct unused: '|| TO_CHAR(ROUND((grand_total_unused/grand_total_blocks)*100) ) ); END; / This is a sample of the report output: Space utilization (TABLES) total blocks: 1237 unused blocks: 613 pct unused: 50 In Oracle 8.0, the partition_name parameter was added to support space analysis for partitioned segments. Since the new parameter has a default value, calls to UNUSED_SPACE written to the version 7.x specification will continue to work under 8.0. WARNING: Under Oracle 8.0, calling DBMS_SPACE.UNUSED_SPACE for a segment results in a DDL lock being held on the segment until the PL/SQL scope within which the call is made completes. This prevents any other DDL from being executed on the segment, so long−running programs that use the UNUSED_SPACE procedure could cause unexpected interference with other DDL operations in the database. Unused space can be deallocated from segments and returned to the free space for the segment's tablespace using the following SQL command: ALTER [ TABLE | INDEX | CLUSTER ] segment_name DEALLOCATE UNUSED; For information on how Oracle allocates and manages segment space, see the Oracle7 Server Concepts manual. For information on the DEALLOCATE UNUSED clause of the ALTER TABLE statement, see the Oracle7 Server SQL Reference. 12.1.3 DBMS_SPACE Examples The DBMS_SPACE package is a good example of how Oracle Corporation is using the built−in packages to expose, in a controlled way, information about database internals not found in the data dictionary. DBAs managing large transaction−oriented databases must pay attention to space utilization within segments. The UNUSED_SPACE procedure provides an additional level of detail that can help the DBAs make better use of space. For instance, wasted space that can be freed back to the tablespace for use by other segments can be detected and measured. Also, segment growth rates can be measured more accurately than by monitoring extent allocation, providing better information on the need to expand tablespaces. DBAs, especially those with Oracle parallel server installations, will be interested additionally in monitoring the segment freelist information exposed by the FREE_BLOCKS procedure. Figure 12.1 illustrates how the blocks of a segment fall into one of three categories: used, unused (above the highwater mark), and on the free list. The latter two categories are the subject of the UNUSED_SPACE and FREE_BLOCKS procedures, respectively. Figure 12.1: Space utilization in a segment [Appendix A] What's on the Companion Disk? 12.1.3 DBMS_SPACE Examples 553 I really like the information available in the DBMS_SPACE programs. However, I find that the programs are very unwieldy to use, due to their long, cumbersome parameter lists. The UNUSED_SPACE procedure has at least three IN parameters and seven OUT parameters! Even the earlier simple illustrative example is many lines long. What if you're interested in only one of the OUT parameters −− say, unused_blocks? You still have to allocate variables to hold all the other OUT parameters just to make the procedure call. Wouldn't it be nice to simply call a function that returns the unused blocks number for a given segment? 12.1.3.1 The segspace package As usual, the solution to such usability issues lies in creating a package to encapsulate those unwieldy program calls with an easier−to−use layer of programs. Here is the specification for my own package called segspace: //* Filename on companion disk: segspace.sql */* CREATE OR REPLACE PACKAGE segspace /* || Extends the DBMS_SPACE package by creating function || calls to return individual parameter values || || Author: John Beresniewicz, Savant Corp || Created: 07/29/97 || || Compilation Requirements: || || Execution Requirements: || || ANALYZE ANY system privilege || */ AS /* || sets the specified segment as current context */ PROCEDURE set_segment (name_IN IN VARCHAR2 ,type_IN IN VARCHAR2 ,schema_IN IN VARCHAR2 ,partition_IN IN VARCHAR2 DEFAULT NULL); /* returns current segment name */ FUNCTION current_name RETURN VARCHAR2; /* returns current segment type */ FUNCTION current_type RETURN VARCHAR2; [Appendix A] What's on the Companion Disk? 12.1.3 DBMS_SPACE Examples 554 /* returns current segment schema */ FUNCTION current_schema RETURN VARCHAR2; /* || returns total_blocks from DBMS_SPACE.UNUSED_SPACE || for the segment specified */ FUNCTION total_blocks (name_IN IN VARCHAR2 DEFAULT current_name ,type_IN IN VARCHAR2 DEFAULT current_type ,schema_IN IN VARCHAR2 DEFAULT current_schema) RETURN NUMBER; /* || returns unused_blocks from DBMS_SPACE.UNUSED_SPACE || for the segment specified */ FUNCTION unused_blocks (name_IN IN VARCHAR2 DEFAULT current_name ,type_IN IN VARCHAR2 DEFAULT current_type ,schema_IN IN VARCHAR2 DEFAULT current_schema) RETURN NUMBER; /* || returns number of blocks on segment freelist using || DBMS_SPACE.FREE_BLOCKS */ FUNCTION freelist_blocks (name_IN IN VARCHAR2 DEFAULT current_name ,type_IN IN VARCHAR2 DEFAULT current_type ,schema_IN IN VARCHAR2 DEFAULT current_schema ,freelist_group_IN IN NUMBER DEFAULT 0 ,partition_IN IN VARCHAR2 DEFAULT NULL) RETURN NUMBER; END segspace; The segspace package has functions called total_blocks and unused_blocks. These functions both accept segment identification information as IN parameters and return the value of their corresponding OUT parameters from DBMS_SPACE.UNUSED_SPACE. So in SQL*Plus, you can use these functions as follows: SQL> var tot_blks NUMBER SQL> execute :tot_blks := segspace.total_blocks('TENK','TABLE','LOAD1'); PL/SQL procedure successfully completed. SQL> print tot_blks TOT_BLKS −−−−−−−−− 455 Well, this sure is a lot easier than calling the UNUSED_SPACE procedure directly! Notice, however, that the IN parameters to these functions also all have default values, which means that they can be suppressed when making the function call (as long as the default is the desired value). The default values used are the segment identifiers (name, type, and schema) most recently specified. Thus we can find out the unused blocks for the LOAD1.TENK table by immediately following the preceding call with this: SQL> var unused_blks number SQL> execute :unused_blks := segspace.unused_blocks; [Appendix A] What's on the Companion Disk? 12.1.3 DBMS_SPACE Examples 555 . the highwater mark in a table, index, or cluster segment. Specifications for Oracle7 and Oracle8 differ as follows. Here is the Oracle 7.x specification: PROCEDURE DBMS_SPACE.UNUSED_SPACE (segment_owner. information on how Oracle allocates and manages segment space, see the Oracle7 Server Concepts manual. For information on the DEALLOCATE UNUSED clause of the ALTER TABLE statement, see the Oracle7 Server. Reference. 12.1.3 DBMS_SPACE Examples The DBMS_SPACE package is a good example of how Oracle Corporation is using the built−in packages to expose, in a controlled way, information about database internals