Sunteți pe pagina 1din 5

05/01/2016 Document 386341.

How to determine the actual size of the LOB segments and how to free the
deleted/unused space above/below the HWM (Doc ID 386341.1)
Modified: 16­Dec­2014 Type: HOWTO

In this Document

Goal
Solution
References

APPLIES TO:

Oracle Database ­ Enterprise Edition ­ Version 9.2.0.1 to 11.2.0.3 [Release 9.2 to 11.2]
Information in this document applies to any platform.

GOAL

Some hints about how to check the actual size of a LOB segment including the free and available space, above and
below the HWM, including the commands to free the space above the HWM.

SOLUTION

The size of the LOB segment can be found by querying dba_segments, as follows:

select bytes from dba_segments where segment_name ='<lob segment name>' and owner
='<table owner>';

To get the details of the table to which this LOB segment belong to:

SELECT TABLE_NAME, COLUMN_NAME  FROM DBA_LOBS WHERE OWNER = '<owner>' AND  SEGMENT_NAME=
'<lob segment name>' ;

The first thing to do would be to check the space that is actually allocated to the LOB data.
  

select sum(dbms_lob.getlength (<lob column name>)) from <table_name>;

Please note that the UNDO data for a LOB segment is kept within the LOB segment space. The above query result
is merely the still active LOB data. The rest of allocated data is undo space. The undo space can vary quite a lot,
from being very small in size (when LOBs are only inserted) to being very large (when many LOBs are deleted) and
is largely depending on the PCTVERSION LOB parameter or the RETENTION parameter.

Hence, The difference between these two is free space and/or undo space. It is not possible to assess the actual
empty space using the queries above alone, because of the UNDO segment size, which is virtually impossible to
assess. Furthermore, even when there is free space in the LOB, this does not mean this space can be released to
the tablespace, it could be under the HWM. To find the freeable space, use the UNUSED_SPACE procedure as
shown below.

Check the "free" space within a LOB segment.
First, remember that a lob  can have 3 states: "inuse", "deleted" and "free". There are no statistics for the LOB
segment, the DBMS_SPACE package is the only tool that could give an idea about it. As well, there is no view
showing the deleted space within the LOB. The deleted space can be converted into free by rebuilding the freelist
or by rebuilding the LOB segment itself, but this is not always possible.
Note:

https://support.oracle.com/epmos/faces/DocContentDisplay?_adf.ctrl­state=16vpri4m15_114&id=386341.1 1/5
05/01/2016 Document 386341.1

LOB Partition sizing is not supported in DBMS_SPACE package until 10g.  
Error ORA­00600 [ktsircinfo_num1] will be generated if the procedure is run against the lob partition on versions
below 10g

P.S: When using dbms_lob.getlength, the output is in characters for CLOBs and NCLOBs, and in bytes for BLOBS
and BFILES.

One can get an idea about how much space is actually used and what could be deallocated as follows:
1. Determine the unused space within the LOB segment, above the HWM. using the UNUSED_SPACE procedure. 

set serveroutput on 
 
declare 
 
TOTAL_BLOCKS number; 
TOTAL_BYTES number;   
 
UNUSED_BLOCKS number; 
UNUSED_BYTES number;   
 
LAST_USED_EXTENT_FILE_ID number; 
 
LAST_USED_EXTENT_BLOCK_ID number; 
LAST_USED_BLOCK number;   
 
begin 
 
dbms_space.unused_space('<owner>','<lob segment name>','LOB', 
TOTAL_BLOCKS, TOTAL_BYTES, UNUSED_BLOCKS, UNUSED_BYTES,   
LAST_USED_EXTENT_FILE_ID, LAST_USED_EXTENT_BLOCK_ID,   
LAST_USED_BLOCK);   
 
dbms_output.put_line('SEGMENT_NAME = <LOB SEGMENT NAME>'); 
 
