Skip to Main Content
  • Questions
  • Reusing LOB segments blocks by doing empty_clob()

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Subbarao.

Asked: October 11, 2011 - 6:20 am UTC

Last updated: October 12, 2011 - 12:02 pm UTC

Version: 10.2.0.1

Viewed 10K+ times! This question is

You Asked

Hi Tom,
I am using oracle 10.2.0.1 DB.

I have a table with two CLOB columns and both sharing the same LOB table space.

Now this table has 40 million rows and LOB table space usage is keep growing as new rows are inserted into the database.

We are using the Local extent management and AUTO segment space management( ASSM AUTO).

I am planning to update the very old records clob columns with empty_clob(), so that the new inserts can use the freed up LOB segment blocks.

I have done the following testing in my dev DB and it works fine.
1. updated 200000 existing rows,setting the CLOB columns to empty_clob().
2. Inserted 100000 new rows into the table with CLOB columns containing 400kb of data.

3. Gathered the Table space usage and DMBS LOB segments blocks usage
details, there is no increase in table space usage as
the new inserts utilised the freed up blocks in step1.

I am not doing the other ways of reclaiming the space ( alter table shrink / table space movement ) to avoid any kind of outages to DB or any adverse impact in production.

Do you think does the above approach introduce any kind of performance related issues ? ( as we are trying to utilise the LOB freed up blocks).

Please suggest.

thanks
Subba.


and Tom said...

Well, lob space is managed differently than normal table data is - when a block in a lob segment is freed, it does not immediately go onto the free list.

log segment space is managed by either the RETENTION clause or PCTVERSION. This is a quote from my last book on this topic:

<quote>

...
So, that gives us a reason to be concerned: if the undo segments are not used to store rollback for LOBs and LOBs support read consistency, how can we prevent the dreaded ORA-1555: snapshot too old error from occurring? And, as important, how do we control the amount of space used by these old versions? That is where RETENTION and, alternatively, PCTVERSION come into play.

RETENTION tells the database to retain modified LOB segment data in the LOB segment in accordance with your database’s UNDO_RETENTION setting. If you set your UNDO_RETENTION to 2 days – Oracle will attempt to not reuse LOB segment space ‘freed’ by a modification. That is, if you deleted all of your rows pointing to LOBS – Oracle would attempt to retain the data in the LOB segment (the deleted data) for two days in order to satisfy your UNDO_RETENTION policy – just as it would attempt to retain the undo information for the structured data (your relational rows and columns) in the UNDO tablespace for two days. It is important you understand that – the ‘freed space’ in the LOB segment will not be not be immediately reused by subsequent INSERTs or UPDATEs. This is a frequent cause of questions in the form of “my LOB segment is growing and growing”. A mass ‘purge’ followed by a reload of information will tend to cause the LOB segment to just grow – since the retention period has not yet expired.

Alternatively, the LOB storage clause could use PCTVERSION. PCTVERSION controls the percentage of allocated (used by LOBs at some point and blocks under the LOBSEGMENT’s HWM) LOB space that should be used for versioning of LOB data. The default of 10 percent is adequate for many uses since many times you only ever INSERT and retrieve LOBs (updating of LOBs is typically not done; LOBs tend to be inserted once and retrieved many times). Therefore, not much space, if any, needs to be set aside for LOB versioning.

However, if you have an application that does modify the LOBs frequently, the default of 10 percent may be too small if you frequently read LOBs at the same time some other session is modifying them. If you hit an ORA-22924 error while processing a LOB, the solution is not to increase the size of your undo tablespace, or increase the undo retention, or add more rollback segments if you are using manual undo management. Rather you should use the following:

ALTER TABLE tabname MODIFY LOB (lobname) ( PCTVERSION n );

and increase the amount of space to be used in that LOBSEGMENT for versioning of data.
....
</quote>


So, when you do your mass delete - you might have to wait quite a while before that free space "appears". If you use retention - you'll have to wait until that period of time passes. If you are using pctversion - then you just need to understand that N% of space will just be reserved for old lobs.


As to your test, there is insufficient data to conclude what you concluded. What I'll conclude instead is that the 200,000 existing rows were updated - but their lobs are still there. The new 100,000 rows are reusing other old space (I'll guess you are using pctversion).

Now that you understand how the free space management works - you'll be able to better forecast how space will be used.

I prefer retention myself for lob space management. It avoids the ora-1555 and will allow the entire lob segment to be used over time as it does not set asided a fixed percent of space to be used.

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

ora 11 new lob architecture

Mark Russel-Brown, October 11, 2011 - 1:56 pm UTC

Tom, How does new lob architecture in Ora 11 change space utilization by clobs. Our main application does a lot of lob updating and we are constantly faced with space issues. Wondering if upgrade would be an instant solution.
Tom Kyte
October 11, 2011 - 2:05 pm UTC

I assume you mean securefiles - the space reuse is fundamentally the same as far as I know. If you are not using retention - you might switch over to that. Retention makes it pretty easy to understand when space will be reused - when the retention period expires. Pctversion is a bit more complex and the larger your lob segment gets, the larger the reserved space.


You do have the ability to compress securefiles if applicable (remember - compressed data doesn't compress, so if you have images for example - they are already compressed pretty much and won't benefit from that)

specifying the further values and querying

Subbarao Nadendla, October 12, 2011 - 10:58 am UTC

Hi Tom,

Thanks for your reply. It makes a lot better in my understanding of LOB blocks re usage.

Apologies for not mentioning the required data ( PCTVERSION etc).

I can see PCTVERSION as ZERO for the CLOB columns. Also the UNDO_RETENTION from v$parameter is showing as 900 ( sec ).

select value from v$parameter where name='undo_retention';
value
=====
9000

select table_name, column_name, pctversion, retention from dba_lobs where owner='<<owner>>'
and tablespace_name='<<LOB_TABLESPACE_NAME>>';

TABLE_NAME COLUMN_NAME PCTVERSION RETENTION
========== =========== ========== =========
XYZ TEST_CLOB1 0 (null)
XYZ TEST_CLOB1 0 (null)

So based on the above values, as my PCTVERSION is 0, as soon as i free up the LOB blocks by empty_clob(), the freed up blocks are available for immediate inserts.

I have read somewhere that we can't specify both PCTVERSION and RETENTION. Here in my case, the PCTVERSION specified as ZERO and that's the reason for freed blocks are available for immediate re-use.

Please confirm if my above understanding is correct or not.

Also as requested in my original post, does this exercise has any impact on performance ? ( not sure whether the LOB index creates any issues after this test).

Please suggest.

thanks
Subba.

Tom Kyte
October 12, 2011 - 12:02 pm UTC

in theory, the blocks should be reusable soon after you commit.


there should be no measurable impact on the lob index, indexes are pretty good at managing their space unless they are "sweeper" indexes (search this site for that term if you are curious as to what I mean by that) and lob indexes are not of that type


More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here