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 329 manually managed undo, which will wrap around and reuse undo space as soon as it can. It is primarily for this reason, the support of the UNDO_RETENTION parameter, that I highly recommend automatic undo management whenever possible. That single parameter reduces the possibility of an ORA-01555 error greatly (when it is set appropriately!). When using manual undo management, it is also important to remember that the probability of an ORA-01555 error is dictated by the smallest rollback segment in your system, not the largest and not the average. Adding one “big” rollback segment will not make this problem go away. It only takes the smallest rollback segment to wrap around while a query is processing, and this query stands a chance of an ORA-01555 error. This is why I was a big fan of equi-sized rollback segments when using the legacy rollback segments. In this fashion, each rollback segment is both the smallest and the largest. This is also why I avoid using “optimally” sized rollback segments. If you shrink a rollback segment that was forced to grow, you are throwing away a lot of undo that may be needed right after that. It discards the oldest rollback data when it does this, minimizing the risk, but still the risk is there. I prefer to manually shrink rollback segments during off-peak times if at all. I am getting a little too deep into the DBA role at this point, so we’ll be moving on to the next case. It’s just important that you understand that the ORA-01555 error in this case is due to the system not being sized correctly for your workload. The only solution is to size correctly for your workload. It is not your fault, but it is your problem since you hit it. It is the same as if you run out of temporary space during a query. You either configure sufficient temporary space for the system, or you rewrite the queries so they use a plan that does not require temporary space. To demonstrate this effect, we can set up a small, but somewhat artificial test. We’ll create a very small undo tablespace with one session that will generate many small transactions, virtually assuring us that it will wrap around and reuse its allocated space many times— regardless of the UNDO_RETENTION setting, since we are not permitting the undo tablespace to grow. The session that uses this undo segment will be modifying a table, T. It will use a full scan of T and read it from “top” to “bottom.” In another session, we will execute a query that will read the table T via an index. In this fashion, it will read the table somewhat randomly: it will read row 1, then row 1,000, then row 500, then row 20,001, and so on. In this way, we will tend to visit blocks very randomly and perhaps many times during the processing of our query. The odds of getting an ORA-01555 error in this case are virtually 100 percent. So, in one session we start with the following: ops$tkyte@ORA10G> create undo tablespace undo_small 2 datafile size 2m 3 autoextend off 4 / Tablespace created. ops$tkyte@ORA10G> alter system set undo_tablespace = undo_small; System altered. Now, we’ll set up the table T used to query and modify. Note that we are ordering the data randomly in this table. The CREATE TABLE AS SELECT tends to put the rows in the blocks in the order it fetches them from the query. We’ll just scramble the rows up so they are not artificially sorted in any order, randomizing their distribution:

330 CHAPTER 9 ■ REDO AND UNDO ops$tkyte@ORA10G> create table t 2 as 3 select * 4 from all_objects 5 order by dbms_random.random; Table created. ops$tkyte@ORA10G> alter table t add constraint t_pk primary key(object_id) 2 / Table altered. ops$tkyte@ORA10G> exec dbms_stats.gather_table_stats( user, 'T', cascade=> true ); PL/SQL procedure successfully completed. And now we are ready to do our modifications: ops$tkyte@ORA10G> begin 2 for x in ( select rowid rid from t ) 3 loop 4 update t set object_name = lower(object_name) where rowid = x.rid; 5 commit; 6 end loop; 7 end; 8 / Now, while that is running, we run a query in another session. This query was reading this table T and processing each record. I spent about 1/100 of a second processing each record before fetching the next (simulated using DBMS_LOCK.SLEEP(0.01)). I used the FIRST_ROWS hint in the query to have it use the index we created to read the rows out of the table via the index sorted by OBJECT_ID. Since the data was randomly inserted into the table, we would tend to query blocks in the table rather randomly. This block ran for only a couple of seconds before failing: ops$tkyte@ORA10G> declare 2 cursor c is 3 select /*+ first_rows */ object_name 4 from t 5 order by object_id; 6 7 l_object_name t.object_name%type; 8 l_rowcnt number := 0; 9 begin 10 open c; 11 loop 12 fetch c into l_object_name; 13 exit when c%notfound; 14 dbms_lock.sleep( 0.01 ); 15 l_rowcnt := l_rowcnt+1; 16 end loop;

