mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
Many files:
Try to skip over corrupt records in SELECT if innodb_force_recovery > 0; print more page hex dumps in CHECK TABLE
This commit is contained in:
parent
d0ee72c801
commit
60499d54dd
7 changed files with 241 additions and 71 deletions
|
@ -2295,20 +2295,26 @@ btr_check_node_ptr(
|
|||
/****************************************************************
|
||||
Checks the size and number of fields in a record based on the definition of
|
||||
the index. */
|
||||
static
|
||||
|
||||
ibool
|
||||
btr_index_rec_validate(
|
||||
/*====================*/
|
||||
/* out: TRUE if ok */
|
||||
rec_t* rec, /* in: index record */
|
||||
dict_index_t* index) /* in: index */
|
||||
/* out: TRUE if ok */
|
||||
rec_t* rec, /* in: index record */
|
||||
dict_index_t* index, /* in: index */
|
||||
ibool dump_on_error) /* in: TRUE if the function
|
||||
should print hex dump of record
|
||||
and page on error */
|
||||
{
|
||||
dtype_t* type;
|
||||
byte* data;
|
||||
ulint len;
|
||||
ulint n;
|
||||
ulint i;
|
||||
page_t* page;
|
||||
char err_buf[1000];
|
||||
|
||||
page = buf_frame_align(rec);
|
||||
|
||||
if (index->type & DICT_UNIVERSAL) {
|
||||
/* The insert buffer index tree can contain records from any
|
||||
|
@ -2321,11 +2327,22 @@ btr_index_rec_validate(
|
|||
n = dict_index_get_n_fields(index);
|
||||
|
||||
if (rec_get_n_fields(rec) != n) {
|
||||
fprintf(stderr, "Record has %lu fields, should have %lu\n",
|
||||
rec_get_n_fields(rec), n);
|
||||
fprintf(stderr,
|
||||
"InnoDB: Record in index %s in table %s, page %lu, at offset %lu\n"
|
||||
"InnoDB: has %lu fields, should have %lu\n",
|
||||
index->name, index->table_name,
|
||||
buf_frame_get_page_no(page), (ulint)(rec - page),
|
||||
rec_get_n_fields(rec), n);
|
||||
|
||||
if (!dump_on_error) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
buf_page_print(page);
|
||||
|
||||
rec_sprintf(err_buf, 900, rec);
|
||||
fprintf(stderr, "InnoDB: record %s\n", err_buf);
|
||||
fprintf(stderr, "InnoDB: corrupt record %s\n", err_buf);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
@ -2336,13 +2353,25 @@ btr_index_rec_validate(
|
|||
type = dict_index_get_nth_type(index, i);
|
||||
|
||||
if (len != UNIV_SQL_NULL && dtype_is_fixed_size(type)
|
||||
&& len != dtype_get_fixed_size(type)) {
|
||||
&& len != dtype_get_fixed_size(type)) {
|
||||
fprintf(stderr,
|
||||
"Record field %lu len is %lu, should be %lu\n",
|
||||
"InnoDB: Record in index %s in table %s, page %lu, at offset %lu\n"
|
||||
"InnoDB: field %lu len is %lu, should be %lu\n",
|
||||
index->name, index->table_name,
|
||||
buf_frame_get_page_no(page),
|
||||
(ulint)(rec - page),
|
||||
i, len, dtype_get_fixed_size(type));
|
||||
|
||||
if (!dump_on_error) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
buf_page_print(page);
|
||||
|
||||
rec_sprintf(err_buf, 900, rec);
|
||||
fprintf(stderr, "InnoDB: record %s\n", err_buf);
|
||||
fprintf(stderr,
|
||||
"InnoDB: corrupt record %s\n", err_buf);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
@ -2373,12 +2402,13 @@ btr_index_page_validate(
|
|||
rec = (&cur)->rec;
|
||||
|
||||
if (page_cur_is_after_last(&cur)) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!btr_index_rec_validate(rec, index)) {
|
||||
if (!btr_index_rec_validate(rec, index, TRUE)) {
|
||||
|
||||
ret = FALSE;
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
page_cur_move_to_next(&cur);
|
||||
|
@ -2435,25 +2465,26 @@ btr_validate_level(
|
|||
|
||||
index = UT_LIST_GET_FIRST(tree->tree_indexes);
|
||||
|
||||
/* Now we are on the desired level */
|
||||
/* Now we are on the desired level. Loop through the pages on that
|
||||
level. */
|
||||
loop:
|
||||
mtr_x_lock(dict_tree_get_lock(tree), &mtr);
|
||||
|
||||
/* Check ordering etc. of records */
|
||||
|
||||
if (!page_validate(page, index)) {
|
||||
fprintf(stderr, "Error in page %lu in index %s\n",
|
||||
buf_frame_get_page_no(page), index->name);
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error in page %lu in index %s table %s, index tree level %lu\n",
|
||||
buf_frame_get_page_no(page), index->name,
|
||||
index->table_name, level);
|
||||
|
||||
ret = FALSE;
|
||||
}
|
||||
} else if (level == 0) {
|
||||
/* We are on level 0. Check that the records have the right
|
||||
number of fields, and field lengths are right. */
|
||||
|
||||
if (level == 0) {
|
||||
if (!btr_index_page_validate(page, index)) {
|
||||
fprintf(stderr,
|
||||
"Error in page %lu in index %s, level %lu\n",
|
||||
buf_frame_get_page_no(page), index->name,
|
||||
level);
|
||||
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -2476,14 +2507,17 @@ loop:
|
|||
UT_LIST_GET_FIRST(tree->tree_indexes)) >= 0) {
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error on pages %lu and %lu in index %s\n",
|
||||
"InnoDB: Error on pages %lu and %lu in index %s table %s\n",
|
||||
buf_frame_get_page_no(page),
|
||||
right_page_no,
|
||||
index->name);
|
||||
index->name, index->table_name);
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: records in wrong order on adjacent pages\n");
|
||||
|
||||
buf_page_print(page);
|
||||
buf_page_print(right_page);
|
||||
|
||||
rec_sprintf(err_buf, 900,
|
||||
page_rec_get_prev(page_get_supremum_rec(page)));
|
||||
fprintf(stderr, "InnoDB: record %s\n", err_buf);
|
||||
|
@ -2506,6 +2540,7 @@ loop:
|
|||
/* Check father node pointers */
|
||||
|
||||
node_ptr = btr_page_get_father_node_ptr(tree, page, &mtr);
|
||||
father_page = buf_frame_align(node_ptr);
|
||||
|
||||
if (btr_node_ptr_get_child_page_no(node_ptr) !=
|
||||
buf_frame_get_page_no(page)
|
||||
|
@ -2513,13 +2548,16 @@ loop:
|
|||
page_rec_get_prev(page_get_supremum_rec(page)),
|
||||
&mtr)) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error on page %lu in index %s\n",
|
||||
"InnoDB: Error on page %lu in index %s table %s\n",
|
||||
buf_frame_get_page_no(page),
|
||||
index->name);
|
||||
index->name, index->table_name);
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: node pointer to the page is wrong\n");
|
||||
|
||||
buf_page_print(father_page);
|
||||
buf_page_print(page);
|
||||
|
||||
rec_sprintf(err_buf, 900, node_ptr);
|
||||
|
||||
fprintf(stderr, "InnoDB: node ptr %s\n", err_buf);
|
||||
|
@ -2540,8 +2578,6 @@ loop:
|
|||
goto node_ptr_fails;
|
||||
}
|
||||
|
||||
father_page = buf_frame_align(node_ptr);
|
||||
|
||||
if (btr_page_get_level(page, &mtr) > 0) {
|
||||
heap = mem_heap_create(256);
|
||||
|
||||
|
@ -2555,9 +2591,12 @@ loop:
|
|||
if (cmp_dtuple_rec(node_ptr_tuple, node_ptr) != 0) {
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error on page %lu in index %s\n",
|
||||
"InnoDB: Error on page %lu in index %s table %s\n",
|
||||
buf_frame_get_page_no(page),
|
||||
index->name);
|
||||
index->name, index->table_name);
|
||||
|
||||
buf_page_print(father_page);
|
||||
buf_page_print(page);
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: node ptrs differ on levels > 0\n");
|
||||
|
@ -2607,9 +2646,13 @@ loop:
|
|||
"InnoDB: node pointer to the right page is wrong\n");
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error on page %lu in index %s\n",
|
||||
"InnoDB: Error on page %lu in index %s table %s\n",
|
||||
buf_frame_get_page_no(page),
|
||||
index->name);
|
||||
index->name, index->table_name);
|
||||
|
||||
buf_page_print(father_page);
|
||||
buf_page_print(page);
|
||||
buf_page_print(right_page);
|
||||
}
|
||||
} else {
|
||||
right_father_page = buf_frame_align(
|
||||
|
@ -2623,9 +2666,14 @@ loop:
|
|||
"InnoDB: node pointer 2 to the right page is wrong\n");
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error on page %lu in index %s\n",
|
||||
"InnoDB: Error on page %lu in index %s table %s\n",
|
||||
buf_frame_get_page_no(page),
|
||||
index->name);
|
||||
index->name, index->table_name);
|
||||
|
||||
buf_page_print(father_page);
|
||||
buf_page_print(right_father_page);
|
||||
buf_page_print(page);
|
||||
buf_page_print(right_page);
|
||||
}
|
||||
|
||||
if (buf_frame_get_page_no(right_father_page)
|
||||
|
@ -2636,9 +2684,14 @@ loop:
|
|||
"InnoDB: node pointer 3 to the right page is wrong\n");
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error on page %lu in index %s\n",
|
||||
"InnoDB: Error on page %lu in index %s table %s\n",
|
||||
buf_frame_get_page_no(page),
|
||||
index->name);
|
||||
index->name, index->table_name);
|
||||
|
||||
buf_page_print(father_page);
|
||||
buf_page_print(right_father_page);
|
||||
buf_page_print(page);
|
||||
buf_page_print(right_page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -399,6 +399,19 @@ btr_print_tree(
|
|||
dict_tree_t* tree, /* in: tree */
|
||||
ulint width); /* in: print this many entries from start
|
||||
and end */
|
||||
/****************************************************************
|
||||
Checks the size and number of fields in a record based on the definition of
|
||||
the index. */
|
||||
|
||||
ibool
|
||||
btr_index_rec_validate(
|
||||
/*====================*/
|
||||
/* out: TRUE if ok */
|
||||
rec_t* rec, /* in: index record */
|
||||
dict_index_t* index, /* in: index */
|
||||
ibool dump_on_error); /* in: TRUE if the function
|
||||
should print hex dump of record
|
||||
and page on error */
|
||||
/******************************************************************
|
||||
Checks the consistency of an index tree. */
|
||||
|
||||
|
|
|
@ -298,6 +298,14 @@ btr_pcur_move_to_prev(
|
|||
function may release the page latch */
|
||||
mtr_t* mtr); /* in: mtr */
|
||||
/*************************************************************
|
||||
Moves the persistent cursor to the last record on the same page. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_move_to_last_on_page(
|
||||
/*==========================*/
|
||||
btr_pcur_t* cursor, /* in: persistent cursor */
|
||||
mtr_t* mtr); /* in: mtr */
|
||||
/*************************************************************
|
||||
Moves the persistent cursor to the next user record in the tree. If no user
|
||||
records are left, the cursor ends up 'after last in tree'. */
|
||||
UNIV_INLINE
|
||||
|
|
|
@ -284,6 +284,24 @@ btr_pcur_move_to_prev_on_page(
|
|||
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
Moves the persistent cursor to the last record on the same page. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_move_to_last_on_page(
|
||||
/*==========================*/
|
||||
btr_pcur_t* cursor, /* in: persistent cursor */
|
||||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
UT_NOT_USED(mtr);
|
||||
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
|
||||
|
||||
page_cur_set_after_last(buf_frame_align(btr_pcur_get_rec(cursor)),
|
||||
btr_pcur_get_page_cur(cursor));
|
||||
|
||||
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
Moves the persistent cursor to the next user record in the tree. If no user
|
||||
records are left, the cursor ends up 'after last in tree'. */
|
||||
|
|
|
@ -41,7 +41,8 @@ Created 5/24/1996 Heikki Tuuri
|
|||
which is referenced */
|
||||
#define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint
|
||||
to a table failed */
|
||||
|
||||
#define DB_CORRUPTION 39 /* data structure corruption noticed */
|
||||
|
||||
/* The following are partial failure codes */
|
||||
#define DB_FAIL 1000
|
||||
#define DB_OVERFLOW 1001
|
||||
|
|
|
@ -1299,12 +1299,16 @@ page_rec_validate(
|
|||
heap_no = rec_get_heap_no(rec);
|
||||
|
||||
if (!(n_owned <= PAGE_DIR_SLOT_MAX_N_OWNED)) {
|
||||
fprintf(stderr, "Dir slot n owned too big %lu\n", n_owned);
|
||||
fprintf(stderr,
|
||||
"InnoDB: Dir slot of rec %lu, n owned too big %lu\n",
|
||||
(ulint)(rec - page), n_owned);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (!(heap_no < page_header_get_field(page, PAGE_N_HEAP))) {
|
||||
fprintf(stderr, "Heap no too big %lu %lu\n", heap_no,
|
||||
fprintf(stderr,
|
||||
"InnoDB: Heap no of rec %lu too big %lu %lu\n",
|
||||
(ulint)(rec - page), heap_no,
|
||||
page_header_get_field(page, PAGE_N_HEAP));
|
||||
return(FALSE);
|
||||
}
|
||||
|
@ -1340,7 +1344,7 @@ page_simple_validate(
|
|||
|
||||
if (n_slots > UNIV_PAGE_SIZE / 4) {
|
||||
fprintf(stderr,
|
||||
"Nonsensical number %lu of page dir slots\n", n_slots);
|
||||
"InnoDB: Nonsensical number %lu of page dir slots\n", n_slots);
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
|
@ -1350,7 +1354,7 @@ page_simple_validate(
|
|||
if (rec_heap_top > page_dir_get_nth_slot(page, n_slots - 1)) {
|
||||
|
||||
fprintf(stderr,
|
||||
"Record heap and dir overlap on a page, heap top %lu, dir %lu\n",
|
||||
"InnoDB: Record heap and dir overlap on a page, heap top %lu, dir %lu\n",
|
||||
(ulint)(page_header_get_ptr(page, PAGE_HEAP_TOP) - page),
|
||||
(ulint)(page_dir_get_nth_slot(page, n_slots - 1) - page));
|
||||
|
||||
|
@ -1372,7 +1376,7 @@ page_simple_validate(
|
|||
|
||||
if (rec > rec_heap_top) {
|
||||
fprintf(stderr,
|
||||
"Record %lu is above rec heap top %lu\n",
|
||||
"InnoDB: Record %lu is above rec heap top %lu\n",
|
||||
(ulint)(rec - page), (ulint)(rec_heap_top - page));
|
||||
|
||||
goto func_exit;
|
||||
|
@ -1383,7 +1387,7 @@ page_simple_validate(
|
|||
if (rec_get_n_owned(rec) != own_count) {
|
||||
|
||||
fprintf(stderr,
|
||||
"Wrong owned count %lu, %lu, rec %lu\n",
|
||||
"InnoDB: Wrong owned count %lu, %lu, rec %lu\n",
|
||||
rec_get_n_owned(rec), own_count,
|
||||
(ulint)(rec - page));
|
||||
|
||||
|
@ -1392,7 +1396,7 @@ page_simple_validate(
|
|||
|
||||
if (page_dir_slot_get_rec(slot) != rec) {
|
||||
fprintf(stderr,
|
||||
"Dir slot does not point to right rec %lu\n",
|
||||
"InnoDB: Dir slot does not point to right rec %lu\n",
|
||||
(ulint)(rec - page));
|
||||
|
||||
goto func_exit;
|
||||
|
@ -1414,7 +1418,7 @@ page_simple_validate(
|
|||
if (rec_get_next_offs(rec) < FIL_PAGE_DATA
|
||||
|| rec_get_next_offs(rec) >= UNIV_PAGE_SIZE) {
|
||||
fprintf(stderr,
|
||||
"Next record offset nonsensical %lu for rec %lu\n",
|
||||
"InnoDB: Next record offset nonsensical %lu for rec %lu\n",
|
||||
rec_get_next_offs(rec),
|
||||
(ulint)(rec - page));
|
||||
|
||||
|
@ -1425,7 +1429,7 @@ page_simple_validate(
|
|||
|
||||
if (count > UNIV_PAGE_SIZE) {
|
||||
fprintf(stderr,
|
||||
"Page record list appears to be circular %lu\n",
|
||||
"InnoDB: Page record list appears to be circular %lu\n",
|
||||
count);
|
||||
goto func_exit;
|
||||
}
|
||||
|
@ -1435,19 +1439,19 @@ page_simple_validate(
|
|||
}
|
||||
|
||||
if (rec_get_n_owned(rec) == 0) {
|
||||
fprintf(stderr, "n owned is zero in a supremum rec\n");
|
||||
fprintf(stderr, "InnoDB: n owned is zero in a supremum rec\n");
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (slot_no != n_slots - 1) {
|
||||
fprintf(stderr, "n slots wrong %lu, %lu\n",
|
||||
fprintf(stderr, "InnoDB: n slots wrong %lu, %lu\n",
|
||||
slot_no, n_slots - 1);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (page_header_get_field(page, PAGE_N_RECS) + 2 != count + 1) {
|
||||
fprintf(stderr, "n recs wrong %lu %lu\n",
|
||||
fprintf(stderr, "InnoDB: n recs wrong %lu %lu\n",
|
||||
page_header_get_field(page, PAGE_N_RECS) + 2, count + 1);
|
||||
|
||||
goto func_exit;
|
||||
|
@ -1460,7 +1464,7 @@ page_simple_validate(
|
|||
if (rec < page + FIL_PAGE_DATA
|
||||
|| rec >= page + UNIV_PAGE_SIZE) {
|
||||
fprintf(stderr,
|
||||
"Free list record has a nonsensical offset %lu\n",
|
||||
"InnoDB: Free list record has a nonsensical offset %lu\n",
|
||||
(ulint)(rec - page));
|
||||
|
||||
goto func_exit;
|
||||
|
@ -1468,7 +1472,7 @@ page_simple_validate(
|
|||
|
||||
if (rec > rec_heap_top) {
|
||||
fprintf(stderr,
|
||||
"Free list record %lu is above rec heap top %lu\n",
|
||||
"InnoDB: Free list record %lu is above rec heap top %lu\n",
|
||||
(ulint)(rec - page), (ulint)(rec_heap_top - page));
|
||||
|
||||
goto func_exit;
|
||||
|
@ -1478,7 +1482,7 @@ page_simple_validate(
|
|||
|
||||
if (count > UNIV_PAGE_SIZE) {
|
||||
fprintf(stderr,
|
||||
"Page free list appears to be circular %lu\n",
|
||||
"InnoDB: Page free list appears to be circular %lu\n",
|
||||
count);
|
||||
goto func_exit;
|
||||
}
|
||||
|
@ -1488,7 +1492,7 @@ page_simple_validate(
|
|||
|
||||
if (page_header_get_field(page, PAGE_N_HEAP) != count + 1) {
|
||||
|
||||
fprintf(stderr, "N heap is wrong %lu, %lu\n",
|
||||
fprintf(stderr, "InnoDB: N heap is wrong %lu, %lu\n",
|
||||
page_header_get_field(page, PAGE_N_HEAP), count + 1);
|
||||
|
||||
goto func_exit;
|
||||
|
@ -1528,10 +1532,13 @@ page_validate(
|
|||
char err_buf[1000];
|
||||
|
||||
if (!page_simple_validate(page)) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Apparent corruption in page %lu in index %s in table %s\n",
|
||||
buf_frame_get_page_no(page), index->name,
|
||||
index->table_name);
|
||||
|
||||
buf_page_print(page);
|
||||
|
||||
fprintf(stderr, "Apparent corruption in a page in index %s\n",
|
||||
index->name);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
@ -1553,7 +1560,7 @@ page_validate(
|
|||
if (!(page_header_get_ptr(page, PAGE_HEAP_TOP) <=
|
||||
page_dir_get_nth_slot(page, n_slots - 1))) {
|
||||
fprintf(stderr,
|
||||
"Record heap and dir overlap on a page in index %s, %lu, %lu\n",
|
||||
"InnoDB: Record heap and dir overlap on a page in index %s, %lu, %lu\n",
|
||||
index->name, (ulint)page_header_get_ptr(page, PAGE_HEAP_TOP),
|
||||
(ulint)page_dir_get_nth_slot(page, n_slots - 1));
|
||||
|
||||
|
@ -1581,10 +1588,14 @@ page_validate(
|
|||
if ((count >= 2) && (!page_cur_is_after_last(&cur))) {
|
||||
if (!(1 == cmp_rec_rec(rec, old_rec, index))) {
|
||||
fprintf(stderr,
|
||||
"Records in wrong order in index %s\n",
|
||||
index->name);
|
||||
"InnoDB: Records in wrong order on page %lu index %s table %s\n",
|
||||
buf_frame_get_page_no(page),
|
||||
index->name,
|
||||
index->table_name);
|
||||
|
||||
rec_sprintf(err_buf, 900, old_rec);
|
||||
fprintf(stderr, "InnoDB: record %s\n", err_buf);
|
||||
fprintf(stderr,
|
||||
"InnoDB: previous record %s\n", err_buf);
|
||||
|
||||
rec_sprintf(err_buf, 900, rec);
|
||||
fprintf(stderr, "InnoDB: record %s\n", err_buf);
|
||||
|
@ -1606,7 +1617,7 @@ page_validate(
|
|||
/* No other record may overlap this */
|
||||
|
||||
fprintf(stderr,
|
||||
"Record overlaps another in index %s \n",
|
||||
"InnoDB: Record overlaps another in index %s \n",
|
||||
index->name);
|
||||
|
||||
goto func_exit;
|
||||
|
@ -1619,7 +1630,7 @@ page_validate(
|
|||
/* This is a record pointed to by a dir slot */
|
||||
if (rec_get_n_owned(rec) != own_count) {
|
||||
fprintf(stderr,
|
||||
"Wrong owned count %lu, %lu, in index %s\n",
|
||||
"InnoDB: Wrong owned count %lu, %lu, in index %s\n",
|
||||
rec_get_n_owned(rec), own_count,
|
||||
index->name);
|
||||
|
||||
|
@ -1628,7 +1639,7 @@ page_validate(
|
|||
|
||||
if (page_dir_slot_get_rec(slot) != rec) {
|
||||
fprintf(stderr,
|
||||
"Dir slot does not point to right rec in %s\n",
|
||||
"InnoDB: Dir slot does not point to right rec in %s\n",
|
||||
index->name);
|
||||
|
||||
goto func_exit;
|
||||
|
@ -1650,7 +1661,7 @@ page_validate(
|
|||
if (rec_get_next_offs(rec) < FIL_PAGE_DATA
|
||||
|| rec_get_next_offs(rec) >= UNIV_PAGE_SIZE) {
|
||||
fprintf(stderr,
|
||||
"Next record offset wrong %lu in index %s\n",
|
||||
"InnoDB: Next record offset wrong %lu in index %s\n",
|
||||
rec_get_next_offs(rec), index->name);
|
||||
|
||||
goto func_exit;
|
||||
|
@ -1663,19 +1674,20 @@ page_validate(
|
|||
}
|
||||
|
||||
if (rec_get_n_owned(rec) == 0) {
|
||||
fprintf(stderr, "n owned is zero in index %s\n", index->name);
|
||||
fprintf(stderr,
|
||||
"InnoDB: n owned is zero in index %s\n", index->name);
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (slot_no != n_slots - 1) {
|
||||
fprintf(stderr, "n slots wrong %lu %lu in index %s\n",
|
||||
fprintf(stderr, "InnoDB: n slots wrong %lu %lu in index %s\n",
|
||||
slot_no, n_slots - 1, index->name);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (page_header_get_field(page, PAGE_N_RECS) + 2 != count + 1) {
|
||||
fprintf(stderr, "n recs wrong %lu %lu in index %s\n",
|
||||
fprintf(stderr, "InnoDB: n recs wrong %lu %lu in index %s\n",
|
||||
page_header_get_field(page, PAGE_N_RECS) + 2, count + 1,
|
||||
index->name);
|
||||
|
||||
|
@ -1683,7 +1695,8 @@ page_validate(
|
|||
}
|
||||
|
||||
if (data_size != page_get_data_size(page)) {
|
||||
fprintf(stderr, "Summed data size %lu, returned by func %lu\n",
|
||||
fprintf(stderr,
|
||||
"InnoDB: Summed data size %lu, returned by func %lu\n",
|
||||
data_size, page_get_data_size(page));
|
||||
goto func_exit;
|
||||
}
|
||||
|
@ -1704,7 +1717,7 @@ page_validate(
|
|||
|
||||
if (buf[offs + i] != 0) {
|
||||
fprintf(stderr,
|
||||
"Record overlaps another in free list, index %s \n",
|
||||
"InnoDB: Record overlaps another in free list, index %s \n",
|
||||
index->name);
|
||||
|
||||
goto func_exit;
|
||||
|
@ -1718,9 +1731,11 @@ page_validate(
|
|||
|
||||
if (page_header_get_field(page, PAGE_N_HEAP) != count + 1) {
|
||||
|
||||
fprintf(stderr, "N heap is wrong %lu %lu in index %s\n",
|
||||
page_header_get_field(page, PAGE_N_HEAP), count + 1,
|
||||
index->name);
|
||||
fprintf(stderr,
|
||||
"InnoDB: N heap is wrong %lu %lu in index %s\n",
|
||||
page_header_get_field(page, PAGE_N_HEAP), count + 1,
|
||||
index->name);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
@ -1728,6 +1743,15 @@ page_validate(
|
|||
func_exit:
|
||||
mem_heap_free(heap);
|
||||
|
||||
if (ret == FALSE) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Apparent corruption in page %lu in index %s in table %s\n",
|
||||
buf_frame_get_page_no(page), index->name,
|
||||
index->table_name);
|
||||
|
||||
buf_page_print(page);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -2560,6 +2560,7 @@ row_search_for_mysql(
|
|||
then this is set to FALSE */
|
||||
ibool success;
|
||||
ulint cnt = 0;
|
||||
ulint next_offs;
|
||||
mtr_t mtr;
|
||||
|
||||
ut_ad(index && pcur && search_tuple);
|
||||
|
@ -2916,7 +2917,59 @@ rec_loop:
|
|||
goto next_rec;
|
||||
}
|
||||
|
||||
ut_ad(page_rec_is_user_rec(rec));
|
||||
/*-------------------------------------------------------------*/
|
||||
/* Do sanity checks in case our cursor has bumped into page
|
||||
corruption */
|
||||
|
||||
next_offs = rec_get_next_offs(rec);
|
||||
|
||||
if (next_offs >= UNIV_PAGE_SIZE || next_offs < PAGE_SUPREMUM) {
|
||||
|
||||
if (srv_force_recovery == 0 || moves_up == FALSE) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
|
||||
"InnoDB: index %s, table %s. Run CHECK TABLE to table. You may need to\n"
|
||||
"InnoDB: restore from a backup, or dump + drop + reimport the table.\n",
|
||||
(ulint)(rec - buf_frame_align(rec)), next_offs,
|
||||
buf_frame_get_page_no(rec), index->name,
|
||||
index->table_name);
|
||||
|
||||
err = DB_CORRUPTION;
|
||||
|
||||
goto lock_wait_or_error;
|
||||
} else {
|
||||
/* The user may be dumping a corrupt table. Jump
|
||||
over the corruption to recover as much as possible. */
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
|
||||
"InnoDB: index %s, table %s. We try to skip the rest of the page.\n",
|
||||
(ulint)(rec - buf_frame_align(rec)), next_offs,
|
||||
buf_frame_get_page_no(rec), index->name,
|
||||
index->table_name);
|
||||
|
||||
btr_pcur_move_to_last_on_page(pcur, &mtr);
|
||||
|
||||
goto next_rec;
|
||||
}
|
||||
}
|
||||
|
||||
if (srv_force_recovery > 0) {
|
||||
if (!rec_validate(rec) || !btr_index_rec_validate(rec, index,
|
||||
FALSE)) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Index record corruption: rec offs %lu next offs %lu, page no %lu,\n"
|
||||
"InnoDB: index %s, table %s. We try to skip the record.\n",
|
||||
(ulint)(rec - buf_frame_align(rec)), next_offs,
|
||||
buf_frame_get_page_no(rec), index->name,
|
||||
index->table_name);
|
||||
|
||||
goto next_rec;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
if (unique_search_from_clust_index && btr_pcur_get_up_match(pcur)
|
||||
== dtuple_get_n_fields(search_tuple)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue