Oracle Database Undo space explained

In this blog post I will talk about the basic workings of Automatic Undo Management, which can cause ORA-01555 and ORA-30036 issues.

The scope is Automatic Undo Management used in 10g and 11g, but has to be explicitly set for 9i (UNDO_MANAGEMENT = AUTO). Manual Undo Management is out of scope for this blog.

The Undo tablespace is a normal tablespace like any other, but only Oracle is controlling what is happening inside it.

Undo something

The Undo tablespace is used for several features: ROLLBACK, READ CONSISTENCY and FLASHBACK technology.


Rollback is easy to understand, if you are not happy with some data modifications, you want to ‘undo’ it: Rollback.
The original (non modified) information within a transaction is stored in a separate Undo tablespace, because the database is designed for COMMIT to be fast, not rolling back.

Read Consistency

Another mechanism Undo information is used for is Read Consistency, which means if you run a query at 9:00 for 10 minutes, you want all the data to be from 9:00. You don’t want it to read data that has been modified at 9:02 and 9:06 or data that hasn’t been committed yet.

So, to support Read Consistency, Oracle must keep the original data (committed or not) for these 10 minutes until the query is finished.

The problem is, you actually don’t know how long the query will run for, so the general rule is to set this ‘keep-old-data-period’ to the longest running query. This is because you also want your longest running query to read consistent data.

This ‘keep-old-data-period’ is called ‘UNDO_RETENTION’ and defaults to 900 seconds, which means the database tries to keep all old changed information for 900 seconds.


Some Oracle features are build based upon using Undo information, meaning undo is more utilized.
Because ‘old’ data is stored for a certain time (UNDO_RETENTION), one can access this information to have look at data back in time by using FLASHBACK features: ‘How did the contents of this table looked like ten minutes ago?’. This information can be used for recovery from user-errors.

Flashback features using Undo are:

  • Flashback Query (based on time)
  • Flashback Versions Query (based on SCN)
  • Flashback Transaction Query (based on period)
  • Flashback Table (based on time)

Flashback Drop and Flashback Database do not use Undo information. Flashback Drop is using ‘not yet recycled segment and extents’ and Flashback Database is a separate mechanism using the Flash/Fast Recovery Area, by taking ‘snapshots’ and redo information.

Undo Lifetime

Undo information has different states during it’s lifecycle, depending on running transactions and retention settings.

There are three states or types of extents in the Undo tablespace: ACTIVE, EXPIRED and UNEXPIRED. Oracle is still using Rollback segments, but with Automatic Undo Management these are completely controlled by Oracle.


Active undo extents are used by transactions and will always be active, because they are needed for Rollback. The UNDO_RETENTION setting is not used here, because one can not say something like: ‘after 900 seconds you are not allowed to rollback anymore…’

You will get ‘ORA-30036 unable to extend segment in Undo tablespace‘ errors when no more space is left to store ACTIVE Undo. This will automatically rollback the transaction causing it. The NOSPACEERRCNT column in V$UNDOSTAT is a good indication how many times this has occurred.


Expired extents are not used by transactions, the data in these extends is committed and the UNDO_RETENTION time has passed, so it is not needed for Read Consistency.


Unexpired extents are non-active extents that still honour UNDO_RETENTION. The transactions belonging to these undo extents are committed, but the retention time has not passed: You still want/need these for Read Consistency!

When the Undo mechanism requires more extents for ACTIVE extents, it is allowed to steal UNEXPIRED extents when there are no EXPIRED extents left for reuse and it can not allocate more free extents (autoextend maxsize reached or fixed tablespace size). One can check the steal-count in UNXPSTEALCNT in V$UNDOSTAT.

You will get ‘ORA-01555 snapshot too old‘ errors if no Read Consistency information for a query is available. The SSOLDERRCNT in V$UNDOSTAT will show a count of these errors.


  • Active undo is used by active transactions: rollback and read consistency.
  • Expired undo is old and can be reused.
  • Unexpired undo is used for read consistency, retention time has not passed yet.
  • Unexpired undo can be stolen for Active undo. If this is happening you can get ORA-01555 before Undo retention has passed.
  • Unexpired undo can be secured by setting the RETENTION GUARANTEE option when creating the Undo tablespace (see Undo Sizing).

Undo extent status examples

With the next query you go through the contents of the Undo tablespace and sum the extent types:

