Determining the Optimal Undo Retention Period:
===================================
You need to determine the optimal length of time for undo retention in your database.
Solution
You can specify the length of time Oracle will retain undo data after a transaction commits, by specifying the
UNDO_RETENTION parameter. To determine the optimal value for the UNDO_RETENTION parameter, you must first
calculate the actual amount of undo that the database is generating. Once you know approximately how much
undo the database is generating, you can calculate a more precise value for the UNDO_RETENTION parameter.
Use the following formula to calculate the optimal value of the UNDO_RETENTION parameter:
OPTIMAL UNDO_RETENTION = UNDO SIZE/(DB_BLOCK_SIZE*UNDO_BLOCK_PER_SEC)
You can calculate the space allocated for undo in your database by issuing the following query:
SQL> select sum(d.bytes) "undo"
2 from v$datafile d,
3 v$tablespace t,
4 dba_tablespaces s
5 where s.contents = 'UNDO'
6 and s.status = 'ONLINE'
7 and t.name = s.tablespace_name
8 and d.ts# = t.ts#;
UNDO
----------
104857600
SQL>
You can calculate the value of UNDO_BLOCKS_PER_SEC with the following query:
SQL> select max(undoblks/((end_time-begin_time)*3600*24))
2 "UNDO_BLOCK_PER_SEC"
3 FROM v$undostat;
UNDO_BLOCK_PER_SEC
------------------
7.625
SQL>
In this case, you choose a value for the UNDO_RETENTION parameter first and use that to calculate
the size of your undo tablespace. The formula now becomes:
size of undo = undo_retention * db_block_size :undo_block_per_sec
You can use the following query to do all the calculations for you:
select d.undo_size/(1024*1024) "Current UNDO SIZE",
SUBSTR(e.value,1,25) "UNDO RETENTION",
(to_number(e.value) * to_number(f.value) *
g.undo_block_per_sec) / (1024*1024)
"Necessary UNDO SIZE"
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';
Current UNDO SIZE
-----------------
500
UNDO RETENTION
--------------
10800
Necessary UNDO SIZE
-------------------
674.611200
The query shows that you should set the size of the undo tablespace in this database to around 675 MB. The final
result is 674.611200. That rounds to 675 MB.
Here is how to set the undo retention to 30 minutes for an instance by updating the value of the UNDO_RETENTION
parameter in the SPFILE:
SQl> alter system set undo_retention=1800 scope=both;
System altered.
SQL>