Subject Re: [IB-Architect] Is there really any way...?
Author Helen Borrie
At 10:30 AM 26-04-00 -0400, you wrote:
>At 09:38 PM 4/26/00 +1000, Helen Borrie wrote:
> >I've had several people suggest a topic for the IBDH along the lines of...
> >
> >"We need a topic that describes the structure of the database so that I can
> >open the .gdb with a suitable editor and retrieve good data from a corrupt
> >database."
> >
> >In my high-handed way, I've tended just to say to myself "Pooph! another
> >of THOSE!" I've always assumed (rightly or wrongly) that it would be like
> >looking for a needle in a haystack, given the relative randomness of
> >storage of rows, never mind tables, indexes, etc.
> >
> >But - is there any way?
> >
>Your instincts are corrected. There is no way to get anything out of
>an Interbase database without understanding the entire on-disk structure.
>This is not to say that a database walking GUI couldn't be built, but
>it would be limited to a single ODS version and couldn't share a
>database file with a running engine.
>For the record, to find a particular field in a specific record
>the utility would have to:
> 1. Read the header pages to get the ground rules and initial
> pointer page of RDB$PAGES.

[snipped 12 Gb of how-to...]

LOL. So poor ol' Joe Blow can't open up his 2 Gig gdb in Notepad and
copy/paste into a script. Tut!


(Eh, Jim, you're not volunteering to write this topic for IBDH?)

> 2. Process the table RDB$PAGES (see below) to find the
> pointer page for RDB$RELATIONS (relation id is a known
> constant).
> 3. Process the table RDB$RELATIONS to get the relation id of
> the target table.
> 4. Go back to RDB$PAGES to get the pointer pages for the
> target table.
> 5. Process RDB$PAGES to find the pointer pages for RDB$RELATION_FIELDS
> and RDB$FIELDS (relation ids are constants).
> 6. Process RDB$RELATION_FIELDS and RDB$FIELDS to get the logical
> structure of the target table.
> 7. Compute the states of interest transactions: start with the
> the oldest interesting transaction on the header page, process
> RDB$PAGES to find the transaction inventory pages (TIPs).
> 8. Starting with the first pointer page for the target table
> search successive data pages.
> 9. For each data page scan record segments skipping deleted
> record stubs, blobs, and non-leading record fragments to
> find record headers.
> 10. For a candidate record header see if it's creating
> transaction was commited. If not, follow the back version
> pointer, remembering to expand the record to apply a delta
> if necessary.
> 11. To expand a segment, it if first necessary to allocate
> a buffer to hold the expanded record. To allocate the
> buffer, you need to know the length. Get the format
> version number from the header and process RDB$FORMATS
> to find the record format (go back to RDB$PAGES to the
> the pointer pages for RDB$FORMATS, etc.). Allocate the
> the buffer. Expand the compressed segment into the the
> buffer. If the record is fragmented, chase the tail
> fragments, expanding each.
> 12. If we were following a back version, apply the compressed
> delta to the expanded version of the previous version. If
> the format versions changed (unlikely but possible), deal
> with it.
> 13. Once the target record has been assembled, index into
> the format to compute the descriptor for the target field.
> 14. If the target field is a blob, fetch the blob header. If
> it is level 0, the data is there. Otherwise, chase down
> and assemble the blob pages (no, blobs are not compressed).
>Doable. But perhaps a little much for an editor.
>Jim Starkey
>Join's affiliate program and enjoy numerous benefits.
>To learn more click here:
>To unsubscribe from this group, send an email to:
"Ask not what your free, open-source database can do for you,
but what you can do for your free, open-source database."