select status,
  round(sum_bytes / (1024*1024), 0) as MB,
  round((sum_bytes / undo_size) * 100, 0) as PERC
  select status, sum(bytes) sum_bytes
  from dba_undo_extents
  group by status
  select sum(a.bytes) undo_size
  from dba_tablespaces c
    join v$tablespace b on = c.tablespace_name
    join v$datafile a on a.ts# = b.ts#
  where c.contents = 'UNDO'
    and c.status = 'ONLINE'

It will sum the three types of extents and shows the distribution of them within the Undo tablespace. ‘Free’ extents are not shown.

‘Normal’ operation

STATUS            MB       PERC
--------- ---------- ----------
ACTIVE            10          4
EXPIRED          110         43
UNEXPIRED         25         10

This is an example of ‘normal’ contents of the Undo tablespace. The system is using ACTIVE extents, some are UNEXPIRED used for read consistency and there are EXPIRED extents which can be reused.

Out of Free/EXPIRED extents

STATUS            MB       PERC
--------- ---------- ----------
ACTIVE           230         90
EXPIRED            0          0
UNEXPIRED         26         10

When the system is under load and the EXPIRED extents are near 0%, the total of ACTIVE and UNEXPIRED is near 100% and the Undo tablespace is not able to extend, Oracle will steal UNEXPIRED extents for ACTIVE extents. If this is the case you might expect ORA-01555 errors, because Undo retention can not be met.

Out of Undo space

STATUS            MB       PERC
--------- ---------- ----------
ACTIVE           255        100
EXPIRED            0          0
UNEXPIRED          1          0

When the system is under load and the ACTIVE extents are near 100%, the total of EXPIRED and UNEXPIRED is near 0% and the Undo Tablespace is not able to extend, Oracle is not able to allocate free extents or steal UNEXPIRED extents for ACTIVE extents. If this is the case you might expect ORA-30036 errors.

Retention to large or UNDO to small?

STATUS            MB       PERC
--------- ---------- ----------
ACTIVE             2          1
EXPIRED            0          0
UNEXPIRED        254         99

In this case, all undo extents are used for the retention period. It might be the retention is to large, or the UNDO tablespace is to small. A DBA must investigate this and take a decision!

Undo Sizing

Storing undo data for a certain amount of time will need space and based on the activity on the database system, it is written at a certain ‘rate’.
From this you can deduct an equation: RATE x RETENTION = SPACE. Some overhead must be added, but that varies between database versions used and data types stored.

If you look at the undo equation, the Undo tablespace size or the retention time can be fixed. A fixed rate can not be set, because it depends on database load.

Since Oracle 10g, the database will be more efficient if the same record is updated more than once in a transaction, it will re-use those ACTIVE extents.

Fixed Size

When the Undo tablespace size is fixed (datafile autoextend=NO), Oracle tunes the Retention Time for the amount of Undo data it is generating to fit into the Undo tablespace. The UNDO_RETENTION parameter will now be used as a minimum, but may automatically be tuned larger when enough space is available.

One can check the tuned Undo retention time in V$UNDOSTAT, using the TUNED_UNDORETENTION column.

In Oracle 9i, it seems Oracle is not actually tuning this, but is only trying to maintain the Undo retention time. Also the TUNED_UNDORETENTION column is absent in 9i.

When you choose the Undo tablespace to be fixed, you can use the Undo Advisor to estimate the needed sizing.

Fixed Size, out of UNEXPIRED extents? Check TUNED_UNDORETENTION!

STATUS            MB       PERC
--------- ---------- ----------
ACTIVE             2          1
EXPIRED            0          0
UNEXPIRED        254         99

Because Oracle is able to extend the retention time, more UNEXPIRED extents are created. In this case, if the Undo tablespace is full, check the TUNED_UNDORETENTION against UNDO_RETENTION. If the tuned retention is much larger, 99% full does not mean a problem!

Take a look at the following query, it will calculate the UNDO total with the following assumption: ACTIVE takes what is needs, EXPIRED ‘is empty’ and UNEXPIRED will be re-calculated against the division of UNDO_RETENTION/TUNED_UNDORETENTION.


select status,
 round(sum_bytes / (1024*1024), 0) as MB,
 round((sum_bytes / undo_size) * 100, 0) as PERC,
 decode(status, 'UNEXPIRED', round((sum_bytes / undo_size * factor) * 100, 0),
                'EXPIRED',   0,
                             round((sum_bytes / undo_size) * 100, 0)) FULL
 select status, sum(bytes) sum_bytes
 from dba_undo_extents
 group by status
 select sum(a.bytes) undo_size
 from dba_tablespaces c
 join v$tablespace b on = c.tablespace_name
 join v$datafile a on a.ts# = b.ts#
 where c.contents = 'UNDO'
 and c.status = 'ONLINE'
 select tuned_undoretention, u.value, u.value/tuned_undoretention factor
 from v$undostat us
 join (select max(end_time) end_time from v$undostat) usm
    on usm.end_time = us.end_time
 join (select name, value from v$parameter) u
    on = 'undo_retention'

