Bug #13413535 61104: INNODB: FAILING ASSERTION: PAGE_GET_N_RECS(PAGE) > 1

This fix does not remove the underlying cause of the assertion
failure. It just works around the problem, allowing a corrupted
secondary index to be fixed by DROP INDEX and CREATE INDEX (or in the
worst case, by re-creating the table).

ibuf_delete(): If the record to be purged is the last one in the page
or it is not delete-marked, refuse to purge it. Instead, write an
error message to the error log and let a debug assertion fail.

ibuf_set_del_mark(): If the record to be delete-marked is not found,
display some more information in the error log and let a debug
assertion fail.

row_undo_mod_del_unmark_sec_and_undo_update(),
row_upd_sec_index_entry(): Let a debug assertion fail when the record
to be delete-marked is not found.

buf_page_print(): Add ut_ad(0) so that corruption will be more
prominent in stress testing with debug binaries. Add ut_ad(0) here and
there where corruption is noticed.

btr_corruption_report(): Display some data on page_is_comp() mismatch.

btr_assert_not_corrupted(): A wrapper around btr_corruption_report().
Assert that page_is_comp() agrees with the table flags.

rb:911 approved by Inaam Rana
This commit is contained in:
Marko Mäkelä 2012-01-26 13:24:00 +02:00
commit d84c95579b
15 changed files with 118 additions and 35 deletions

View file

@ -3880,6 +3880,7 @@ ibuf_insert_to_index_page_low(
fputs("InnoDB: Submit a detailed bug report"
" to http://bugs.mysql.com\n", stderr);
ut_ad(0);
}
/************************************************************************
@ -4073,6 +4074,11 @@ ibuf_set_del_mark(
TRUE, mtr);
}
} else {
const page_t* page
= page_cur_get_page(&page_cur);
const buf_block_t* block
= page_cur_get_block(&page_cur);
ut_print_timestamp(stderr);
fputs(" InnoDB: unable to find a record to delete-mark\n",
stderr);
@ -4081,10 +4087,14 @@ ibuf_set_del_mark(
fputs("\n"
"InnoDB: record ", stderr);
rec_print(stderr, page_cur_get_rec(&page_cur), index);
putc('\n', stderr);
fputs("\n"
"InnoDB: Submit a detailed bug report"
" to http://bugs.mysql.com\n", stderr);
fprintf(stderr, "\nspace %u offset %u"
" (%u records, index id %llu)\n"
"InnoDB: Submit a detailed bug report"
" to http://bugs.mysql.com\n",
(unsigned) buf_block_get_space(block),
(unsigned) buf_block_get_page_no(block),
(unsigned) page_get_n_recs(page),
btr_page_get_index_id(page));
ut_ad(0);
}
}
@ -4128,12 +4138,31 @@ ibuf_delete(
offsets = rec_get_offsets(
rec, index, offsets, ULINT_UNDEFINED, &heap);
/* Refuse to delete the last record. */
ut_a(page_get_n_recs(page) > 1);
if (page_get_n_recs(page) <= 1
|| !(REC_INFO_DELETED_FLAG
& rec_get_info_bits(rec, page_is_comp(page)))) {
/* Refuse to purge the last record or a
record that has not been marked for deletion. */
ut_print_timestamp(stderr);
fputs(" InnoDB: unable to purge a record\n",
stderr);
fputs("InnoDB: tuple ", stderr);
dtuple_print(stderr, entry);
fputs("\n"
"InnoDB: record ", stderr);
rec_print_new(stderr, rec, offsets);
fprintf(stderr, "\nspace %u offset %u"
" (%u records, index id %llu)\n"
"InnoDB: Submit a detailed bug report"
" to http://bugs.mysql.com\n",
(unsigned) buf_block_get_space(block),
(unsigned) buf_block_get_page_no(block),
(unsigned) page_get_n_recs(page),
btr_page_get_index_id(page));
/* The record should have been marked for deletion. */
ut_ad(REC_INFO_DELETED_FLAG
& rec_get_info_bits(rec, page_is_comp(page)));
ut_ad(0);
return;
}
lock_update_delete(block, rec);
@ -4219,6 +4248,7 @@ ibuf_restore_pos(
fprintf(stderr, "InnoDB: ibuf tree ok\n");
fflush(stderr);
ut_ad(0);
}
return(FALSE);