3711 Marko Mäkelä 2012-01-26
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
modified:
storage/innobase/btr/btr0btr.c
storage/innobase/btr/btr0cur.c
storage/innobase/buf/buf0buf.c
storage/innobase/ibuf/ibuf0ibuf.c
storage/innobase/include/btr0btr.h
storage/innobase/include/mtr0log.ic
storage/innobase/lock/lock0lock.c
storage/innobase/page/page0page.c
storage/innobase/row/row0ins.c
storage/innobase/row/row0sel.c
storage/innobase/row/row0umod.c
storage/innobase/row/row0upd.c
storage/innobase/srv/srv0srv.c
storage/innobase/trx/trx0purge.c
storage/innobase/trx/trx0rec.c
3710 Guilhem Bichot 2012-01-26 [merge]
merge from 5.1
modified:
mysql-test/r/range.result
mysql-test/t/range.test
sql/item.cc
=== modified file 'storage/innobase/btr/btr0btr.c'
--- a/storage/innobase/btr/btr0btr.c revid:guilhem.bichot@oracle.com-20120126093828-3nb40whrhkp2cz11
+++ b/storage/innobase/btr/btr0btr.c revid:marko.makela@stripped2400-lmni2h5frvv5v54z
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -42,6 +42,27 @@ Created 6/2/1994 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "trx0trx.h"
+/**************************************************************//**
+Report that an index page is corrupted. */
+UNIV_INTERN
+void
+btr_corruption_report(
+/*==================*/
+ const buf_block_t* block, /*!< in: corrupted block */
+ const dict_index_t* index) /*!< in: index tree */
+{
+ fprintf(stderr, "InnoDB: flag mismatch in space %u page %u"
+ " index %s of table %s\n",
+ (unsigned) buf_block_get_space(block),
+ (unsigned) buf_block_get_page_no(block),
+ index->name, index->table_name);
+ buf_page_print(buf_block_get_frame(block), 0);
+ if (block->page.zip.data) {
+ buf_page_print(block->page.zip.data,
+ buf_block_get_zip_size(block));
+ }
+}
+
#ifdef UNIV_BLOB_DEBUG
# include "srv0srv.h"
# include "ut0rbt.h"
@@ -692,8 +713,7 @@ btr_root_block_get(
block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH,
index, mtr);
- ut_a((ibool)!!page_is_comp(buf_block_get_frame(block))
- == dict_table_is_comp(index->table));
+ btr_assert_not_corrupted(block, index);
#ifdef UNIV_BTR_DEBUG
if (!dict_index_is_ibuf(index)) {
const page_t* root = buf_block_get_frame(block);
@@ -1532,7 +1552,7 @@ btr_page_reorganize_low(
ibool success = FALSE;
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
- ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table));
+ btr_assert_not_corrupted(block, index);
#ifdef UNIV_ZIP_DEBUG
ut_a(!page_zip || page_zip_validate(page_zip, page));
#endif /* UNIV_ZIP_DEBUG */
@@ -3164,7 +3184,8 @@ btr_compress(
block = btr_cur_get_block(cursor);
page = btr_cur_get_page(cursor);
index = btr_cur_get_index(cursor);
- ut_a((ibool) !!page_is_comp(page) == dict_table_is_comp(index->table));
+
+ btr_assert_not_corrupted(block, index);
ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
=== modified file 'storage/innobase/btr/btr0cur.c'
--- a/storage/innobase/btr/btr0cur.c revid:guilhem.bichot@stripped
+++ b/storage/innobase/btr/btr0cur.c revid:marko.makela@oracle.com-20120126112400-lmni2h5frvv5v54z
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -762,11 +762,11 @@ retry_page_get:
if (level != 0) {
/* x-latch the page */
- page = btr_page_get(
+ buf_block_t* child_block = btr_block_get(
space, zip_size, page_no, RW_X_LATCH, index, mtr);
- ut_a((ibool)!!page_is_comp(page)
- == dict_table_is_comp(index->table));
+ page = buf_block_get_frame(child_block);
+ btr_assert_not_corrupted(child_block, index);
} else {
cursor->low_match = low_match;
cursor->low_bytes = low_bytes;
=== modified file 'storage/innobase/buf/buf0buf.c'
--- a/storage/innobase/buf/buf0buf.c revid:guilhem.bichot@stripped
+++ b/storage/innobase/buf/buf0buf.c revid:marko.makela@oracle.com-20120126112400-lmni2h5frvv5v54z
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -615,6 +615,8 @@ buf_page_print(
ulint old_checksum;
ulint size = zip_size;
+ ut_ad(0);
+
if (!size) {
size = UNIV_PAGE_SIZE;
}
=== modified file 'storage/innobase/ibuf/ibuf0ibuf.c'
--- a/storage/innobase/ibuf/ibuf0ibuf.c revid:guilhem.bichot@stripped93828-3nb40whrhkp2cz11
+++ b/storage/innobase/ibuf/ibuf0ibuf.c revid:marko.makela@stripped5frvv5v54z
@@ -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);
=== modified file 'storage/innobase/include/btr0btr.h'
--- a/storage/innobase/include/btr0btr.h revid:guilhem.bichot@oracle.com-20120126093828-3nb40whrhkp2cz11
+++ b/storage/innobase/include/btr0btr.h revid:marko.makela@stripped20120126112400-lmni2h5frvv5v54z
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -92,6 +92,26 @@ insert/delete buffer when the record is
buffer when the record is not in the buffer pool. */
#define BTR_DELETE 8192
+/**************************************************************//**
+Report that an index page is corrupted. */
+UNIV_INTERN
+void
+btr_corruption_report(
+/*==================*/
+ const buf_block_t* block, /*!< in: corrupted block */
+ const dict_index_t* index) /*!< in: index tree */
+ UNIV_COLD __attribute__((nonnull));
+
+/** Assert that a B-tree page is not corrupted.
+@param block buffer block containing a B-tree page
+@param index the B-tree index */
+#define btr_assert_not_corrupted(block, index) \
+ if ((ibool) !!page_is_comp(buf_block_get_frame(block)) \
+ != dict_table_is_comp((index)->table)) { \
+ btr_corruption_report(block, index); \
+ ut_error; \
+ }
+
#ifdef UNIV_BLOB_DEBUG
# include "ut0rbt.h"
/** An index->blobs entry for keeping track of off-page column references */
=== modified file 'storage/innobase/include/mtr0log.ic'
--- a/storage/innobase/include/mtr0log.ic revid:guilhem.bichot@strippedrhkp2cz11
+++ b/storage/innobase/include/mtr0log.ic revid:marko.makela@stripped
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -216,6 +216,7 @@ mlog_write_initial_log_record_fast(
"Please post a bug report to "
"bugs.mysql.com.\n",
type, offset, space);
+ ut_ad(0);
}
}
=== modified file 'storage/innobase/lock/lock0lock.c'
--- a/storage/innobase/lock/lock0lock.c revid:guilhem.bichot@oracle.com-20120126093828-3nb40whrhkp2cz11
+++ b/storage/innobase/lock/lock0lock.c revid:marko.makela@stripped120126112400-lmni2h5frvv5v54z
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1690,7 +1690,7 @@ lock_rec_create(
page_no = buf_block_get_page_no(block);
page = block->frame;
- ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table));
+ btr_assert_not_corrupted(block, index);
/* If rec is the supremum record, then we reset the gap and
LOCK_REC_NOT_GAP bits, as all locks on the supremum are
@@ -1795,6 +1795,7 @@ lock_rec_enqueue_waiting(
"InnoDB: Submit a detailed bug report"
" to http://bugs.mysql.com\n",
stderr);
+ ut_ad(0);
}
/* Enqueue the lock request that will wait to be granted */
@@ -3795,6 +3796,7 @@ lock_table_enqueue_waiting(
"InnoDB: Submit a detailed bug report"
" to http://bugs.mysql.com\n",
stderr);
+ ut_ad(0);
}
/* Enqueue the lock request that will wait to be granted */
=== modified file 'storage/innobase/page/page0page.c'
--- a/storage/innobase/page/page0page.c revid:guilhem.bichot@stripped126093828-3nb40whrhkp2cz11
+++ b/storage/innobase/page/page0page.c revid:marko.makela@strippedni2h5frvv5v54z
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -549,8 +549,7 @@ page_copy_rec_list_end_no_locks(
page_cur_move_to_next(&cur1);
}
- ut_a((ibool)!!page_is_comp(new_page)
- == dict_table_is_comp(index->table));
+ btr_assert_not_corrupted(new_block, index);
ut_a(page_is_comp(new_page) == page_rec_is_comp(rec));
ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == (ulint)
(page_is_comp(new_page) ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM));
=== modified file 'storage/innobase/row/row0ins.c'
--- a/storage/innobase/row/row0ins.c revid:guilhem.bichot@stripped40whrhkp2cz11
+++ b/storage/innobase/row/row0ins.c revid:marko.makela@stripped
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -950,7 +950,7 @@ row_ins_foreign_check_on_constraint(
fputs("\n"
"InnoDB: Submit a detailed bug report to"
" http://bugs.mysql.com\n", stderr);
-
+ ut_ad(0);
err = DB_SUCCESS;
goto nonstandard_exit_func;
=== modified file 'storage/innobase/row/row0sel.c'
--- a/storage/innobase/row/row0sel.c revid:guilhem.bichot@stripped
+++ b/storage/innobase/row/row0sel.c revid:marko.makela@oracle.com-20120126112400-lmni2h5frvv5v54z
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -2963,6 +2963,7 @@ row_sel_get_clust_rec_for_mysql(
fputs("\n"
"InnoDB: Submit a detailed bug report"
" to http://bugs.mysql.com\n", stderr);
+ ut_ad(0);
}
clust_rec = NULL;
=== modified file 'storage/innobase/row/row0umod.c'
--- a/storage/innobase/row/row0umod.c revid:guilhem.bichot@stripped26093828-3nb40whrhkp2cz11
+++ b/storage/innobase/row/row0umod.c revid:marko.makela@strippedh5frvv5v54z
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -509,6 +509,7 @@ row_undo_mod_del_unmark_sec_and_undo_upd
fputs("\n"
"InnoDB: Submit a detailed bug report"
" to http://bugs.mysql.com\n", stderr);
+ ut_ad(0);
break;
case ROW_FOUND:
btr_cur = btr_pcur_get_btr_cur(&pcur);
=== modified file 'storage/innobase/row/row0upd.c'
--- a/storage/innobase/row/row0upd.c revid:guilhem.bichot@stripped8-3nb40whrhkp2cz11
+++ b/storage/innobase/row/row0upd.c revid:marko.makela@stripped54z
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1617,6 +1617,7 @@ row_upd_sec_index_entry(
fputs("\n"
"InnoDB: Submit a detailed bug report"
" to http://bugs.mysql.com\n", stderr);
+ ut_ad(0);
break;
case ROW_FOUND:
/* Delete mark the old index record; it can already be
=== modified file 'storage/innobase/srv/srv0srv.c'
--- a/storage/innobase/srv/srv0srv.c revid:guilhem.bichot@stripped0whrhkp2cz11
+++ b/storage/innobase/srv/srv0srv.c revid:marko.makela@stripped
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
@@ -2415,6 +2415,7 @@ loop:
"InnoDB: Please submit a bug report"
" to http://bugs.mysql.com\n",
old_lsn, new_lsn);
+ ut_ad(0);
}
old_lsn = new_lsn;
=== modified file 'storage/innobase/trx/trx0purge.c'
--- a/storage/innobase/trx/trx0purge.c revid:guilhem.bichot@stripped93828-3nb40whrhkp2cz11
+++ b/storage/innobase/trx/trx0purge.c revid:marko.makela@strippedfrvv5v54z
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2011, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -730,6 +730,7 @@ trx_purge_rseg_get_next_history_log(
"InnoDB: report, and submit it"
" to http://bugs.mysql.com\n",
(ulong) trx_sys->rseg_history_len);
+ ut_ad(0);
}
mutex_exit(&kernel_mutex);
=== modified file 'storage/innobase/trx/trx0rec.c'
--- a/storage/innobase/trx/trx0rec.c revid:guilhem.bichot@oracle.com-20120126093828-3nb40whrhkp2cz11
+++ b/storage/innobase/trx/trx0rec.c revid:marko.makela@stripped26112400-lmni2h5frvv5v54z
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1003,6 +1003,7 @@ trx_undo_update_rec_get_update(
fprintf(stderr, "\n"
"InnoDB: n_fields = %lu, i = %lu, ptr %p\n",
(ulong) n_fields, (ulong) i, ptr);
+ ut_ad(0);
*upd = NULL;
return(NULL);
}
@@ -1513,6 +1514,7 @@ trx_undo_prev_version_build(
"InnoDB: record version ", stderr);
rec_print_new(stderr, rec, offsets);
putc('\n', stderr);
+ ut_ad(0);
return(DB_ERROR);
}
@@ -1618,6 +1620,7 @@ trx_undo_prev_version_build(
(ullint) old_roll_ptr, (ullint) roll_ptr);
trx_purge_sys_print();
+ ut_ad(0);
return(DB_ERROR);
}
No bundle (reason: useless for push emails).| Thread |
|---|
| • bzr push into mysql-5.5 branch (marko.makela:3710 to 3711) Bug#13413535 | marko.makela | 30 Jan |