mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 22:43:04 +01:00
Fixed CORE-1127 : Circular index references in corrupt database causes fbserver to loop infinitely.
Thanks to Diane Downie
This commit is contained in:
parent
fbdbd4b450
commit
e4b66b962e
@ -437,7 +437,8 @@ const int VAL_TIP_CONFUSED = 21;
|
||||
const int VAL_REL_CHAIN_ORPHANS = 22;
|
||||
const int VAL_INDEX_MISSING_ROWS = 23;
|
||||
const int VAL_INDEX_ORPHAN_CHILD = 24;
|
||||
const int VAL_MAX_ERROR = 25;
|
||||
const int VAL_INDEX_CYCLE = 25;
|
||||
const int VAL_MAX_ERROR = 26;
|
||||
|
||||
|
||||
//
|
||||
|
@ -647,7 +647,8 @@ static const TEXT msg_table[][66] = {
|
||||
"Transaction inventory pages confused, sequence %ld",
|
||||
"Relation has %ld orphan backversions (%ld in use)",
|
||||
"Index %d is corrupt (missing entries)",
|
||||
"Index %d has orphan child page at page %ld"
|
||||
"Index %d has orphan child page at page %ld",
|
||||
"Index %d has a circular reference at page %ld"
|
||||
};
|
||||
|
||||
|
||||
@ -1430,11 +1431,16 @@ static RTN walk_index(thread_db* tdbb, vdr* control, jrd_rel* relation,
|
||||
SCHAR flags = 0;
|
||||
UCHAR* pointer;
|
||||
IndexNode node, lastNode;
|
||||
PageBitmap visited_pages; // used to check circular page references, Diane Downie 2/9/07
|
||||
|
||||
while (next) {
|
||||
WIN window(-1);
|
||||
btree_page* page = 0;
|
||||
fetch_page(tdbb, control, next, pag_index, &window, &page);
|
||||
|
||||
// remember each page for circular reference detection
|
||||
visited_pages.set(next);
|
||||
|
||||
if ((next != page_number) &&
|
||||
(page->btr_header.pag_flags & BTR_FLAG_COPY_MASK) !=
|
||||
(flags & BTR_FLAG_COPY_MASK))
|
||||
@ -1686,6 +1692,13 @@ static RTN walk_index(thread_db* tdbb, vdr* control, jrd_rel* relation,
|
||||
nullKeyHandled = !(unique && null_key);
|
||||
}
|
||||
|
||||
// check for circular referenes
|
||||
if (next && visited_pages.test(next))
|
||||
{
|
||||
corrupt(tdbb, control, VAL_INDEX_CYCLE, relation,
|
||||
id + 1, next);
|
||||
next = 0;
|
||||
}
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
}
|
||||
|
||||
|
@ -768,6 +768,17 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb, RecordSource*
|
||||
CCH_RELEASE(tdbb, &rpb->rpb_window);
|
||||
return false;
|
||||
}
|
||||
|
||||
// hvlad: if i'm garbage collector i don't need to read backversion of active
|
||||
// record. Just do notify self about it (if background policy enabled)
|
||||
if (attachment->att_flags & ATT_garbage_collector)
|
||||
{
|
||||
// VIO_chase_record_version
|
||||
notify_garbage_collector(tdbb, rpb);
|
||||
CCH_RELEASE(tdbb, &rpb->rpb_window);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(rpb->rpb_flags & rpb_delta)) {
|
||||
rpb->rpb_prior = NULL;
|
||||
/* Fetch a back version. If a latch timeout occurs, refetch the
|
||||
|
Loading…
Reference in New Issue
Block a user