When running this query, the next result will show when UNDO_RETENTION = 900 and TUNED_UNDORETENTION is about 1800 seconds:

STATUS            MB       PERC       FULL
--------- ---------- ---------- ----------
ACTIVE             2          1          1
EXPIRED            0          0          0
UNEXPIRED        254         99         50
          ---------- ---------- ----------
sum              256        100         51

Unexpired at 99% is not really a problem here, because the tuned retention is twice as large as the desired retention!

Since 10gR2, a maximum retention is introduced. The longest period of tuned undo I have seen is 96 hours. Automatic tuning retention can also be turned off using the hidden ‘_undo_autotune=false’ parameter (don’t use until Oracle suggested this hidden parameter). See also My Oracle Support Note: Full UNDO Tablespace In 10gR2 [ID 413732.1].

Fixed/Auto Retention

If the Undo tablespace is configured with the autoextend option for the data files, Oracle sets the Retention Time to the time it takes for the longest-running query to run. This can result in a large Undo tablespace if there are un-tuned queries running on your system.

Again in 9i, even though it is called Automatic Undo Management, UNDO_RETENTION parameter seems always ‘fixed’, but it does mean you don’t have to bother about Rollback Segments.

Shrink Undo tablespace

The Undo tablespace can only grow larger, but it can not shrink by itself. If you want to shrink the Undo tablespace, create a new one and set the UNDO_TABLESPACE parameter to the new Undo tablespace.

Retention Guaranteed

When you create the Undo tablespace with the RETENTION GUARANTEE option, UNEXPIRED Undo information will never get stolen. Set this if you want to guarantee Read Consistency or when you want to use Flashback with a guaranteed point-in-time!

Beware that when this is set, the chance of ORA-30036 errors increases. It’s your choice: ORA-30036 or ORA-01555…

Setting the UNDO_RETENTION parameter to the longest running query

A good practice is to set the UNDO_RETENTION parameter to the longest running query, to avoid ORA-01555 (read consistency) errors. To get a good indication about the longest running query in the last 7 days, try:

select max(maxquerylen) from v$undostat;

If you want to increase your Flashback period, take the largest of these two.

How much Undo will this generate?

Again take a look at V$UNDOSTAT and the UNDOBLKS column in particular.
Multiply these UNDOBLKS (per 10 minutes by default) times your BLOCKSIZE times the MAXQUERYLEN.

For a worst case scenario size you can calculate much undo would have been generated when you multiply the highest rate with the longest query:

  round(max(undoblks/600)*8192*max(maxquerylen)/(1024*1024)) as "UNDO in MB"
from v$undostat;

But, it could be your longest running query will not run when the most undo is generated…

Undo Advisor

The Undo Advisor can be found in the Oracle Enterprise Manager or by using the DBMS_ADVISOR package.

Undo Advisor

Undo Advisor

When opening the Undo advisor, it will show the current retention time and tablespace settings, but also shows analysis results, potential problems and recommendations.
These results are based on a 7 days period, analysing longest query or Flashback duration and Undo generation rates. This can be made visible thought the Undo graph.

Undo Retention Graph

Undo Retention Graph

New: When unchanged, this shows the current retention time setting. You can change the UNDO_RETENTION to a new value by selecting a dot on the line in the graph.
Auto-tuned Undo retention: This is the retention time Oracle can currently hold. It will use the UNDO_RETENTION as a minimum.
Best Possible Undo retention: With the current size (fixed) or maxsize (autoextend) of the Undo tablespace, this is the retention time it possibly could hold.

Oracle uses the statistics in the V$UNDOSTAT view to tune the Undo mechanism. A DBA can also use this view, together with V$ROLLSTAT to get a good indication of current workload. The DBA_HIST_UNDOSTAT view contains statistical snapshots of V$UNDOSTAT information.

All this information is based on the selected Analysis Time Period with the Undo generation rate within that period.


Automatic Undo Management not supported for LOBs. Undo information for LOBs is not stored Undo tablespace, but in the segment itself. For LOBs, the database uses the UNDO_RETENTION as a minimum, but when space becomes a problem, the UNEXPIRED Undo information for the LOB may be reused.


Even though Automatic Undo Management is able to tune itself, one needs to keep an eye on transaction duration, retention time and space consumed.

