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 331 17 close c; 18 exception 19 when others then 20 dbms_output.put_line( 'rows fetched = ' || l_rowcnt ); 21 raise; 22 end; 23 / rows fetched = 253 declare * ERROR at line 1: ORA-01555: snapshot too old: rollback segment number 23 with name "_SYSSMU23$" too small ORA-06512: at line 21 As you can see, it got to process only 253 records before failing with the ORA-01555: snapshot too old error. To correct this, we want to make sure two things are done: • UNDO_RETENTION is set in the database to be at least long enough for this read process to complete. That will allow the database to grow the undo tablespace to hold sufficient undo for us to complete. • The undo tablespace is allowed to grow or you manually allocate more disk space to it. For this example, I have determined my long-running process takes about 600 seconds to complete. My UNDO_RETENTION is set to 900 (this is in seconds, so the undo retention is about 15 minutes). I altered the undo tablespace’s data file to permit it to grow by 1MB at a time, up to 2GB in size: ops$tkyte@ORA10G> column file_name new_val F ops$tkyte@ORA10G> select file_name 2 from dba_data_files 3 where tablespace_name = 'UNDO_SMALL'; FILE_NAME ------------------------------ /home/ora10g/oradata/ora10g/OR A10G/datafile/o1_mf_undo_sma_1 729wn1h_.dbf ops$tkyte@ORA10G> alter database 2 datafile '&F' 3 autoextend on 4 next 1m 5 maxsize 2048m; old 2: datafile '&F' new 2: datafile '/home/ora10g/.../o1_mf_undo_sma_1729wn1h_.dbf' Database altered.

332 CHAPTER 9 ■ REDO AND UNDO When I ran the processes concurrently again, both ran to completion. The undo tablespace’s data file grew this time, because it was allowed to and the undo retention I set up said to: ops$tkyte@ORA10G> select bytes/1024/1024 2 from dba_data_files 3 where tablespace_name = 'UNDO_SMALL'; BYTES/1024/1024 --------------- 11 So, instead of receiving an error, we completed successfully, and the undo grew to be large enough to accommodate our needs. It is true that in this example, getting the error was purely due to the fact that we read the table T via the index and performed random reads all over the table. If we had full scanned the table instead, there is a good chance we would not get the ORA-01555 in this particular case. This is because both the SELECT and UPDATE would have been full scanning T, and the SELECT could most likely race ahead of the UPDATE during its scan (the SELECT just has to read, but the UPDATE must read and update and therefore could go slower). By doing the random reads, we increase the probability that the SELECT will need to read a block, which the UPDATE modified and committed many rows ago. This just demonstrates the somewhat insidious nature of ORA-01555. Its occurrence depends on how concurrent sessions access and manipulate the underlying tables. Delayed Block Cleanout This cause of the ORA-01555 error is hard to eliminate entirely, but it is rare anyway, as the circumstances under which it occurs do not happen frequently (at least not in Oracle8i and above anymore). We have already discussed the block cleanout mechanism, but to summarize, it is the process whereby the next session to access a block after it has been modified may have to check to see if the transaction that last modified the block is still active. Once the process determines that the transaction is not active, it cleans out the block so that the next session to access it does not have to go through the same process again. To clean out the block, Oracle determines the undo segment used for the previous transaction (from the blocks header) and then determines if the undo header indicates whether it has been committed or not. This confirmation is accomplished in one of two ways. One way is that Oracle can determine that the transaction committed a long time ago, even though its transaction slot has been overwritten in the undo segment transaction table. The other way is that the COMMIT SCN is still in the transaction table of the undo segment, meaning the transaction committed a short time ago, and its transaction slot hasn’t been overwritten. To receive the ORA-01555 error from a delayed block cleanout, all of the following conditions must be met: • A modification is made and COMMITed, and the blocks are not cleaned out automatically (e.g., it modified more blocks than can fit in 10 percent of the SGA block buffer cache). • These blocks are not touched by another session and will not be touched until our unfortunate query (displayed shortly) hits it.

332<br />

CHAPTER 9 ■ REDO AND UNDO<br />

When I ran the processes concurrently again, both ran to completion. The undo tablespace’s<br />

data file grew this time, because it was allowed to <strong>and</strong> the undo retention I set up<br />

said to:<br />

ops$tkyte@ORA10G> select bytes/1024/1024<br />

2 from dba_data_files<br />

3 where tablespace_name = 'UNDO_SMALL';<br />

BYTES/1024/1024<br />

---------------<br />

11<br />

So, instead of receiving an error, we completed successfully, <strong>and</strong> the undo grew to be large<br />

enough to accommodate our needs. It is true that in this example, getting the error was purely<br />

due to the fact that we read the table T via the index <strong>and</strong> performed r<strong>and</strong>om reads all over the<br />

table. If we had full scanned the table instead, there is a good chance we would not get the<br />

ORA-01555 in this particular case. This is because both the SELECT <strong>and</strong> UPDATE would have been<br />

full scanning T, <strong>and</strong> the SELECT could most likely race ahead of the UPDATE during its scan (the<br />

SELECT just has to read, but the UPDATE must read <strong>and</strong> update <strong>and</strong> therefore could go slower).<br />

By doing the r<strong>and</strong>om reads, we increase the probability that the SELECT will need to read a<br />

block, which the UPDATE modified <strong>and</strong> committed many rows ago. This just demonstrates the<br />

somewhat insidious nature of ORA-01555. Its occurrence depends on how concurrent sessions<br />

access <strong>and</strong> manipulate the underlying tables.<br />

Delayed Block Cleanout<br />

This cause of the ORA-01555 error is hard to eliminate entirely, but it is rare anyway, as the circumstances<br />

under which it occurs do not happen frequently (at least not in <strong>Oracle</strong>8i <strong>and</strong><br />

above anymore). We have already discussed the block cleanout mechanism, but to summarize,<br />

it is the process whereby the next session to access a block after it has been modified<br />

may have to check to see if the transaction that last modified the block is still active. Once the<br />

process determines that the transaction is not active, it cleans out the block so that the next<br />

session to access it does not have to go through the same process again. To clean out the<br />

block, <strong>Oracle</strong> determines the undo segment used for the previous transaction (from the blocks<br />

header) <strong>and</strong> then determines if the undo header indicates whether it has been committed or<br />

not. This confirmation is accomplished in one of two ways. One way is that <strong>Oracle</strong> can determine<br />

that the transaction committed a long time ago, even though its transaction slot has<br />

been overwritten in the undo segment transaction table. The other way is that the COMMIT SCN<br />

is still in the transaction table of the undo segment, meaning the transaction committed a<br />

short time ago, <strong>and</strong> its transaction slot hasn’t been overwritten.<br />

To receive the ORA-01555 error from a delayed block cleanout, all of the following conditions<br />

must be met:<br />

• A modification is made <strong>and</strong> COMMITed, <strong>and</strong> the blocks are not cleaned out automatically<br />

(e.g., it modified more blocks than can fit in 10 percent of the SGA block buffer cache).<br />

• These blocks are not touched by another session <strong>and</strong> will not be touched until our<br />

unfortunate query (displayed shortly) hits it.

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

Saved successfully!

Ooh no, something went wrong!