|
Rollback segments
Copyright Oriole Corporation, 1999
Rollback segments are areas in your database which are used to temporarily
save the previous values when some updates (by 'updates' we mean inserts
or deletes as well) are going on. They have two main purposes :
- If for one reason or another the user wants to cancel his/her update with
a ROLLBACK statement, the former values are restored. This is
possible only during the life of the transaction. If the user executes
COMMIT instead, the values in the rollback segment are marked
as invalidated and the change becomes permanent.
- This is where other, concurrent sessions read the data when they access
the changed tables before the transactions are committed. Note that if a
SELECT starts on a table while a transaction is modifying the same table,
the old value of the data will be read from a rollback segment even if the
changed data is actually read by the SELECT after the
transaction has been committed (this is what is called read
consistency - what you see is, in fact, like a snapshot of the table at
the time when the SELECT starts). This explains why it's
important for Oracle to keep track of what changed values were orginally,
for as long as possible - some queries take a pretty long time to run.
In practise, rollback segments are segments like any other segment - i.e.
a collection of contiguous Oracle blocks known as extents which
increases as the need arises - when the segment has to grow, a new extent
is allocated and given a size computed from the parameters in the
storage clause for the segment. They must be created in a tablespace
and the universal practice is to create a tablespace dedicated to rollback
segments, where all the rollback segments (but for the rollback segment
named system which is created at database creation in
the similarly named tablespace and is used by the oracle kernel) are created.
The way rollback segments grow is a little bit special : what happens is
that when a transaction begins (in practice, when a session executes a
DELETE, an INSERT or an UPDATE) it
is (by default) randomly assigned to a rollback segment (the Oracle kernel
tries to spread the transactions between the various rollback segments
which are currently online). All the changed data will be written to this
rollback segment exclusively until the transaction commits. Several
transactions may share the same rollback segment, and even the same extent,
but each block within the extent will be filled in by a single transaction.
Because of read-consistency, Oracle tries to keep even out-dated data in
the rollback segments for as long as possible. However, filling the database with
rollback segments is not the ultimate purpose. Therefore, the strategy is as
follows; when a transaction reaches the end of the current extent and needs more
space, Oracle checks the next extent, if one was previously allocated or, if we
are 'at the end' of the rollback segment, the first extent - extents are, in
other words, used in a circular way.
- If no transaction is active within the
extent, then the extent will be recycled and rollback data generated by the
current transaction(s) will overwrite what was previously in this extent.
Note that the fact that no transaction is active doesn't mean that the data
is unused : some long-running SELECT may still be using it
to reconstruct the image of the table as it was when it started. Occasionally
(fairly rarely in practice) such a query may then fail with a snapshot too
old message (it will usually run OK when restarted).
- If however a transaction is still active, which means uncommitted,
even if it uses very few bytes in a very big extent, Oracle will allocate
a new extent and will go on allocating as long as it will be unable to
reuse the extent. If we see the rollback segment, as it is used circularly,
as a tire, we can say that Oracle will inflate the tire, making it bigger
and bigger.
This is where we may have many problems : suppose a big batch program which performs
tens of thousands of updates is running while a user updates a table - unused
by the batch program-, then, without committing the change, goes to the coffee
machine, and meets somebody very talkative there, the big update may fail
because Oracle was using the same rollback segments for both unrelated
transactions and tried to allocate extents and extents and extents until the
segment reached its MAXEXTENTS value (assuming it was not
unlimited) or the tablespace is full.
Note that some ALTER SESSION commands let us specify which
rollback segment we want to use, which may be useful for programs which
have huge requirements. However, this implies hard-coding physical details
which are specific to a particular database and should be transparent to
developers, which is why we are against this practise.
Because of the various points explained above, the creation of rollback
segments must obey a few rules :
- Because of the circular use of extents, having them differently sized
is totally irrelevant. Therefore INITIAL should be equal to
NEXT in the storage clause. Note that for rollback segments
specifying a value for PCTINCREASE is invalid (it is always 0,
which means that all dynamically allocated extents will be given the same
size as the NEXT parameter).
- As they are randomly assigned (forget about the ALTER SESSION
mentioned above), all simultaneously online rollback segments must be
created with the same STORAGE clause.
- To spread transactions between rollback segments, one must create enough
of them. The generally acknowledged ratio is one rollback segment per four
concurrently active transactions. Most databases do with 5 to 20 rollback
segments.
- Rollback segments cannot be created as fewer than two extents, as when
an active transaction reaches the end of the first extent it cannot do
other than to write to another extent. But in fact they must be created
with a value for MINEXTENTS higher than that, as dynamically
allocating an extent slows down transactions very noticeably.
Opinions vary about the right number of extents to create initially, anything between
4 and 20 is acceptable (this author would rather be in favor of the lower
values). Basically, the problem with rollback segments is the following :
- The total number of bytes required (the size of a rollback segment)
depends only on the programs which update the database - how heavily
they update it and how often transactions are committed.
- The total size being 'fixed' (although hard to predict), the product
number of extents x extent size is something over which the DBA has
no control. But he/she can choose the factors. If the extent size is
small, it will move easily in and out of memory, but we risk
exceeding (for a heavy update) the maximum number
of extents, at least with a pre-Oracle8 database for which this
value is limited. On the other hand, with very big extents first
you will probably do more I/O and you increase the risk of having
many transactions sharing the same extent - with a laggard which
maintains an extent in an 'un-overwritable' status, thus forcing
Oracle to allocate more and more extents.
The problem is that it is virtually impossible to predict anything. Our
advice is to create, say 5 to 10 rollback segments in a tablespace which is
big enough (50M is a minimum), and to create them as, say, 5 extents of 50
or 100K each - then to let the programs run for a while, and to monitor
closely. The view to watch is V$ROLLSTAT which will tell you
the size reached by each rollback segment, how much of it was active on
average, how many times we have 'wrapped', i.e. gone for the full circle and
reused the first extent. This gives you everything which is needed to
properly resize your rollback segments. For growns-up, there is a script which
does it automatically in the X-rated section on the Oriole website.
- One must especially not forget to use a keyword special to rollback
segments in the STORAGE clause : OPTIMAL.
Oracle will try to maintain rollback segments to the size defined as OPTIMAL,
allocating extents are they are required but deallocating them afterwards if
the segment has grown too big. However, one must be careful not to have
too many deallocations, which are roughly as costly as allocations.
This is why OPTIMAL must be very carefully set, and only after
the first round of observations.
|