Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

rekharaghuram
from rekharaghuram More from this publisher
05.11.2015 Views

CHAPTER 9 ■ REDO AND UNDO 325 ops$tkyte@ORA10G> update t set indexed = lower(indexed); 48771 rows updated. ops$tkyte@ORA10G> select used_ublk ... 10 / USED_UBLK ---------- 1938 As you can see, updating that indexed column in this example generated almost five times the undo. This is due to the inherit complexity of the index structure itself and the fact that we updated every single row in the table—moving every single index key value in this structure. ORA-01555: snapshot too old Error In the last chapter, we briefly investigated the ORA-01555 error and looked at one cause of it: committing too frequently. Here we are going to take a much more detailed look at the causes and solutions for the ORA-01555 error. ORA-01555 is one of those errors that confound people. It is the foundation for many myths, inaccuracies, and suppositions. ■Note ORA-01555 is not related to data corruption or data loss at all. It is a “safe” error in that regard; the only outcome is that the query that received this error is unable to continue processing. The error is actually straightforward and has only two real causes, but since there is a special case of one of them that happens so frequently, I’ll say that there are three: • The undo segments are too small for the work you perform on your system. • Your programs fetch across COMMITs (actually a variation on the preceding point). We covered this in the last chapter. • Block cleanout. The first two points are directly related to Oracle’s read consistency model. As you recall from Chapter 7, the results of your query are pre-ordained, meaning they are well defined before Oracle goes to retrieve even the first row. Oracle provides this consistent point in time “snapshot” of the database by using the undo segments to roll back blocks that have changed since your query began. Every statement you execute, such as the following: update t set x = 5 where x = 2; insert into t select * from t where x = 2; delete from t where x = 2; select * from t where x = 2;

326 CHAPTER 9 ■ REDO AND UNDO will see a read-consistent view of T and the set of rows where X=2, regardless of any other concurrent activity in the database. ■Note The four statements presented here are just examples of the types of statements that would see a read-consistent view of T. They were not meant to be run as a single transaction in the database, as the first update would cause the following three statements to see no records. They are purely illustrative. All statements that “read” the table take advantage of this read consistency. In the example just shown, the UPDATE reads the table to find rows where x=2 (and then UPDATEs them). The INSERT reads the table to find where X=2, and then INSERTs them, and so on. It is this dual use of the undo segments, both to roll back failed transactions and to provide for read consistency, that results in the ORA-01555 error. The third item in the previous list is a more insidious cause of ORA-01555, in that it can happen in a database where there is a single session, and this session is not modifying the tables that are being queried when the ORA-01555 error is raised! This doesn’t seem possible— why would we need undo data for a table we can guarantee is not being modified? We’ll find out shortly. Before we take a look at all three cases with illustrations, I’d like to share with you the solutions to the ORA-1555 error, in general: • Set the parameter UNDO_RETENTION properly (larger than the amount of time it takes to execute your longest running transaction). V$UNDOSTAT can be used to determine the duration of your long-running queries. Also, ensure sufficient space on disk has been set aside so the undo segments are allowed to grow to the size they need to be based on the requested UNDO_RETENTION. • Increase or add more rollback segments when using manual undo management. This decreases the likelihood of undo data being overwritten during the course of your longrunning query. This method goes toward solving all three of the previous points. • Reduce the runtime of your query (tune it). This is always a good thing if possible, so it might be the first thing you try. This will reduce the need for larger undo segments. This method goes toward solving all three of the previous points. • Gather statistics on related objects. This will help avoid the third point listed earlier. Since the block cleanout is the result of a very large mass UPDATE or INSERT, this needs to be done anyway after a mass UPDATE or large load. We’ll come back to these solutions, as they are important facts to know. It seemed appropriate to display them prominently before we begin. Undo Segments Are in Fact Too Small The scenario is this: you have a system where the transactions are small. As a result of this, you need very little undo segment space allocated. Say, for example, the following is true:

326<br />

CHAPTER 9 ■ REDO AND UNDO<br />

will see a read-consistent view of T <strong>and</strong> the set of rows where X=2, regardless of any other concurrent<br />

activity in the database.<br />

■Note The four statements presented here are just examples of the types of statements that would see a<br />

read-consistent view of T. They were not meant to be run as a single transaction in the database, as the first<br />

update would cause the following three statements to see no records. They are purely illustrative.<br />

All statements that “read” the table take advantage of this read consistency. In the example<br />

just shown, the UPDATE reads the table to find rows where x=2 (<strong>and</strong> then UPDATEs them). The<br />

INSERT reads the table to find where X=2, <strong>and</strong> then INSERTs them, <strong>and</strong> so on. It is this dual use<br />

of the undo segments, both to roll back failed transactions <strong>and</strong> to provide for read consistency,<br />

that results in the ORA-01555 error.<br />

The third item in the previous list is a more insidious cause of ORA-01555, in that it can<br />

happen in a database where there is a single session, <strong>and</strong> this session is not modifying the<br />

tables that are being queried when the ORA-01555 error is raised! This doesn’t seem possible—<br />

why would we need undo data for a table we can guarantee is not being modified? We’ll find<br />

out shortly.<br />

Before we take a look at all three cases with illustrations, I’d like to share with you the<br />

solutions to the ORA-1555 error, in general:<br />

• Set the parameter UNDO_RETENTION properly (larger than the amount of time it takes to<br />

execute your longest running transaction). V$UNDOSTAT can be used to determine the<br />

duration of your long-running queries. Also, ensure sufficient space on disk has been<br />

set aside so the undo segments are allowed to grow to the size they need to be based on<br />

the requested UNDO_RETENTION.<br />

• Increase or add more rollback segments when using manual undo management. This<br />

decreases the likelihood of undo data being overwritten during the course of your longrunning<br />

query. This method goes toward solving all three of the previous points.<br />

• Reduce the runtime of your query (tune it). This is always a good thing if possible, so it<br />

might be the first thing you try. This will reduce the need for larger undo segments. This<br />

method goes toward solving all three of the previous points.<br />

• Gather statistics on related objects. This will help avoid the third point listed earlier.<br />

Since the block cleanout is the result of a very large mass UPDATE or INSERT, this needs<br />

to be done anyway after a mass UPDATE or large load.<br />

We’ll come back to these solutions, as they are important facts to know. It seemed appropriate<br />

to display them prominently before we begin.<br />

Undo Segments Are in Fact Too Small<br />

The scenario is this: you have a system where the transactions are small. As a result of this, you<br />

need very little undo segment space allocated. Say, for example, the following is true:

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!