Commit 26740944 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 7201c801
...@@ -224,6 +224,9 @@ in the free list to the frames. ...@@ -224,6 +224,9 @@ in the free list to the frames.
/* Value in microseconds */ /* Value in microseconds */
static const int WAIT_FOR_READ = 20000; 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 */ buf_pool_t* buf_pool = NULL; /* The buffer buf_pool of the database */
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
...@@ -1160,6 +1163,7 @@ buf_page_get_gen( ...@@ -1160,6 +1163,7 @@ buf_page_get_gen(
ulint fix_type; ulint fix_type;
ibool success; ibool success;
ibool must_read; ibool must_read;
ulint retries = 0;
ut_ad(mtr); ut_ad(mtr);
ut_ad((rw_latch == RW_S_LATCH) ut_ad((rw_latch == RW_S_LATCH)
...@@ -1200,7 +1204,29 @@ buf_page_get_gen( ...@@ -1200,7 +1204,29 @@ buf_page_get_gen(
return(NULL); 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 #ifdef UNIV_DEBUG
buf_dbg_counter++; buf_dbg_counter++;
......
...@@ -299,30 +299,27 @@ buffer buf_pool if it is not already there. Sets the io_fix flag and sets ...@@ -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 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 released by the i/o-handler thread. Does a random read-ahead if it seems
sensible. */ sensible. */
ibool
ulint
buf_read_page( buf_read_page(
/*==========*/ /*==========*/
/* out: number of page read requests issued: this can /* out: TRUE if success, FALSE otherwise */
be > 1 if read-ahead occurred */
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint offset) /* in: page number */ ulint offset) /* in: page number */
{ {
ib_longlong tablespace_version; ib_longlong tablespace_version;
ulint count; ulint count;
ulint count2;
ulint err; ulint err;
tablespace_version = fil_space_get_version(space); 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 /* We do the i/o in the synchronous aio mode to save thread
switches: hence TRUE */ 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); tablespace_version, offset);
srv_buf_pool_reads+= count2; srv_buf_pool_reads+= count;
if (err == DB_TABLESPACE_DELETED) { if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
...@@ -336,7 +333,7 @@ buf_read_page( ...@@ -336,7 +333,7 @@ buf_read_page(
/* Flush pages from the end of the LRU list if necessary */ /* Flush pages from the end of the LRU list if necessary */
buf_flush_free_margin(); 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 ...@@ -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 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 released by the i/o-handler thread. Does a random read-ahead if it seems
sensible. */ sensible. */
ibool
ulint
buf_read_page( buf_read_page(
/*==========*/ /*==========*/
/* out: number of page read requests issued: this can /* out: TRUE if success, FALSE otherwise */
be > 1 if read-ahead occurred */
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint offset);/* in: page number */ 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