Commit 34e5d474 authored by Marko Mäkelä's avatar Marko Mäkelä

Backport an InnoDB Bug #58815 (Bug #11765812) work-around from mysql-trunk:

------------------------------------------------------------
revno 2876.244.305
revision id marko.makela@oracle.com-20110413082211-e6ouhjz5rmqxcqap
parent  marko.makela@oracle.com-20110413075948-kvytmc37ye1nt7d9
committer  Marko Mäkelä <marko.makela@oracle.com>
branch nick 5.6-innodb
timestamp Wed 2011-04-13 11:22:11 +0300
message:
  Suppress the Bug #58815 (Bug #11765812) assertion failure.

  buf_page_get_gen(): Introduce BUF_GET_POSSIBLY_FREED for suppressing the
  check that the file page must not have been freed.

  btr_estimate_n_rows_in_range_on_level(): Pass BUF_GET_POSSIBLY_FREED and
  explain in the comments why this is needed and why it should be mostly
  harmless to ignore the problem. If InnoDB had always initialized all
  unused fields in data files, no problem would exist.

  This change does not fix the bug, it just "shoots the messenger".

  rb:647 approved by Jimmy Yang
parent 79f8d024
......@@ -3264,9 +3264,14 @@ btr_estimate_n_rows_in_range_on_level(
mtr_start(&mtr);
/* fetch the page */
block = buf_page_get(space, zip_size, page_no, RW_S_LATCH,
&mtr);
/* Fetch the page. Because we are not holding the
index->lock, the tree may have changed and we may be
attempting to read a page that is no longer part of
the B-tree. We pass BUF_GET_POSSIBLY_FREED in order to
silence a debug assertion about this. */
block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH,
NULL, BUF_GET_POSSIBLY_FREED,
__FILE__, __LINE__, &mtr);
page = buf_block_get_frame(block);
......@@ -3285,6 +3290,13 @@ btr_estimate_n_rows_in_range_on_level(
goto inexact;
}
/* It is possible but highly unlikely that the page was
originally written by an old version of InnoDB that did
not initialize FIL_PAGE_TYPE on other than B-tree pages.
For example, this could be an almost-empty BLOB page
that happens to contain the magic values in the fields
that we checked above. */
n_pages_read++;
if (page_no != slot1->page_no) {
......
......@@ -2747,6 +2747,7 @@ buf_page_get_gen(
case BUF_GET_IF_IN_POOL:
case BUF_PEEK_IF_IN_POOL:
case BUF_GET_IF_IN_POOL_OR_WATCH:
case BUF_GET_POSSIBLY_FREED:
break;
default:
ut_error;
......@@ -3062,7 +3063,10 @@ wait_until_unfixed:
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
buf_block_buf_fix_inc(block, file, line);
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(mode == BUF_GET_POSSIBLY_FREED
|| !block->page.file_page_was_freed);
#endif
mutex_exit(&block->mutex);
/* Check if this is the first access to the page */
......@@ -3075,10 +3079,6 @@ wait_until_unfixed:
buf_page_set_accessed_make_young(&block->page, access_time);
}
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(!block->page.file_page_was_freed);
#endif
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(++buf_dbg_counter % 5771 || buf_validate());
ut_a(block->page.buf_fix_count > 0);
......
......@@ -53,6 +53,9 @@ Created 11/5/1995 Heikki Tuuri
/*!< Get the page only if it's in the
buffer pool, if not then set a watch
on the page. */
#define BUF_GET_POSSIBLY_FREED 16
/*!< Like BUF_GET, but do not mind
if the file page has been freed. */
/* @} */
/** @name Modes for buf_page_get_known_nowait */
/* @{ */
......
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