Oracle Scratchpad

June 16, 2009

Clean it up

Filed under: Infrastructure — Jonathan Lewis @ 7:08 pm GMT Jun 16,2009

There is some confusion about the expression “clean” in Oracle circles, so I thought I’d write a short note to explain the different ways in which the word may be applied to Oracle blocks. There are five terms to consider:

  1. clean
  2. commit cleanout
  3. block cleanout
  4. delayed block cleanout
  5. delayed logging block cleanout

Clean:

A block (or, to be strictly accurate, a buffered copy of a block) is “clean” if and only if the copy in memory is the same as the version on disc. Conversly, if the copy in memory and the version on disc differ (presumably because something has modified the in-memory copy) then the buffer copy is “dirty”. Moreover, we have to remember that the concepts of “clean” and “dirty” are only relevant to the current copy of the block.

You have to be  a little careful when checking for dirty blocks, though. The buffer header structure (x$bh) includes a column called flag which uses a bit string to tell us about the state of the buffer. Bit zero in this flag is the “buffer_dirty” bit so we can easily check which buffers are considered dirty. There’s a little trap, though. Oracle only needs to write dirty buffers that are also “current” versions (CUR) and you will find that it doesn’t reset the “buffer_dirty” flag when it makes a read-consistent (CR) copy of the block – or in various other circumstances.  So if you’re trying to count the number of dirty buffers in x$bh, don’t forget to restrict your count to those where the “state” column is set to 1 or 2 (XCUR and SCUR)

There is a common misunderstanding about what happens when DBWR (the database writer) writes a block to disc. I have often seen people say that the copy of the block is “flushed” from the cache when the write takes place (i.e. implying that the block disappears from the cache). Most of the time this is not true – the dbwr has two main reasons for writing and only one of those two is followed (I think) by a call to free the buffer that’s just been written.

One reason for writing is simply to keep the data files reasonably up to date; in this case the buffered copy of the block changes from dirty to clean but is not flushed from memory. The other reason is when a session has been searching for a free buffer, fails to find one soon enough, and calls DBWR to make some free space in the buffer cache – and that’s the case when DBWR may flush blocks from memory or, to be accurate, marks the buffer as free after copying them to disc (and I’m not even sure that I’ve ever proved that that’s really true). There are a couple of fairly well-known special cases where blocks reallys flushed from disc after the write: truncating tables, putting tablespaces offline, and the explicit “flush buffer_cache” spring to mind.

Commit Cleanout:

When you modify some data you will make some buffered blocks “dirty”. It is quite possible that the database writer will copy those blocks to disc (marking the buffers “clean”) before you issue your commit. When you issue the commit, your session will update its transaction table slot (which is in an undo segment header block), generating a little redo to describe this action, and then call the log writer (lgwr) to write.

Optionally, your session may also revisit a few of the blocks it has modified (nominally up to 10% of the buffer cache) and mark the associated ITL (interested transaction list) entry in those blocks with the “commit SCN”. It is this activity that is called a commit cleanout. The commit cleanout does not do a complete tidy up on the block (it leaves lock bytes in place, for example), it simply ensures that the next process to see the block knows that your transaction has committed and when it committed. This feature was introduced some around Oracle version 7.3 to reduce block pinging in OPS  (Oracle Parallel Server, the precursor to RAC).

Note that any of the blocks that had previously been written by dbwr will have been made “dirty” again if your sessions does applies a commit cleanout to them, so dbwr will have to write them to disc again eventually. Although a commit cleanout changes blocks it does not create any redo to describe those changes and, strangely, it doesn’t report db block gets for the block vists that apply those changes.

Block Cleanout / Delayed Block Cleanout:

It’s possible that some of the blocks changed by your transaction were written to disc by dbwr and were even flushed from the buffer cache before you issued the commit. Your session will not re-read these blocks in order to do a commit cleanout on them. In fact, if your transaction was quite large and modified a lot of blocks, it’s quite possible that your session will not even do a commit cleanout on all of the blocks that are still in memory – Oracle doesn’t want to make the user wait for a commit to complete,  so it’s a bit lazy about commit cleanout.

At some later point in time another session may read one of those blocks and discover that the ITL includes a transaction that has committed but not been cleaned out. (It can work this out by cross-checking the ITL entry with the relevant transaction table slot in the undo segment header block).

This session will read the commit SCN from the transaction table slot, tidy up the block’s ITL entry, and clear all the related lock bytes.  (And it will do this for all committed transactions it finds on the block).  This process is known as block cleanout, and because this full cleanout mechanism never takes place on the commit it is more commonly known as delayed block cleanout.

The delayed block cleanout operation changes the block so it generates redo – which is why you may see redo being generated on a select statement, especially after a very big update. (Interestingly, Oracle will report db block changes as this happens – but doesn’t record the block visits as db block gets.)

Delayed Logging Block Cleanout

Finally, let’s go back to a block that was subject to commit cleanout. If you query this block you can see the effects of the committed transaction, but since the commit cleanout wrote the commit SCN into its ITL slot you know when the transaction committed and generally don’t need to do anything to tidy the block up as you read it. However if you want to update the block you become responsible for finishing the cleanout of the block – in fact you may even want to re-use that ITL entry and update some of the rows which are still showing a lock byte. So, at this point, you complete the block cleanout, and generate redo that describes not only the changed you are now making but also the earlier commit cleanout.  This process is known as ‘delayed logging’ block cleanout – because the redo log for the commit cleanout has been delayed until this moment.

There are lots more tiny bits of information, odd behaviour in special cases, and peculiarities of statistics reporting that I could go into – but I’ve probably confused enough people already, so I’ll stop there.