CHAPTER 9 ■ REDO AND UNDO 329<br />

manually managed undo, which will wrap around <strong>and</strong> reuse undo space as soon as it can. It is<br />

primarily for this reason, the support of the UNDO_RETENTION parameter, that I highly recommend<br />

automatic undo management whenever possible. That single parameter reduces the<br />

possibility of an ORA-01555 error greatly (when it is set appropriately!).<br />

When using manual undo management, it is also important to remember that the probability<br />

of an ORA-01555 error is dictated by the smallest rollback segment in your system, not the<br />

largest <strong>and</strong> not the average. Adding one “big” rollback segment will not make this problem go<br />

away. It only takes the smallest rollback segment to wrap around while a query is processing,<br />

<strong>and</strong> this query st<strong>and</strong>s a chance of an ORA-01555 error. This is why I was a big fan of equi-sized<br />

rollback segments when using the legacy rollback segments. In this fashion, each rollback<br />

segment is both the smallest <strong>and</strong> the largest. This is also why I avoid using “optimally” sized<br />

rollback segments. If you shrink a rollback segment that was forced to grow, you are throwing<br />

away a lot of undo that may be needed right after that. It discards the oldest rollback data<br />

when it does this, minimizing the risk, but still the risk is there. I prefer to manually shrink<br />

rollback segments during off-peak times if at all.<br />

I am getting a little too deep into the DBA role at this point, so we’ll be moving on to the<br />

next case. It’s just important that you underst<strong>and</strong> that the ORA-01555 error in this case is due to<br />

the system not being sized correctly for your workload. The only solution is to size correctly<br />

for your workload. It is not your fault, but it is your problem since you hit it. It is the same as<br />

if you run out of temporary space during a query. You either configure sufficient temporary<br />

space for the system, or you rewrite the queries so they use a plan that does not require temporary<br />

space.<br />

To demonstrate this effect, we can set up a small, but somewhat artificial test. We’ll create<br />

a very small undo tablespace with one session that will generate many small transactions,<br />

virtually assuring us that it will wrap around <strong>and</strong> reuse its allocated space many times—<br />

regardless of the UNDO_RETENTION setting, since we are not permitting the undo tablespace to<br />

grow. The session that uses this undo segment will be modifying a table, T. It will use a full<br />

scan of T <strong>and</strong> read it from “top” to “bottom.” In another session, we will execute a query that<br />

will read the table T via an index. In this fashion, it will read the table somewhat r<strong>and</strong>omly:<br />

it will read row 1, then row 1,000, then row 500, then row 20,001, <strong>and</strong> so on. In this way, we<br />

will tend to visit blocks very r<strong>and</strong>omly <strong>and</strong> perhaps many times during the processing of our<br />

query. The odds of getting an ORA-01555 error in this case are virtually 100 percent. So, in one<br />

session we start with the following:<br />

ops$tkyte@ORA10G> create undo tablespace undo_small<br />

2 datafile size 2m<br />

3 autoextend off<br />

4 /<br />

Tablespace created.<br />

ops$tkyte@ORA10G> alter system set undo_tablespace = undo_small;<br />

System altered.<br />

Now, we’ll set up the table T used to query <strong>and</strong> modify. Note that we are ordering the data<br />

r<strong>and</strong>omly in this table. The CREATE TABLE AS SELECT tends to put the rows in the blocks in the<br />

order it fetches them from the query. We’ll just scramble the rows up so they are not artificially<br />

sorted in any order, r<strong>and</strong>omizing their distribution:

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

Saved successfully!

Ooh no, something went wrong!