05.11.2015 Views

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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

316<br />

CHAPTER 9 ■ REDO AND UNDO<br />

...<br />

...<br />

36484 redo size<br />

500 rows processed<br />

So, this SELECT generated about 35KB of redo during its processing. This represents the<br />

block headers it modified during the full scan of T. DBWR will be writing these modified blocks<br />

back out to disk at some point in the future. Now, if I run the query again<br />

ops$tkyte@ORA10G> select *<br />

2 from t;<br />

500 rows selected.<br />

Statistics<br />

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

...<br />

0 redo size<br />

...<br />

500 rows processed<br />

ops$tkyte@ORA10G> set autotrace off<br />

I see that no redo is generated—the blocks are all clean.<br />

If we were to rerun the preceding example with the buffer cache set to hold at least 5,000<br />

blocks, we’ll find that we generate little to no redo on any of the SELECTs—we will not have to<br />

clean dirty blocks during either of our SELECT statements. This is because the 500 blocks we<br />

modified fit comfortably into 10 percent of our buffer cache, <strong>and</strong> we are the only users. There<br />

is no one else mucking around with the data, <strong>and</strong> no one else is causing our data to be flushed<br />

to disk or accessing those blocks. In a live system, it will be normal for at least some of the<br />

blocks to not be cleaned out sometimes.<br />

This behavior will most affect you after a large INSERT (as just demonstrated), UPDATE, or<br />

DELETE—one that affects many blocks in the database (anything more than 10 percent of the<br />

size of the cache will definitely do it). You will notice that the first query to touch the block<br />

after this will generate a little redo <strong>and</strong> dirty the block, possibly causing it to be rewritten if<br />

DBWR had already flushed it or the instance had been shut down, clearing out the buffer cache<br />

altogether. There is not too much you can do about it. It is normal <strong>and</strong> to be expected. If <strong>Oracle</strong><br />

did not do this deferred cleanout of a block, a COMMIT could take as long to process as the<br />

transaction itself. The COMMIT would have to revisit each <strong>and</strong> every block, possibly reading<br />

them in from disk again (they could have been flushed).<br />

If you are not aware of block cleanouts <strong>and</strong> how they work, it will be one of those mysterious<br />

things that just seems to happen for no reason. For example, say you UPDATE a lot of data<br />

<strong>and</strong> COMMIT. Now you run a query against that data to verify the results. The query appears to<br />

generate tons of write I/O <strong>and</strong> redo. It seems impossible if you are unaware of block cleanouts;<br />

it was to me the first time I saw it. You go <strong>and</strong> get someone to observe this behavior with you,<br />

but it is not reproducible, as the blocks are now “clean” on the second query. You simply write<br />

it off as one of those database mysteries.

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

Saved successfully!

Ooh no, something went wrong!