Commit af2cb5e4 authored by inaam's avatar inaam

branches/5.1: Fix Bug #38901

InnoDB logs error repeatedly when trying to load page into buffer pool

In buf_page_get_gen() if we are unable to read a page (because of
corruption or some other reason) we keep on retrying. This fills up
error log with millions of entries in no time and we'd eventually run
out of disk space. This patch limits the number of attempts that we
make (currently set to 100) and after that we abort with a message.

rb://241 Approved by: Heikki
parent 91eadaf4
......@@ -224,6 +224,9 @@ in the free list to the frames.
/* Value in microseconds */
static const int WAIT_FOR_READ = 20000;
/* Number of attemtps made to read in a page in the buffer pool */
static const ulint BUF_PAGE_READ_MAX_RETRIES = 100;
buf_pool_t* buf_pool = NULL; /* The buffer buf_pool of the database */
#ifdef UNIV_DEBUG
......@@ -1160,6 +1163,7 @@ buf_page_get_gen(
ulint fix_type;
ibool success;
ibool must_read;
ulint retries = 0;
ut_ad(mtr);
ut_ad((rw_latch == RW_S_LATCH)
......@@ -1200,7 +1204,29 @@ loop:
return(NULL);
}
buf_read_page(space, offset);
if (buf_read_page(space, offset)) {
retries = 0;
} else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
++retries;
} else {
fprintf(stderr, "InnoDB: Error: Unable"
" to read tablespace %lu page no"
" %lu into the buffer pool after"
" %lu attempts\n"
"InnoDB: The most probable cause"
" of this error may be that the"
" table has been corrupted.\n"
"InnoDB: You can try to fix this"
" problem by using"
" innodb_force_recovery.\n"
"InnoDB: Please see reference manual"
" for more details.\n"
"InnoDB: Aborting...\n",
space, offset,
BUF_PAGE_READ_MAX_RETRIES);
ut_error;
}
#ifdef UNIV_DEBUG
buf_dbg_counter++;
......
......@@ -299,30 +299,27 @@ buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
released by the i/o-handler thread. Does a random read-ahead if it seems
sensible. */
ulint
ibool
buf_read_page(
/*==========*/
/* out: number of page read requests issued: this can
be > 1 if read-ahead occurred */
/* out: TRUE if success, FALSE otherwise */
ulint space, /* in: space id */
ulint offset) /* in: page number */
{
ib_longlong tablespace_version;
ulint count;
ulint count2;
ulint err;
tablespace_version = fil_space_get_version(space);
count = buf_read_ahead_random(space, offset);
buf_read_ahead_random(space, offset);
/* We do the i/o in the synchronous aio mode to save thread
switches: hence TRUE */
count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
tablespace_version, offset);
srv_buf_pool_reads+= count2;
srv_buf_pool_reads+= count;
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
......@@ -336,7 +333,7 @@ buf_read_page(
/* Flush pages from the end of the LRU list if necessary */
buf_flush_free_margin();
return(count + count2);
return(count > 0);
}
/************************************************************************
......
......@@ -18,12 +18,10 @@ buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
released by the i/o-handler thread. Does a random read-ahead if it seems
sensible. */
ulint
ibool
buf_read_page(
/*==========*/
/* out: number of page read requests issued: this can
be > 1 if read-ahead occurred */
/* out: TRUE if success, FALSE otherwise */
ulint space, /* in: space id */
ulint offset);/* in: page number */
/************************************************************************
......
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