This will prevent any further validation of the relation.
NOTE: For views, the metadata is scanned but nothing further is done.
Prior to 4.5 (NevaStone) Indices were walked before data pages.
In NevaStone Index walking was moved to after data page walking.
Please refer to the later section entitled "Index Walking".
All the pointer pages for the relation are walked. As they are walked
all child data pages are walked (see below). If a pointer page cannot
be found, the following message is returned:
"Pointer page (sequence xxx) lost"
If the pointer page is not part of the relation we expected or
if it is not marked as being in the proper sequence, the following
message is returned:
"Pointer page xxx is inconsistent"
If each pointer page does not point to the next pointer page as
stored in the RDB$PAGE_SEQUENCE field in RDB$PAGES, the following
error is returned:
"Pointer page (sequence xxx) inconsistent"
Each of the data pages referenced by the pointer page is fetched.
If any are found to be corrupt at the page level, and -mend is
specified, the page is deleted from its pointer page. This will
cause a whole page of data to be lost.
The data page is corrupt at the page level if it is not marked as
part of the current relation, or if it is not marked as being in
the proper sequence. If either of these conditions occurs, the
following error is returned:
"Data page xxx (sequence xxx) is confused"
Each of the slots on the data page is looked at, up to the count
of records stored on page. If the slot is non-zero, the record
fragment at the specified offset is retrieved. If the record
begins before the end of the slots array, or continues off the
end of the page, the following error is returned:
"Data page xxx (sequence xxx), line xxx is bad"
where "line" means the slot number.
NOTE: If this condition is encountered, the data page is considered
corrupt at the page level (and thus will be removed from its
pointer page if -mend is specified).
The record at each slot is looked at for basic validation, regardless
of whether -full is specified or not. The fragment could be any of the
- Back Version
If the fragment is marked as a back version, then it is skipped.
It will be fetched as part of its record.
If the fragment is determined to be corrupt for any reason, and -mend
is specified, then the record header is marked as damaged.
If the fragment is marked damaged already from a previous visit or
a previous validation, the following error is returned:
"Record xxx is marked as damaged"
where xxx is the record number.
- Bad Transaction
If the record is marked with a transaction id greater than the last
transaction started in the database, the following error is returned:
"Record xxx has bad transaction xxx"
If -full is specified, and the fragment is the first fragment in a logical
record, then the record at this slot number is fully retrieved. This
involves retrieving all versions, and all fragments of each
particular version. In other
words, the entire logical record will be retrieved.
- Back Versions
If there are any back versions, they are visited at this point.
If the back version is on another page, the page is fetched but
not validated since it will be walked separately.
If the slot number of the back version is greater than the max
records on page, or there is no record stored at that slot number,
or it is a blob record, or it is a record fragment, or the
fragment itself is invalid, the following error
message is returned:
"Chain for record xxx is broken"
If the record header is marked as incomplete, it means that there
are additional fragments to be fetched--the record was too large
to be stored in one slot.
A pointer is stored in the record to the next fragment in the list.
For fragmented records, all fragments are fetched to form a full
record version. If any of the fragments is not in a valid position,
or is not the correct length, the following error is returned:
"Fragmented record xxx is corrupt"
Once the full record has been retrieved, the length of the format is
checked against the expected format stored in RDB$FORMATS (the
format number is stored with the record, representing the exact
format of the relation at the time the record was stored.)
If the length of the reconstructed record does not match
the expected format length, the following error is returned:
"Record xxx is wrong length"
For delta records (record versions which represent updates to the record)
this check is not made.
If the slot on the data page points to a blob record, then the blob
is fetched (even without -full). This has several cases, corresponding
to the various blob levels. (See the "Engine Internals" document for a
discussion of blob levels.)
||These are just records on page, and no further validation is done.
||All the pages pointed to by the blob record are fetched and validated
||All pages pointed to by the blob pointer pages are fetched and validated.
||The blob page is itself a blob pointer page; all its children are fetched
For each blob page found, some further validation is done. If the
page does not point back to the lead page, the following error
"Warning: blob xxx appears inconsistent"
where xxx corresponds to the blob record number. If any of the blob pages
are not marked in the sequence we expect them to be in, the following
error is returned:
"Blob xxx is corrupt"
Tip: the message for the same error in level 2 or 3 blobs is slightly
"Blob xxx corrupt"
If we have lost any of the blob pages in the sequence, the following error
"Blob xxx is truncated"
If the fetched blob is determined to be corrupt for any of the above
reasons, and -mend is specified, then the blob record is marked as
In 4.5 (NevaStone) Index walking was moved to after the completion
of data page walking.
The indices for the relation are walked. If the index root page
is missing, the following message is returned:
"Missing index root page"
and the indices are not walked. Otherwise the index root page
is fetched and all indices on the page fetched.
For each index, the btree pages are fetched from top-down, left to
Basic validation is made on non-leaf pages to ensure that each node
on page points to another index page. If -full validation is specified
then the lower level page is fetched to ensure it is starting index
entry is consistent with the parent entry.
On leaf pages, the records pointed to by the index pages are not
fetched, the keys are looked at to ensure they are in correct
If a visited page is not part of the specified relation and index,
the following error is returned:
"Index xxx is corrupt at page xxx"
If there are orphan child pages, i.e. a child page does not have its entry
as yet in the parent page, however the child's left sibling page has it's
btr_sibling updated, the following error is returned
"Index xxx has orphan child page at page xxx"
If the page does not contain the number of nodes we would have
expected from its marked length, the following error is returned:
"Index xxx is corrupt on page xxx"
While we are walking leaf pages, we keep a bitmap of all record
numbers seen in the index. At the conclusion of the index walk
we compare this bitmap to the bitmap of all records in the
relation (calculated during data page/Record Validation phase).
If the bitmaps are not equal then we have a corrupt index
and the following error is reported:
"Index %d is corrupt (missing entries)"
We do NOT check that each version of each record has a valid
index entry - nor do we check that the stored key for each item
in the index corresponds to a version of the specified record.
We count the number of backversions seen while walking pointer pages,
and separately count the number of backversions seen while walking
record chains. If these numbers do not match it indicates either
"orphan" backversion chains or double-linked chains. If this is
see the following error is returned:
"Relation has %ld orphan backversions (%ld in use)"
Currently we do not try to correct this condition, mearly report
it. For "orphan" backversions the space can be reclaimed by
a backup/restore. For double-linked chains a SWEEP should
remove all the backversions.