Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
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.
- Page 326: CHAPTER 8 ■ TRANSACTIONS 281 scot
- Page 329 and 330: 284 CHAPTER 9 ■ REDO AND UNDO cri
- Page 331 and 332: 286 CHAPTER 9 ■ REDO AND UNDO Fir
- Page 333 and 334: 288 CHAPTER 9 ■ REDO AND UNDO The
- Page 335 and 336: 290 CHAPTER 9 ■ REDO AND UNDO We
- Page 337 and 338: 292 CHAPTER 9 ■ REDO AND UNDO Wha
- Page 339 and 340: 294 CHAPTER 9 ■ REDO AND UNDO row
- Page 341 and 342: 296 CHAPTER 9 ■ REDO AND UNDO If
- Page 343 and 344: 298 CHAPTER 9 ■ REDO AND UNDO ops
- Page 345 and 346: 300 CHAPTER 9 ■ REDO AND UNDO Inv
- Page 347 and 348: 302 CHAPTER 9 ■ REDO AND UNDO The
- Page 349 and 350: 304 CHAPTER 9 ■ REDO AND UNDO 41
- Page 351 and 352: 306 CHAPTER 9 ■ REDO AND UNDO ins
- Page 353 and 354: 308 CHAPTER 9 ■ REDO AND UNDO So,
- Page 355 and 356: 310 CHAPTER 9 ■ REDO AND UNDO ops
- Page 357 and 358: 312 CHAPTER 9 ■ REDO AND UNDO ops
- Page 359 and 360: 314 CHAPTER 9 ■ REDO AND UNDO •
- Page 361 and 362: 316 CHAPTER 9 ■ REDO AND UNDO ...
- Page 363 and 364: 318 CHAPTER 9 ■ REDO AND UNDO •
- Page 365 and 366: 320 CHAPTER 9 ■ REDO AND UNDO bac
- Page 367 and 368: 322 CHAPTER 9 ■ REDO AND UNDO As
- Page 369 and 370: 324 CHAPTER 9 ■ REDO AND UNDO ops
- Page 371 and 372: 326 CHAPTER 9 ■ REDO AND UNDO wil
- Page 373 and 374: 328 CHAPTER 9 ■ REDO AND UNDO Thi
- Page 375: 330 CHAPTER 9 ■ REDO AND UNDO ops
- Page 379 and 380: 334 CHAPTER 9 ■ REDO AND UNDO Tha
- Page 381 and 382: 336 CHAPTER 9 ■ REDO AND UNDO tou
- Page 383 and 384: 338 CHAPTER 10 ■ DATABASE TABLES
- Page 385 and 386: 340 CHAPTER 10 ■ DATABASE TABLES
- Page 387 and 388: 342 CHAPTER 10 ■ DATABASE TABLES
- Page 389 and 390: 344 CHAPTER 10 ■ DATABASE TABLES
- Page 391 and 392: 346 CHAPTER 10 ■ DATABASE TABLES
- Page 393 and 394: 348 CHAPTER 10 ■ DATABASE TABLES
- Page 395 and 396: 350 CHAPTER 10 ■ DATABASE TABLES
- Page 397 and 398: 352 CHAPTER 10 ■ DATABASE TABLES
- Page 399 and 400: 354 CHAPTER 10 ■ DATABASE TABLES
- Page 401 and 402: 356 CHAPTER 10 ■ DATABASE TABLES
- Page 403 and 404: 358 CHAPTER 10 ■ DATABASE TABLES
- Page 405 and 406: 360 CHAPTER 10 ■ DATABASE TABLES
- Page 407 and 408: 362 CHAPTER 10 ■ DATABASE TABLES
- Page 409 and 410: 364 CHAPTER 10 ■ DATABASE TABLES
- Page 411 and 412: 366 CHAPTER 10 ■ DATABASE TABLES
- Page 413 and 414: 368 CHAPTER 10 ■ DATABASE TABLES
- Page 415 and 416: 370 CHAPTER 10 ■ DATABASE TABLES
- Page 417 and 418: 372 CHAPTER 10 ■ DATABASE TABLES
- Page 419 and 420: 374 CHAPTER 10 ■ DATABASE TABLES
- Page 421 and 422: 376 CHAPTER 10 ■ DATABASE TABLES
- Page 423 and 424: 378 CHAPTER 10 ■ DATABASE TABLES
- Page 425 and 426: 380 CHAPTER 10 ■ DATABASE TABLES
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.