Вы находитесь на странице: 1из 2

ORA-01555 : “Snapshot too Old Error”

“ORA-01555 – Snapshot too old Error” is one of the common errors that is faced in Oracle
Databases running in Roll back Segments (RBS) or in Automatic Undo Management
(AUM) mode. This error is mainly caused because of the long running transactions where in
the Transaction or the Query tries to fetch a data across commit levels and also the system
looks for data that is very older and which is not available in the UNDO table space. This
error is also caused because of Oracle trying to attain a ‘READ CONSITENT’ image of the
process running in the Database.

Some Common Causes of getting ORA-1555 Error:

Some of the common causes or reasons for getting the “Snapshot too old” error are as
follows:

• The rollback information itself is overwritten so that Oracle is unable to rollback the
(committed) transaction entries to attain a sufficiently old enough version of the
block.

• The transaction slot in the rollback segment's transaction table (stored in the rollback
segment's header) is overwritten, and Oracle cannot rollback the transaction header
sufficiently to derive the original rollback segment transaction slot.

• Another reason for getting the ORA-1555 Error is because of Oracle trying to lookup
the rollback segment header's transaction slot pointed to by the top of the data block.
It then realizes that this has been overwritten and attempts to rollback the changes
made to the rollback segment header to get the original transaction slot entry. If it
cannot rollback the rollback segment transaction table sufficiently it will return ORA-
1555 since Oracle can no longer derive the required version of the data block.

• If the database has many transactions changing data and committing very often, then
chance of reusing the space used by a committed transaction is higher. A long
running query then may not be able to reconstruct the snapshot due to wrap around
and overwrite in rollback segments. Larger rollback segments in this case will
reduce the chance of reusing the committed transaction slots.

• If the rollback segment is corrupted and could not be read, then a statement needing
to reconstruct a before image snapshot will result in the error.

Some of the Common solutions to avoid ORA-1555 Error message:

1. Increase size of rollback segment or add additional Rollback segments which will reduce
the likelihood of overwriting rollback information that is needed. (In case of using RBS). This
will allow the updates etc. to be spread across more rollback segments thereby reducing the
chances of overwriting required rollback information.
2. Reduce the number of commit or reduce the Commit Interval at the application level so
that the query will commit the records at the database level in frequent intervals.

3. If the query is trying to fetch the data across commit level, try avoiding that so that the
error can be avoided.

4. Ensure that the outer select does not revisit the same block at different times during the
processing. This can be achieved by:

- Using a full table scan rather than an index lookup


- Introducing a dummy sort so that we retrieve all the data, sort it and then sequentially
visit these data blocks.

5. In case of the Database using AUM, we need to set the value of the UNDO RETENTION
properly (basically this value can reflect the number of hours the process is going to execute)
and also depending upon the size of the UNDO Table space. But we have to make sure that
we set the value of the UNDO RRETENTION correctly because setting a higher value or
lower value of this parameter will / can affect the Performance of execution of the query.
The below query can be used to find the OPTIMAL value of the UNDO RETENTION that
can be set at the time of the execution of a long-running query so that the ORA-1555 error
message can be avoided.

*********************************************************************************************************
SELECT d.undo_size/(1024*1024) "ACTUAL UNDO SIZE [MByte]",
SUBSTR(e.value,1,25) "UNDO RETENTION [Sec]",
ROUND((d.undo_size / (to_number(f.value) *
g.undo_block_per_sec))) "OPTIMAL UNDO RETENTION [Sec]"
FROM (
SELECT SUM(a.bytes) undo_size
FROM v$datafile a,
v$tablespace b,
dba_tablespaces c
WHERE c.contents = 'UNDO'
AND c.status = 'ONLINE'
AND b.name = c.tablespace_name
AND a.ts# = b.ts#
) d,
v$parameter e,
v$parameter f,
(
SELECT MAX(undoblks/((end_time-begin_time)*3600*24))
undo_block_per_sec
FROM v$undostat
)g
WHERE e.name = 'undo_retention'
AND f.name = 'db_block_size'
/
********************************************************************************************************

Вам также может понравиться