Oracle Scratchpad

May 5, 2010

Row count 2

Filed under: Infrastructure,Troubleshooting — Jonathan Lewis @ 7:42 pm BST May 5,2010

Following my notes about counting rows in blocks, someone emailed me to ask how the query I’d published would deal with migrated rows. Remember, a migrated row is one that has been moved in its entirety to a different block because an update to the row resulted in the row needing more space than was currently available in its original block.

The answer is simple – my query doesn’t see that the content of the row is in a new location, it only sees the ‘head piece’ row directory entry. To clarify this point I’ve set up some data and then extracted a few details from a pair of block dumps. I created a table with just two (big) rows in the first block, then updated the second row to make it migrate to the second block in the table (I was using freelist management, not ASSM, so the behaviour was predictable).

The first extract is from the block dump of the first block after the update and shows the row directory and the start of each row in the “row heap” (that’s a term I’ve just invented – I think). Notice how the flag byte (fb) on row 1 has just the H bit (head piece) set but its F bit (first row piece) and L bit (last row piece) not set. Compare this with row 0 which has the H, F and L bits set. We also see that the row itself carries the nrid (next rowid ) value that points to the next row piece for this row.

0xe:pti[0]	nrow=2	offs=0
0x12:pri[0]	offs=0xc0c
0x14:pri[1]	offs=0x3ce
tab 0, row 0, @0xc0c
tl: 5012 fb: --H-FL-- lb: 0x0  cc: 3
col  0: [ 2]  c1 02
col  1: [2500]
 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
tab 0, row 1, @0x3ce
tl: 9 fb: --H----- lb: 0x2  cc: 0
nrid:  0x0140120b.0

The second extract is from the dump of the second block in the table. The row directory shows just one row in the block, but when we check the flag byte for that row we see that the H bit is not set while the F and L bits are – this tells us that the row piece is the whole row but it has been migrated from another location. The row entry itself holds the hrid (head rowid) telling us where the row came from.

0xe:pti[0]	nrow=1	offs=0
0x12:pri[0]	offs=0xde2
tab 0, row 0, @0xde2
tl: 4518 fb: ----FL-- lb: 0x2  cc: 3
hrid: 0x0140120a.1
col  0: [ 2]  c1 03
col  1: [2000]
 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42

The flag information tells Oracle what type of row piece is identified by each row directory entry – so when I run my row counting query against this table it can (and will) report two rows in the first block and no rows in the second block.

This complication is a detail I didn’t think of when I was on the client site; and this omission is the type of “blinkered vision” that can appear at all levels of Oracle skill: if there’s no hint that you need to check for special cases it’s very easy to forget that such special cases might be relevant.

1 Comment »

  1. […] you’ve looked at the dump details for chained or migrated rows before, you’ll be familiar with the values in the “flag byte” (fb) – the F […]

    Pingback by Compression Units « Oracle Scratchpad — July 20, 2012 @ 6:04 am BST Jul 20,2012 | Reply

RSS feed for comments on this post. TrackBack URI

Comments and related questions are welcome.

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

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

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Powered by