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.)Clean it up | Oracle Scratchpad