mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 05:23:03 +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_REL_CHAIN_ORPHANS = 22;
|
||||||
const int VAL_INDEX_MISSING_ROWS = 23;
|
const int VAL_INDEX_MISSING_ROWS = 23;
|
||||||
const int VAL_INDEX_ORPHAN_CHILD = 24;
|
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",
|
"Transaction inventory pages confused, sequence %ld",
|
||||||
"Relation has %ld orphan backversions (%ld in use)",
|
"Relation has %ld orphan backversions (%ld in use)",
|
||||||
"Index %d is corrupt (missing entries)",
|
"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;
|
SCHAR flags = 0;
|
||||||
UCHAR* pointer;
|
UCHAR* pointer;
|
||||||
IndexNode node, lastNode;
|
IndexNode node, lastNode;
|
||||||
|
PageBitmap visited_pages; // used to check circular page references, Diane Downie 2/9/07
|
||||||
|
|
||||||
while (next) {
|
while (next) {
|
||||||
WIN window(-1);
|
WIN window(-1);
|
||||||
btree_page* page = 0;
|
btree_page* page = 0;
|
||||||
fetch_page(tdbb, control, next, pag_index, &window, &page);
|
fetch_page(tdbb, control, next, pag_index, &window, &page);
|
||||||
|
|
||||||
|
// remember each page for circular reference detection
|
||||||
|
visited_pages.set(next);
|
||||||
|
|
||||||
if ((next != page_number) &&
|
if ((next != page_number) &&
|
||||||
(page->btr_header.pag_flags & BTR_FLAG_COPY_MASK) !=
|
(page->btr_header.pag_flags & BTR_FLAG_COPY_MASK) !=
|
||||||
(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);
|
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);
|
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);
|
CCH_RELEASE(tdbb, &rpb->rpb_window);
|
||||||
return false;
|
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)) {
|
if (!(rpb->rpb_flags & rpb_delta)) {
|
||||||
rpb->rpb_prior = NULL;
|
rpb->rpb_prior = NULL;
|
||||||
/* Fetch a back version. If a latch timeout occurs, refetch the
|
/* Fetch a back version. If a latch timeout occurs, refetch the
|
||||||
|
Loading…
Reference in New Issue
Block a user