With the addition of Flashback technology to the database, the Undo tablespace is now also used to recover from user errors. When Retention Guaranteed is used, more priority is given to support Read Consistency and Flashback operations, because Oracle will not steal UNEXPIRED extents.

Furthermore the Undo Advisor can be used to visualise retention time vs. space consumed, but in case of Undo related errors, a DBA still needs to analyse V$UNDOSTAT and related views to solve problems other than ‘just enlarge’ the Undo tablespace.

Information in this article is based on my own experience and derived from articles and documentation found on the internet.

Tagged , , , , . Bookmark the permalink.

28 Responses to Oracle Database Undo space explained

  1. Pingback: The expdp equivalent of ‘exp consistent=y’…

  2. sumon says:


  3. Shafi says:

    I have to appreciate for what you have contributed in “undo management”…

  4. eme says:


    Our process requires set of queries to fetch consistent data. So we would be fetching the current_scn(select current_scn from v$database)
    and using that scn in all the queries in the procedure .(Select *from …. as of scn).

    This is our undo parameters values.

    undo_management – AUTO
    undo_tablespace – UNDOTBS2
    undo_retention – 900

    But I am currently facing error (ORA-01466 unable to read data – table definition has changed) even when the process fetches
    data before 900 seconds. However the error doesnt seem to be consistent. That is i am not reproduce the error. Kindly help me.


    • Ian Hoogeboom says:

      What the error tells, is that between the time you want to get data from (at SCN xyz) and ‘now’, the table (or an index) definition has been changed by a DDL statement. E.g at 9:05 you change a table or index and at 9:10 you run a query to get data from 9:00: At 9:05 you changed the definition.
      It’ is also possible you ask the database to get data ‘from the future’. There must be a bit of a delay between you get the SCN and use the flashback feature (Metalink: Error ORA-01466 while executing a flashback query. [ID 281510.1]). For Oracle 10, this is 6 seconds, for Oracle 9 it’s 5 minutes…

  5. eme says:

    Thanks for the reply Ian.

    There were no DDL changes between the time the current_scn was fetched and the time the scn was used in the flashback query.

    We use the same scn(xyz) fetched for a set of queries in which the first two or three queries execute with no issues. The issues comes in fourth or fifth queries at times.


    • Ian Hoogeboom says:

      Hi eme,
      It’s strange it works for a few queries, are these ‘fourth and fifth’ completed?

  6. Ashish Girahiya says:

    Hi Ian,

    Believe me, your blog on UNDO MANAGEMENT is very precise and to the point and it provides all the information related to Undo tablespace. I had read many articles, including Oracle docs, but the knowledge I have gained by reading your blog is just Amazing…

    Thanks a lot for creating such an article. It serves the purpose !! Good job..

  7. sagar says:

    what happen when you execute insert statement on table ?
    at that time undo is created that i know but how that is created or which information will be stored in that undo that i can’t identify.
    please help me.

    • Ian Hoogeboom says:

      With an update, the undo is filled with the old values and new values are in memory. Just before you commit (or every 3 seconds or when buffer is 90/95 something % full), the updated or dirty block in memory is written to the redo logs in disk. For Oracle the data is safe now (it’s even not in the data file yet). If you don’t commit, but do a rollback, the value from the undo is used to ‘un-dirty’ the block in memory again.
      A select from a user while another is updating will not read the dirty block in memory, but the original block in undo (this is why the undo retention is important).

      An insert is all new data, it has no corresponding ‘old value’. Your select within an transaction will read the ‘new dirty’ block, but a select from an other user will read noting.
      I don’t know if it’s really true, but I don’t think much undo data written when inserting. I have never thought of it before on inserting. Maybe something like: ‘that original block you are referring to, is empty’. It does however generate redo data.

  8. Joel says:

    Thanks for your excellent post!

    I have what I consider to be an odd problem. Just started occurring in the last month. I get constant alerts telling me there is a tablespace problem; however GRID shows only 36% tablespace full. A query against tablespace shows:

    —————————— ——— ———-
    UNDOTBS2 UNEXPIRED 111.875061
    UNDOTBS2 EXPIRED 142.212769

    It would seem that there is NO problem. Any thoughts, anyone?

  9. Byron says:

    I though the unexpired extents were the problem with my DB, but after reading your post the issue is clear. I have fixed undo tbs!

    Thanks for posting, sharing, educating!

  10. Amit says:

    Thanks made lot of thing clear now. Thank you for such lovely posts. Keep sharing.
    So finally the conclusion i made was though the unexpired count is large and active and expired count is less one need not worry about ORA 30036 since the expired and unexpired are bound to be reused. Am i right.

  11. tony says:

    Nice blog, helped lots refreshing my knowledge on undo!


  12. Amit says:

    Thank.. good blog on undo.

  13. Sudheer Godgeri says:

    I am facing ORA-8176: am using Red Hat Linux with Oracle
    both os and db are 64 bit.

    consistent read failure: no rollback data available.
    in a procedure using INSERT INTO global_temporary_Table and a lot
    of MERGE statements also using Global Temporary table udpates.

    UNDO space is 90% free ( our undo tablespace is 30gb)/
    undo_retention: 15000
    undo_Tablespace=undotbs1 ( 30 gb) and shows 90% free

    This repeats many times – but no entry related to this seen in alert log.
    Only the front end form/batch job shows this message.

    Found no workaround on net — am going to apply patchupdate
    as per metalink advise on this issue But i think it is weird and
    a workaround would be better than applying patch on heavily used
    production server.
    plz. advise if any solution is possible w/o patchset application.

    • Ian Hoogeboom says:


      If you are referring to Bug 9638090, I’m sorry to say that the only solution is to patch the Oracle software.
      It’s a problem in the database software and Oracle does not provide a workaround.


  14. surendra says:

    I have gained more knowledge by reading your blog is just Amazing…

  15. surendra says:

    what happen when you execute insert and delete statement on table ?

    • Ian Hoogeboom says:

      When you make changes, insert, updates and deletes, the old values are written to UNDO and ‘active’, new values are in memory (or REDO if the transaction takes more than 3 seconds).
      When you COMMIT these changes, the new values are persisted in REDO and ‘later’ written to the data files and the UNDO values is ‘unexpired’ and after the undo_retention has passed, it’s ‘expired’.
      When you ROLLBACK (or UNDO) these changes, the old values from UNDO are used to rollback the changes.

  16. Pingback: Oracle Database Undo space explained – Oracle 48 » Billy Aung Myint

  17. Yodha Lehal says:

    lets say the retention period is 900 sec , are there unexpired undo segments with different timestamp. and are they overwritten in some sequence or randomly. please let us know the sequence in which unexpired segments are written

    • Ian Hoogeboom says:

      Hi Yodha,

      Good question… I don’t know.
      I don’t think Oracle will be seeking the segment with the oldest unexpired undo (less than 900 seconds). In most examples it seeks in a rolling fashion for the next block within a segement, if it can not be found, it goes to the next segment (and extend the data file if necessary).

      From a response of Tom Kyte on a Rollback Segment question: The rollback segment is “full”. We try to wrap around but cannot (there is a transaction that is not committed with data in block 1 — we cannot reuse that block). So we try to extend — but the tablespace is full — we cannot extend. Hence, we fail.
      Rollback Segments – Unable to extend

      So my best guess is ‘sequentially’, but not on date/age, but on Rollback Segment sequence. This would look like ‘random’ as the ages within a block/segment are not sequentially stored.

      Although this is a ‘my best guess’ answer, I hope it helped!

      Regards, Ian.

  18. Amit says:

    how many give maximum size that we allocate to an undo tablespace.

    • Ian Hoogeboom says:

      The psychical limit of an Undo Tablespace is the same as a Data Tablespace, which is about 128TB or something?
      This is not what you want, the Undo Tablespace only needs to hold only you running transactions with a little extra for the retention parameter.
      There are calculations for big you could make it when using a fixed size (, but I would just leave it to autoextend and one datafile (32GB) if you have the space.
      If it hits 32GB, one must have take a look why you have so much Undo in there… at one one point you would have had 32Gb of data in open transactions.

  19. Praveen says:

    We are noticing this error “ORA-01555: snapshot too old: rollback segment number 33 with name “_SYSSMU33_269257306$” too small” in our data loading task. We are running a tool that will extract data from source and insert into Target db using java jdbc connection in batch commit. Along with that there are select from Target table and insert into another table. It may have huge data while doing select..insert. Current undo tb space is 30 GB. and undo_retention is 900. How to analyse this error? Adding more undo tb space is going to help?

    • Ian Hoogeboom says:

      “ORA-01555: snapshot too old” usually means a query (the extraction) is running for a much longer time than the 900 seconds (15 minutes) retention on the source database.
      If this is not the case, you can check with the query from the post if you meet the ‘Out of Free/EXPIRED extents’ numbers, if so the 30GB might be to small and the retention of 900 seconds is not met.

Leave a Reply

Your email address will not be published. Required fields are marked *