dbms_output.put_line('­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­'); 
dbms_output.put_line('TOTAL_BLOCKS = '||TOTAL_BLOCKS);   
dbms_output.put_line('TOTAL_BYTES = '||TOTAL_BYTES);   
 
dbms_output.put_line('UNUSED_BLOCKS = '||UNUSED_BLOCKS); 
dbms_output.put_line('UNUSED BYTES = '||UNUSED_BYTES);   
 
dbms_output.put_line('LAST_USED_EXTENT_FILE_ID = '||LAST_USED_EXTENT_FILE_ID); 
 
dbms_output.put_line('LAST_USED_EXTENT_BLOCK_ID = '||LAST_USED_EXTENT_BLOCK_ID); 
dbms_output.put_line('LAST_USED_BLOCK = '||LAST_USED_BLOCK);   
 
end; 
/  

This is the only space that could be deallocated using the ALTER TABLE ... DEALLOCATE UNUSED command as
seen below.

2.1. For tablespaces that are using free lists, the following procedures could be used to find the blocks that are on
the freelists (which is not extremely useful when wanting to free up some space, as these blocks are just filled
below the PCTUSED. Nevertheless, this shows there is some free space within the LOB.

2.1.1. for one freelist group:

declare 
 
free_blocks number; 
begin   
 
DBMS_SPACE.FREE_BLOCKS('<owner>', '<lob segment name>', 'LOB',0 ,free_blocks); 
dbms_output.put_line('Nb of free blocks = '||free_blocks);   
end;   
/  

https://support.oracle.com/epmos/faces/DocContentDisplay?_adf.ctrl­state=16vpri4m15_114&id=386341.1 2/5
05/01/2016 Document 386341.1

2.1.2. for multiple freelist groups:

variable free_blks number; 
declare i int;   
 
declare v_freelist_groups:=100; ­­­ replace this with the actual number 
begin   
 
FOR i IN 0..v_freelist_groups­1 LOOP 
 
DBMS_SPACE.FREE_BLOCKS('<owner>','<lob segment name>','LOB', i, :free_blks); 
dbms_output.put_line('instance#: ' || i);   
 
dbms_output.put_line('free_blks: ' || :free_blks); 
dbms_output.put_line('');   
END LOOP;  

the above procedures would not work for ASSM tablespaces, because the free_blocks procedure does not work
with them. 

2.2 SPACE_USAGE procedure could be used for ASSM segments instead:

declare 
 
v_unformatted_blocks number; 
v_unformatted_bytes number;   
v_fs1_blocks number;   
v_fs1_bytes number;   
 
v_fs2_blocks number; 
v_fs2_bytes number;   
 
v_fs3_blocks number; 
v_fs3_bytes number;   
 
v_fs4_blocks number; 
v_fs4_bytes number;   
 
v_full_blocks number; 
v_full_bytes number;   
begin   
 
dbms_space.space_usage ('<owner>', '<lob segment name>', 'LOB', v_unformatted_blocks, 
v_unformatted_bytes, v_fs1_blocks, v_fs1_bytes, v_fs2_blocks, v_fs2_bytes,   
 
v_fs3_blocks, v_fs3_bytes, v_fs4_blocks, v_fs4_bytes, v_full_blocks, v_full_bytes); 
dbms_output.put_line('Unformatted Blocks = '||v_unformatted_blocks);   
dbms_output.put_line('FS1 Blocks = '||v_fs1_blocks);   
dbms_output.put_line('FS2 Blocks = '||v_fs2_blocks);  
dbms_output.put_line('FS3 Blocks = '||v_fs3_blocks);  
dbms_output.put_line('FS4 Blocks = '||v_fs4_blocks);  
 
dbms_output.put_line('Full Blocks = '||v_full_blocks); 
end;   
/  

Determine ASSM tablespaces or ASSM residing LOBs with:

select tablespace_name,EXTENT_MANAGEMENT,allocation_type,segment_space_management
from dba_tablespaces where segment_space_management='AUTO' 
and tablespace_name NOT LIKE '%UNDO%'
and tablespace_name = '<name of tablespace>'
/

­­Find LOBs that reside in ASSM tablespaces:

col Table format a24
col Tablespace format a22

https://support.oracle.com/epmos/faces/DocContentDisplay?_adf.ctrl­state=16vpri4m15_114&id=386341.1 3/5
05/01/2016 Document 386341.1

col partitioned format a11
col column_name format a24

select column_name "Column",table_name "Table",tablespace_name "Tablespace",partitioned
from DBA_LOBS
where tablespace_name in (select tablespace_name
from DBA_TABLESPACES where segment_space_management='AUTO'
and tablespace_name NOT LIKE '%UNDO%'
and owner NOT IN ('SYS','SYSTEM','CTXSYS','MDSYS','ORDSYS','DBSNMP',
'SYSMAN','XDB','MDSYS','ORDSYS','EXFSYS','DMSYS','WMSYS'))
order by tablespace_name
/

3. The command used to deallocate the lob free space is:

alter table <table name> modify lob (<lob column name>) (deallocate unused);

This is not very useful in most circumstances. There is probably very little space above the high water mark. On top
of this, the deleted space from inside the the lob segment is not even shown by the procedures above. This is the
expected behaviour and, unfortunately, currently there is no procedure/view to show the deleted space. Having
such an option is the current subject of an enhancement request.

However, the deleted space can be turned into free space and, when this happens, the procedure in 2.2 would
show this free space. To turn the deleted space into free space, one has to rebuild the freepools. The command
used to do this is: 

alter table <table name> modify lob(<lob column name>) (freepools <number of free
pools>);

The free pools number can be taken from the dba_lobs view. When this value is null, the command can be run with
a freepools number of 1. This procedure will not release the free space to the tablespace.

If one wants to release the space,
­ for versions below 10.2, one has to rebuild the LOB segment using the MOVE command:

alter table <table name> move lob (<lob column name>) store as (tablespace <tablespace
name>);

 ­ 10.2 introduced an even better option, it extended the SHRINK SPACE command to LOBs. As such, one can
remove the deleted and free space altogether from the LOB segment and LOB index: 

alter table <table name> modify lob(<lob column name>) (shrink space [cascade]);

WARNINGS:

#1. Be aware of the following bug before adjusting storage freelists for any LOB

Serious LOB corruption can occur after an 
ALTER TABLE <table> MODIFY LOB ("<lob_column>") (STORAGE (freelists <n>));
has been issued on a LOB column which resides in a manual space managed tablespace. Subsequent use of the
LOB can fail with various internal errors such as:
ORA­600 [ktsbvmap1] 

https://support.oracle.com/epmos/faces/DocContentDisplay?_adf.ctrl­state=16vpri4m15_114&id=386341.1 4/5
05/01/2016 Document 386341.1

ORA­600 [25012]

For more information, please refer to bug 4450606.

#2. Be aware of the following bug before using the SHRINK option in releases which are <=10.2.0.3:
Bug: 5636728 LOB corruption / ORA­1555 when reading LOBs after a SHRINK operation
Please check:
Note.5636728.8 Ext/Pub Bug 5636728 ­ LOB corruption / ORA­1555 when reading LOBs after a SHRINK operation
for details on it.

#3. Be aware that, sometimes, it could be needed to perform the shrink operation twice, in order to avoid the:
Bug:5565887 SHRINK SPACE IS REQUIRED TWICE FOR RELEASING SPACE.
is fixed in 10.2.

REFERENCES

NOTE:1453350.1 ­ How to Determine what storage is used in a LOBSEGMENT and should it be shrunk /
reorganized?
NOTE:861344.1 ­ 11g Advanced Compression ­ How to Check Space Occupied by LOB Compression

Didn't find what you are looking for?

https://support.oracle.com/epmos/faces/DocContentDisplay?_adf.ctrl­state=16vpri4m15_114&id=386341.1 5/5

S-ar putea să vă placă și