48 Comments »

  1. Nice post Jonathan.

    Every time I see anything about dirty blocks I am reminded of an old entry in the appendix (or was it the index – well one of those lists in the back of the book). Anyway, it was in one of the DBA manuals (version 5 or something). I had run across something about Dirty Reads and I was looking it up. The entry said “Dirty Reads – Done Dirt Cheap”. I almost busted a gut laughing. (Actually I’m still chuckling) I always figured it was an AC/DC fan in the documentation group that was able to sneak one by the proof readers.

    Kerry

    Comment by Kerry Osborne — June 17, 2009 @ 3:55 am GMT Jun 17,2009 | Reply

  2. My goodness, Kerry! That made my day! Now I’ll be singing AC/DC all day!

    And Jonathan, this is a great post to add to some training I will be doing in house! Thanks so much!

    Carol

    Comment by Carol D — June 19, 2009 @ 2:32 pm GMT Jun 19,2009 | Reply

  3. Thank you for the great links Jonathan. Everything is clear now as day :).

    BTW. I did make another comment before (it was not published?), but you can disregard it now after posting these links.

    Domagoj

    Comment by Domagoj — June 20, 2009 @ 7:57 pm GMT Jun 20,2009 | Reply

  4. We have a fairly large collection of Oracle manuals in our “Miracle Lex de Haan Memorial Oracle Museum” (or whatever we called it when we founded it a few years ago :) ), including database docs that go back to version 3, so I’ll see if I can find an entry with dirty reads done dirt cheap somewhere.

    Greetings from Mogens (who will be present at the AC/DC concert on Friday at Wembley…)

    Comment by Mogens Nørgaard — June 21, 2009 @ 4:19 am GMT Jun 21,2009 | Reply

  5. Mogens,

    Greetings. I checked the V5 DBA guide and it didn’t have it. (that’s the same doc set as the one I donated to the afore mentioned Museum). One of my co-workers said they thought it was in a newer version than that and he remembered it being in an Architecture manual. Good luck on the search. And have fun at the show. Although I don’t think the bands been quite the same since Bon Scott’s passing (oops, I’m dating myself)

    Kerry

    Comment by Kerry Osborne — June 22, 2009 @ 12:32 am GMT Jun 22,2009 | Reply

  6. [...] Jonathan Lewis-Clean it up [...]

    Pingback by Blogroll Report 12/06/09 – 19/06/09 « Coskan’s Approach to Oracle — June 23, 2009 @ 11:24 am GMT Jun 23,2009 | Reply

  7. [...] cleanout: See this generic note on various uses of the term “clean” in [...]

    Pingback by Glossary « Oracle Scratchpad — June 26, 2009 @ 7:12 pm GMT Jun 26,2009 | Reply

  8. [...]  Chris Dunscombe from SIG committee  did a small presentation about the problem they had with Delayed Cleanout and ORA-1555 problem.  End of his presentation there was a perfect discussion between Joel Goodman [...]

    Pingback by UKOUG DBMS SIG July 2009 « Coskan’s Approach to Oracle — July 2, 2009 @ 12:06 pm GMT Jul 2,2009 | Reply

  9. Jonathan, regarding to your article “Read only tablespaces”. I didnt check 10g, but it seems things has changed in 11g.

    When i change row in that tablespace in one session, and trying to execute alter tablespace readonly in second session it it waites for “unbound tx”. BUT, there is no need to wait “outstanding transactions that started before the call to make the tablespace read only”. If that transactions doesnt change data in that tablespace, conversion to read only happens immediately. Somehow oracle tracks these things now?

    Comment by Alexey — July 6, 2009 @ 8:20 am GMT Jul 6,2009 | Reply

    • Alexey,
      I don’t see this on 11.1.0.6:
      session 1: update table in tablespace test_8k.
      session 2: alter tablespace test_8k read only; — hangs showing TX mode 4 in v$lock, waiting on the transaction from session 1, and continutes only after session 1 commits.

      Similarly
      session 1: update table in tablespace test_8k;
      session 2: alter tablespace users read only; — hangs in the same way.

      Tested in 10g and 11g.

      Comment by Jonathan Lewis — July 9, 2009 @ 6:36 pm GMT Jul 9,2009 | Reply

      • Jonathan, i double checked that again in 11.1.0.7. It is works the same way as i said earlier.
        If it is possible, check that again on 11.1.0.7, please.

        Comment by Alexey — July 10, 2009 @ 5:35 am GMT Jul 10,2009 | Reply

      • Jonathan, i was told by support that It is bug 2227223.
        Filed 14-FEB-2002 in 8.1.7.2.

        Fixed in 11.1.0.7.
        It took 7 years to fix :)

        Comment by Alexey — July 10, 2009 @ 7:29 am GMT Jul 10,2009 | Reply

      • Jonathan, regarding to read only tablespaces. We have found than oracle uses ktutsn_find function to find out the list of tablespaces in wich transaction has made any changes.

        Comment by Alexey — August 14, 2009 @ 10:58 am GMT Aug 14,2009 | Reply

  10. ” This session will read the commit SCN from the transaction table slot, tidy up the block’s ITL entry, and clear all the related lock bytes. (And it will do this for all committed transactions it finds on the block). This process is known as block cleanout, and because this full cleanout mechanism never takes place on the commit it is more commonly known as delayed block cleanout.”

    Is it mean that in delayed block cleanout DBWR doesn’t write all dirty blocks to datafile but writes on datafile header so that it should look like commited?

    Regards,
    Avi

    Comment by Avi — July 31, 2009 @ 1:49 pm GMT Jul 31,2009 | Reply

    • Avi,
      Your question doesn’t seem to have anything to do with the paragraph you have quoted.
      I think you have to read the notes again, but remembering the following:

      DBWR has nothing to do with commits, or block cleanout – it simply writes buffers to disk, and a block is clean if the in-memory copy is identical to the on-disk copy.

      A transaction is committed if and only if its transaction table entry, which will be in the header block of an undo segment, says that it has been committed.

      Comment by Jonathan Lewis — August 6, 2009 @ 4:15 pm GMT Aug 6,2009 | Reply

  11. Respected Sir;

    You mentioned that:

    “Note that any of the blocks that had previously been written by dbwr will have been made “dirty” again and dbwr will have to write them to disc again eventually.”

    Assume I generated some dirty blocks and checkpoint occured(before the commit) and these dirty blocks are written to datafiles and become clean.

    When I issue commit, Do these block become dirty again? I have some doubts

    Comment by Scofield — August 4, 2009 @ 8:57 am GMT Aug 4,2009 | Reply

  12. Sir,
    Does commit generate redo? I have some doubts during readong commit cleanout topic.

    “When you issue the commit, your session will update its transaction table slot (which is in an undo segment header block), generating a little redo to describe this action.”
    “Although a commit cleanout changes blocks it does not create any redo to describe those changes – and it doesn’t report db block gets for the block vists that do the changes.”

    Comment by Scofield — August 8, 2009 @ 7:38 am GMT Aug 8,2009 | Reply

    • Scofield:

      If you’re not prepared to voice your doubts I won’t be able to address them. Quoting a couple of sentences that I’ve written doesn’t tell me anything about the way you’re thinking.

      Comment by Jonathan Lewis — August 10, 2009 @ 10:16 pm GMT Aug 10,2009 | Reply

      • I think he was meaning to say, “It looks like you said a Commit leads to a little redo generation, but you also say a Commit does not lead to redo generation”.

        But I think he’s confusing redo associated with the transaction slot following a Commit, and non-redo associated with a commit cleanout.

        Comment by Nigel — November 9, 2009 @ 1:00 pm GMT Nov 9,2009 | Reply

        • Nigel,

          Possible, but we may never know.

          But it’s possible that by asking him to state the source of his doubt I encouraged him to read the text more carefully and note that he was confusing the actions of the “commit” with the actions of the “commit cleanout” and answer his own question.

          Comment by Jonathan Lewis — November 9, 2009 @ 6:29 pm GMT Nov 9,2009

  13. The “Dirty Reads (Done Dirt Cheap)” was certainly present in the Oracle 7 manual set back in 1996. I can’t remember if it was in the Concepts or DBA Guide now, but I was so impressed with it that I “archived” a copy of that manual from my place of work at the time, so I can go and check :)

    Oracle seem to have lost their sense of humour in the interim!

    Simon

    Comment by Simon Holt — November 6, 2009 @ 3:13 pm GMT Nov 6,2009 | Reply

  14. Sir,

    It would be great if you could also explain the ITL structure and transaction table structure in detail.

    I have one doubt regrading the lock bits. Where do they exist? In the ITL or in the row of the block?

    Many Thanks

    Comment by Hashmi — March 8, 2010 @ 5:06 pm GMT Mar 8,2010 | Reply

    • Hashmi,

      Have a look, through the Oracle Glossary (see “special links” in the panel to the right) for ITL, Transaction Table, and Lock Byte.
      This may answer your questions.

      See also the articles listed in my comment above to Carol D, especially the one on block cleanout.

      Comment by Jonathan Lewis — March 8, 2010 @ 6:07 pm GMT Mar 8,2010 | Reply

  15. [...] the thread which can be true or false,  but when I first read the question I immediately think if delayed block cleanout have the similar effect on flashback log generation as well, so I [...]

    Pingback by Flashback log generation with select statements « Coskan’s Approach to Oracle — May 27, 2010 @ 3:51 pm GMT May 27,2010 | Reply

  16. Jonathan,

    I am confuse with your statement above,

    “At some later point in time another session may read one of those blocks and discover that the ITL includes a transaction that has committed but not been cleaned out. (It can work this out by cross-checking the ITL entry with the relevant transaction table slot in the undo segment header block).”

    My confusion, when the relevant transaction table slot can’t be found in the time the read is happened because it’s undo header block being override by other session’s transaction, how Oracle could cross-checking the ITL entry with the relevant transaction table slot in the undo segment header block ?

    Please clear up my confusion, Thank you.

    Comment by Rendy — June 1, 2010 @ 4:18 pm GMT Jun 1,2010 | Reply

    • Rendy,

      There are many little details of undo handling and read-consistency which make it very hard to describe the essential features well enough for most cases.

      In this case I left out the detail that the number of transaction table slots in an undo segment header block is quite small (in the order of tens), so they have to be re-used very frequently – and they can only be re-used after the transaction has been committed.

      Point 1: When a new transaction re-uses a transaction table slot, it copies the information from that slot into its first undo record, so the old content of the transaction table slot is not lost.

      Point 2: When some other session looks at the transaction slot to see if the (older) transaction it is interested in has committed it can deduce that the transaction has committed because a newer transaction is using the slot.

      Point 3: If the other session needs to know WHEN the older transaction committed, it can go to the first undo record of the new transaction and use it to build an older copy of the transaction table. (And if it find that it still can’t see the correct transaction in the transaction slot it goes to the first undo record of the transaction it finds, and so on – although it’s a little more subtle than that.)

      If you are worried about how much work Oracle does trying to rebuild the state of old transaction slots, there are two statistics to help:

      transaction tables consistent reads - undo records applied
      transaction tables consistent read rollbacks
      

      The second one tell you how many times a session followed a chain of undo records to find a commit time; the first one tells you the total number of undo records it followed to do this work.

      Comment by Jonathan Lewis — June 2, 2010 @ 7:54 am GMT Jun 2,2010 | Reply

  17. [...] block (line 5: ktudh) as we acquire a “transaction table slot” (see my glossary, and “cleanout”) specifically slot 0×0016, which we stamp with sequence number 0x00001a69. The final change [...]

    Pingback by Redo « Oracle Scratchpad — January 3, 2011 @ 7:40 pm GMT Jan 3,2011 | Reply

  18. Hello,

    I post this information hoping it is useful to other users of this article.

    I found the two statistics “immediate (CR) block cleanout applications” and “deferred (CURRENT) block cleanout applications”. The (few) experiments I did on a 11.2. database indicate that “immediate (CR) block cleanout applications” counts the number of blocks that were subject to delayed block cleanout while “deferred (CURRENT) block cleanout applications” counts the number of blocks that were subject to delayed logging block cleanout.

    The description of these statistics in the Oracle Database Reference could be understood in that way as well.

    kind regards
    Martin

    Comment by Martin Maletinsky — September 12, 2012 @ 8:11 am GMT Sep 12,2012 | Reply

  19. Hi Jonathan,
    This is absolute gem , I was looking for this information for quite some time and this article has clarified all the doubts I had.
    Thanks a ton.

    Comment by Navin Kumar — October 25, 2012 @ 4:47 am GMT Oct 25,2012 | Reply

  20. [...] best guess was delayed block cleanout . Quick twitter survey added another vote for cleanouts and a suggestion to check for [...]

    Pingback by Select Statement Generating Redo and Other Mysteries of Exadata | The Pythian Blog — October 31, 2012 @ 4:54 am GMT Oct 31,2012 | Reply

  21. Here’s a little detail I’ve been meaning to check for ages.

    When a session commits it may apply commit cleanout (see above) to some of the blocks that is has changed in the course of the transaction. But I’ve never checked if this commit cleanout takes place BEFORE the session posts lgwr or AFTER. I think I may even have a line in Oracle Core (though I can’t find it at present) which admits to never having checked.

    I finally decided to take a closer look at it tody – the answer is that (in 10.2.0.3, at least, which is the instance I had at hand) the commit cleanout takes place before the call to lgwr.

    Method:
    Session 1: update a single row in a table 1,000 times (to get past any special cases with private redo)
    Session 2: flush buffer_cache, dump the block
    Session 3: suspend the log writer (oradebug suspend {pid})
    Session 1: commit — which hangs because the log writer isn’t going to notice the post
    Session 2: dump the block — you may have to wait a while, or read a raw dump, but you’ll see the commit cleanout has happened
    Session 3: resume the log writer (oradebug resume {pid})

    Don’t try this on anything other than a private database – users tend to get cross when the database stops.

    Comment by Jonathan Lewis — December 31, 2012 @ 1:52 pm GMT Dec 31,2012 | Reply

  22. [...] on that object are dirty again. This is due to the commit-cleanout [link to Jonathan Lewis blog http://jonathanlewis.wordpress.com/2009/06/16/clean-it-up/%5D occurring on 10% worth of buffers. Because my transaction lasts so long, Oracle attempts to [...]

    Pingback by 11.2.0.3 Strange statistic, large transactions, dirty buffers and “direct path read” « Nigel Noble's Oracle Blog — January 10, 2013 @ 5:27 pm GMT Jan 10,2013 | Reply

  23. “The delayed block cleanout operation changes the block so it generates redo – which is why you may see redo being generated on a select statement, especially after a very big update”
    If the block cleanout only changes the transactional stuff rather than the data, then why is redo generated? Is there some recursive SQL being run?

    Comment by Neil — February 20, 2013 @ 11:28 am GMT Feb 20,2013 | Reply

    • From page 49 of Oracle Core, I have learned that it’s not just a change to the data in a block that needs to be logged, rather ANY change to a block must be logged.

      Comment by Neil — March 1, 2013 @ 12:15 pm GMT Mar 1,2013 | Reply

      • Neil,

        Sorry, I managed to miss your comment the first time around.
        Glad you found the answer in Oracle Core. Yes, every change to the data files ends up in the redo log files – although some of the “internal” changes are not protected by undo.

        Comment by Jonathan Lewis — March 1, 2013 @ 7:42 pm GMT Mar 1,2013 | Reply

  24. Hi Jonathan, Firstly thanks for a good article as you do always. I need a clarity from you on the behavior of Oracle. The scenario is, you have a block that was dirty and moved to data file (i.e due to a checkpoint) before a COMMIT is issued. Per your article, when the user issues COMMIT for the changes made on the before said dirty block, Oracle would update only the Undo segment and consider this has been done. So we now have un-committed block that was moved to data file and Undo segment’s transaction list updated with the COMMIT event. As this is a committed transaction, the entry in Undo segment is already expired and shall be re-used by another transaction. Consider the Undo segment associated with this transaction has been reused by another session. Now we have lost the undo segment information and the data block in the data file still has the before commit image (i.e ITL is still not updated). Now if a user is trying to access a record from this block, how would Oracle cleanout the data block, as the undo segment is already lost and Oracle couldn’t confirm if the block data is committed or not.

    Comment by Vivek Nagarajan — February 2, 2014 @ 7:47 pm GMT Feb 2,2014 | Reply

  25. Hello Sir,

    Optionally, your session may also revisit a few of the blocks it has modified (nominally up to 10% of the buffer cache) and mark the associated ITL (interested transaction list) entry in those blocks with the “commit SCN”.

    Could you please throw some light into above quote? Why the session may also revisit a few of the blocks? Shouldn’t it visits all the blocks. I mean why “a few”?
    Also what do you mean by the “nominally up to 10% of the buffer cache”?

    Thanks for your help. You are the best!

    Regards
    Charlie

    Comment by Charlie — April 3, 2014 @ 6:13 am GMT Apr 3,2014 | Reply

    • If you want more discussion on this point it’s in Oracle Core.

      The “few” is simply to minimise the amount of time it takes for a commit to complete – historically Oracle didn’t revisit ANY of the changed blocks, but this had an undesirable side-effect in RAC (or OPS – Oracle Parallel Server – as it then was).

      It’s “nominally” 10% because Oracle may stop before getting to the 10% limit. The session won’t re-read blocks to clean them if they’ve been flushed out of memory, and if it fails on too many blocks (for any reason, but flushed from memory is a good one) it will simply stop trying to clean blocks.

      Comment by Jonathan Lewis — April 3, 2014 @ 6:15 pm GMT Apr 3,2014 | Reply

  26. Reblogged this on Weishan's Oracle Blog and commented:
    An extremely good read for understanding how Oracle deals with clean/dirty buffer using UNDO tablespace. It’s pretty confusing though!

    Comment by Wei Shan — October 20, 2014 @ 6:34 pm GMT Oct 20,2014 | Reply

  27. Thanks for sharing your thoughts about pic. Regards

    Comment by reklama — October 22, 2014 @ 4:55 am GMT Oct 22,2014 | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Theme: Rubric. Get a free blog at WordPress.com

Follow

Get every new post delivered to your Inbox.

Join 4,306 other followers