Commit 90c8d773 authored by Eugene Kosov's avatar Eugene Kosov Committed by Eugene Kosov

MDEV-21251 CHECK TABLE fails to check info_bits of records

btr_validate_index(): do not stop checking after some level failed.
That way it'll become possible to see errors in leaf pages even when
uppers layers are corrupted too.

page_validate(): check info_bits and status_bits more
parent b811c6ec
Branches unavailable
Tags unavailable
No related merge requests found
......@@ -5260,7 +5260,6 @@ btr_validate_index(
if (!btr_validate_level(index, trx, n - i, lockout)) {
err = DB_CORRUPTION;
break;
}
}
......
......@@ -2476,6 +2476,7 @@ bool page_validate(const page_t* page, const dict_index_t* index)
/* Validate the record list in a loop checking also that
it is consistent with the directory. */
ulint count = 0, data_size = 0, own_count = 1, slot_no = 0;
ulint info_bits;
slot_no = 0;
slot = page_dir_get_nth_slot(page, slot_no);
......@@ -2499,9 +2500,16 @@ bool page_validate(const page_t* page, const dict_index_t* index)
goto next_rec;
}
info_bits = rec_get_info_bits(rec, page_is_comp(page));
if (info_bits
& ~(REC_INFO_MIN_REC_FLAG | REC_INFO_DELETED_FLAG)) {
ib::error() << "info_bits has an incorrect value "
<< info_bits;
ret = false;
}
if (rec == first_rec) {
if ((rec_get_info_bits(rec, page_is_comp(page))
& REC_INFO_MIN_REC_FLAG)) {
if (info_bits & REC_INFO_MIN_REC_FLAG) {
if (page_has_prev(page)) {
ib::error() << "REC_INFO_MIN_REC_FLAG "
"is set on non-left page";
......@@ -2512,8 +2520,7 @@ bool page_validate(const page_t* page, const dict_index_t* index)
ib::error() << "REC_INFO_MIN_REC_FLAG "
"is set in a leaf-page record";
ret = false;
} else if (rec_get_deleted_flag(
rec, page_is_comp(page))) {
} else if (info_bits & REC_INFO_DELETED_FLAG) {
/* If this were a 10.4 metadata
record for index->table->instant
we should not get here in 10.3, because
......@@ -2529,13 +2536,51 @@ bool page_validate(const page_t* page, const dict_index_t* index)
ib::error() << "Metadata record is missing";
ret = false;
}
} else if (rec_get_info_bits(rec, page_is_comp(page))
& REC_INFO_MIN_REC_FLAG) {
} else if (info_bits & REC_INFO_MIN_REC_FLAG) {
ib::error() << "REC_INFO_MIN_REC_FLAG record is not "
"first in page";
ret = false;
}
if (page_is_comp(page)) {
const rec_comp_status_t status = rec_get_status(rec);
if (status != REC_STATUS_ORDINARY
&& status != REC_STATUS_NODE_PTR
&& status != REC_STATUS_INFIMUM
&& status != REC_STATUS_SUPREMUM
&& status != REC_STATUS_COLUMNS_ADDED) {
ib::error() << "impossible record status "
<< status;
ret = false;
} else if (page_rec_is_infimum(rec)) {
if (status != REC_STATUS_INFIMUM) {
ib::error()
<< "infimum record has status "
<< status;
ret = false;
}
} else if (page_rec_is_supremum(rec)) {
if (status != REC_STATUS_SUPREMUM) {
ib::error() << "supremum record has "
"status "
<< status;
ret = false;
}
} else if (!page_is_leaf(page)) {
if (status != REC_STATUS_NODE_PTR) {
ib::error() << "node ptr record has "
"status "
<< status;
ret = false;
}
} else if (!index->is_instant()
&& status == REC_STATUS_COLUMNS_ADDED) {
ib::error() << "instantly added record in a "
"non-instant index";
ret = false;
}
}
/* Check that the records are in the ascending order */
if (count >= PAGE_HEAP_NO_USER_LOW
&& !page_rec_is_supremum(rec)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment