FAQ
This happens when a database is migrated from 7 to 8.0 when absolute
and relative filenumbers were introduced.
see also http://www.ora600.be/DUDE_PRIMER.pdf chapter 7.1

Snippet starts here ----------------------------------------->

7.1 How do we know this was once an Oracle 7 beauty

In Oracle 6 there were only 5 to 6 bits used for the file number. So only a maximum of
2^5-1 (31) or 2^6-1 (63) datafiles could be used (database wide).
In Oracle 7 this changed to 10bits or 2^10-1 (1023) datafiles (database wide). However,
because of backward compatibility with Oracle 6 an encoding scheme was introduced
splitting up the 10bits for file number into 6 and 4 bits and wrapping them around. It
really depends on the platform. On intel windows and IBM AIX for example, I’ve seen
an 8/2 split.

SVRMGR> select dump(chartorowid('00000000.0000.0001')) from dual;
DUMP(CHARTOROWID('0000000

Typ=69 Len=6: 1,0,0,0,0,0
1 row selected.

SVRMGR> select dump(chartorowid('00000000.0000.ffff')) from dual;
DUMP(CHARTOROWID('00000000.00

Typ=69 Len=6: 255,192,0,0,0,0
1 row selected.

This means that the first file# is :

00000001 00000000 00000000 00000000 -> file# 1

And the maximum file# is :
11111111 11000000 00000000 00000000 -> file# 1023

So the 10bits encoding scheme is like this :
LLLL LLLL HH

Where L is the low order bits
And H the high order bits

Now let’s open DUDE on a series of these datafiles :

DUDE> Initialising ...
DUDE> Init : creating filenumber map ...
DUDE> Scanning tablespace SYSTEM : BLOCKSIZE = 2048
DUDE> File : G:\sys1orcl.ora resolves to number : 4
DUDE> File : G:\sys2.ora resolves to number : 40

You’ll notice that sys1orcl.ora which is basically the first file of the database has file#
equal to 4. And we know that sys2.ora had file# equal to 10. How’s that possible ?
File# 1 = 0000 0001 00 (LLLL LLLL HH) EQUALS 4 in Oracle 8 DBA format
File# 10 = 0000 1010 00 (LLLL LLLL HH) EQUALS 40 in Oracle 8 DBA format

It’s clear that using the Oracle 8 DBA format encoding on the Oracle 7 wrapped DBA
format, results in different file numbers. Basically, the file number shifted 2 bits to the
left (or x2x2). This is of course platform specific, but if the first file of SYSTEM has a
file number that is a multiple of 2, you probably have a migrated database.
So what happened when Oracle 8.0 came along and introduced 2^10-1 or 1023 datafiles
per tablespace ! Well – the DBA format stayed the same. However, the file numbers
became relative to the tablespace. So 2 datafiles of the same database could have
potentially the same file number, but belong to 2 different tablespaces.
What happened to the Oracle 7 (absolute) file numbers when it was migrated to Oracle
8. Surely, the mig utility didn’t update the DBA for all blocks ?
Let’s check out an Oracle 7 database :

SVRMGR> desc file$
Column Name Null? Type

------------------------------ -------- ----

FILE# NOT NULL NUMBER

STATUS$ NOT NULL NUMBER

BLOCKS NOT NULL NUMBER

TS# NOT NULL NUMBER

SVRMGR> select file#, ts# from file$;
FILE# TS#

---------- ----------
1 0
2 1
3 2
4 3
5 8
6 9
7 10
8 7
9 11
10 0
10 rows selected.

Ok – looks logical – we see that tablespace TS#=0 or SYSTEM has 2 datafiles with
file#=1 and file#=10.

Let’s do the same after a migration to 8.0 :
SVRMGR> desc file$
Column Name Null? Type

------------------------------ -------- ----

FILE# NOT NULL NUMBER

STATUS$ NOT NULL NUMBER

BLOCKS NOT NULL NUMBER

TS# NUMBER

RELFILE# NUMBER

MAXEXTEND NUMBER

INC NUMBER

CRSCNWRP NUMBER

CRSCNBAS NUMBER

OWNERINSTANCE VARCHAR2(30)

SPARE1 NUMBER

SPARE2 NUMBER

SPARE3 VARCHAR2(1000)

SPARE4 DATE

SVRMGR> select file#,ts# from file$;
FILE# TS#

---------- ----------
1 0
2 1
3 2
4 3
5 8
6 9
7 10
8 7
9 11
10 0
10 rows selected.

So – the file# for the datafiles stayed the same. But we can see an add column in file$ -
relfile# :

SVRMGR> select file#,relfile#,ts# from file$;
FILE# RELFILE# TS#

---------- ---------- ----------
1 4 0
2 8 1
3 12 2
4 16 3
5 20 8
6 24 9
7 28 10
8 32 7
9 36 11
10 40 0
10 rows selected.

Here we can clearly see the 2bit shift to the left – the Oracle 7 absolute filenumber
became an Oracle 8 relative filenumber.
So the mig utility did not have to :
- update the DBA in a block
- row addresses in chained and migrated rows

<----------------------------------------- Snippet ends here

Cheers,
Kurt
----- Oorspronkelijk bericht -----
Van
: Mathias Magnusson
Verzonden
: vrijdag, april
10, 2009 10:43 AM
Aan
: oracle-l@freelists.org
Onderwerp
: Fwd: Decoding rowid in a datablock.
I'm trying to document how rowid is used by Oracle and intend to use it for
a presentation on rowid and how it is used by Oracle. Anyway, I found one
thing I feel I should document better, but I cannot find anything about.

Looking at the rowid in a block dump it has a format like 01 00 03 00 00 00.
I believe I've found evidence that this makes it 010 for file, 00300 for
block and 0000 for row. Block becomes 768 which is exactly what I knew it
would be, it is also the only row so 0000 for row is correct. The issue is
the file number. I know it is 4, but 010 is 16 converted to decimal. I think
I have found indications that it needs to be divided by 4. That of course
gets me the correct value.

The question is, is this correct?

Is this documented somewhere? What are the three numbers skipped in the file
id in the rowid used for (it would seem that the file id part of a rowid in
a block would never contain the value 1, 2, or 3)?

Mathias
--
http://www.freelists.org/webpage/oracle-l

Search Discussions

  • Kurt Van Meerbeeck at Apr 10, 2009 at 3:12 pm
    I'm sorry - I assumed you were talking about the system datafile having file# 4.

    Anyways - in short - the extended rowid is data objectid + rdba + slot in row directory.
    dataobjectid = 4bytes
    (r)dba = 4bytes
    slot = 2 bytes
    so total 10bytes

    You mention "01 00 03 00 00 00" in your mail.
    That's 6bytes - so I'm guessing you're referring to the pointer part in a row header of a migrated or chained row ?
    If so - that consists of dba+slot.
    The dba contains the file# and can be decoded as follows:
    ( dba[ 0 ] << 2 ) + ( dba[ 1 ] >> 6 )
    So let's take the first 2 bytes of your example

    in hex 01 00
    in binary 0000 0001 0000 0000
    shift left 2 00 000100 0000 0000
    shift right 6 00 000100 00

    add byte 1+2 00 000100+00 = 00000100 + 00 = 00000100 or in hex 0x04.

    I hope this helped (and I hope I didn't make any mistakes here;-) )

    cheers,
    Kurt Van Meerbeeck
    ----- Oorspronkelijk bericht -----
    Van
    : Mathias Magnusson
    Verzonden
    : vrijdag, april
    10, 2009 02:29 PM
    Aan
    : kurtvm_at_pandora.be
    Onderwerp
    : Re: : Decoding rowid in a datablock.
    Kurt,

    The explanation is good, but this database was never a release 7 database.
    It was installed as a 11Gr1 Database by me on my computer. relative_fno and
    file_id in dba_data_files are the same (4) which makes sense as it is users
    and system, sysaux and aundo would be created before. Those are also
    showing up with 1,2 and 3 in file_id and relative_fno.

    Somehow hex 010 maps to 4 as relative and absolute file number. The question
    is why and how to map back to the relative_fno from what is in the symbolic
    block dump.

    relfile# in file$ is what we see as relative_fno in dba_data_files, right?
    Or is some magic at plat that makes your explanation work even for

    Reading your explanation, I think it could possibly be true that the last 0
    in 010 represents two high order bits for the file number. Could it be that
    the first byte is not used at all for the file id, the second is what is
    used most of the time and the last seldom and when it is should be placed
    before the second when converting to a decimal value? That is if the value
    was 123, then 1 could be ignored and would currently not be used, 3 is
    placed before 2 so the value to convert would be 32 still in hex? If that
    holds up, then does this work for all platforms for databases installed
    after release 7?

    Mathias
    On Fri, Apr 10, 2009 at 12:44 PM, Kurt Van Meerbeeck wrote:


    This happens when a database is migrated from 7 to 8.0 when absolute
    and relative filenumbers were introduced.

    --
    http://www.freelists.org/webpage/oracle-l
  • Jason Heinrich at Apr 10, 2009 at 3:26 pm
    Burleson has a fairly decent and succinct description of the rowid formats:
    http://www.remote-dba.net/10g_46.htm

    Keep in mind that the rowid format is a little different for bigfile
    tablespaces in 10g and higher. You can use dbms_rowid to retrieve the
    various components that make up the rowid.

    --
    Jason Heinrich

    On Fri, Apr 10, 2009 at 3:43 AM, Mathias Magnusson <
    mathias.magnusson_at_gmail.com> wrote:
    I'm trying to document how rowid is used by Oracle and intend to use it for
    a presentation on rowid and how it is used by Oracle. Anyway, I found one
    thing I feel I should document better, but I cannot find anything about.

    Looking at the rowid in a block dump it has a format like 01 00 03 00 00
    00. I believe I've found evidence that this makes it 010 for file, 00300 for
    block and 0000 for row. Block becomes 768 which is exactly what I knew it
    would be, it is also the only row so 0000 for row is correct. The issue is
    the file number. I know it is 4, but 010 is 16 converted to decimal. I think
    I have found indications that it needs to be divided by 4. That of course
    gets me the correct value.

    The question is, is this correct?

    Is this documented somewhere? What are the three numbers skipped in the
    file id in the rowid used for (it would seem that the file id part of a
    rowid in a block would never contain the value 1, 2, or 3)?

    Mathias
    --
    http://www.freelists.org/webpage/oracle-l

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouporacle-l @
categoriesoracle
postedApr 10, '09 at 10:44a
activeApr 10, '09 at 3:26p
posts3
users2
websiteoracle.com

People

Translate

site design / logo © 2022 Grokbase