diff options
Diffstat (limited to 'storage/innobase/buf')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 9 | ||||
-rw-r--r-- | storage/innobase/buf/buf0lru.cc | 14 | ||||
-rw-r--r-- | storage/innobase/buf/buf0rea.cc | 47 |
3 files changed, 66 insertions, 4 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 2ae668ace50..2b543d8d1cf 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -3866,9 +3866,10 @@ buf_mark_space_corrupt( /********************************************************************//** Completes an asynchronous read or write request of a file page to or from -the buffer pool. */ +the buffer pool. +@return TRUE if successful */ UNIV_INTERN -void +ibool buf_page_io_complete( /*=================*/ buf_page_t* bpage) /*!< in: pointer to the block in question */ @@ -3995,7 +3996,7 @@ corrupt: table as corrupted instead of crashing server */ if (bpage->space > TRX_SYS_SPACE && buf_mark_space_corrupt(bpage)) { - return; + return(FALSE); } else { fputs("InnoDB: Ending processing" " because of" @@ -4087,6 +4088,8 @@ corrupt: mutex_exit(buf_page_get_mutex(bpage)); buf_pool_mutex_exit(buf_pool); + + return(TRUE); } /*********************************************************************//** diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 92883269d42..1e2c15f969f 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1993,9 +1993,23 @@ buf_LRU_free_one_page( be in a state where it can be freed; there may or may not be a hash index to the page */ { +#ifdef UNIV_DEBUG + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); +#endif + mutex_t* block_mutex = buf_page_get_mutex(bpage); + + ut_ad(buf_pool_mutex_own(buf_pool)); + ut_ad(mutex_own(block_mutex)); + if (buf_LRU_block_remove_hashed_page(bpage, TRUE) != BUF_BLOCK_ZIP_FREE) { buf_LRU_block_free_hashed_page((buf_block_t*) bpage); + } else { + /* The block_mutex should have been released by + buf_LRU_block_remove_hashed_page() when it returns + BUF_BLOCK_ZIP_FREE. */ + ut_ad(block_mutex == &buf_pool->zip_mutex); + mutex_enter(block_mutex); } } diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index 1b3e5deed05..227cb083725 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -52,6 +52,44 @@ i/o-fixed buffer blocks */ #define BUF_READ_AHEAD_PEND_LIMIT 2 /********************************************************************//** +Unfixes the pages, unlatches the page, +removes it from page_hash and removes it from LRU. */ +static +void +buf_read_page_handle_error( +/*=======================*/ + buf_page_t* bpage) /*!< in: pointer to the block */ +{ + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + const ibool uncompressed = (buf_page_get_state(bpage) + == BUF_BLOCK_FILE_PAGE); + + /* First unfix and release lock on the bpage */ + buf_pool_mutex_enter(buf_pool); + mutex_enter(buf_page_get_mutex(bpage)); + ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ); + ut_ad(bpage->buf_fix_count == 0); + + /* Set BUF_IO_NONE before we remove the block from LRU list */ + buf_page_set_io_fix(bpage, BUF_IO_NONE); + + if (uncompressed) { + rw_lock_x_unlock_gen( + &((buf_block_t*) bpage)->lock, + BUF_IO_READ); + } + + /* remove the block from LRU list */ + buf_LRU_free_one_page(bpage); + + ut_ad(buf_pool->n_pend_reads > 0); + buf_pool->n_pend_reads--; + + mutex_exit(buf_page_get_mutex(bpage)); + buf_pool_mutex_exit(buf_pool); +} + +/********************************************************************//** Low-level function which reads a page asynchronously from a file to the buffer buf_pool if it is not already there, in which case does nothing. Sets the io_fix flag and sets an exclusive lock on the buffer frame. The @@ -154,6 +192,11 @@ buf_read_page_low( } thd_wait_end(NULL); + if (*err == DB_TABLESPACE_DELETED) { + buf_read_page_handle_error(bpage); + return(0); + } + if (*err != DB_SUCCESS) { if (ignore_nonexistent_pages) { return(0); @@ -165,7 +208,9 @@ buf_read_page_low( if (sync) { /* The i/o is already completed when we arrive from fil_read */ - buf_page_io_complete(bpage); + if (!buf_page_io_complete(bpage)) { + return(0); + } } return(1); |