mirror of
https://github.com/MariaDB/server.git
synced 2025-05-13 01:01:44 +03:00
Bug#14251529 : FIX FOR BUG 13704145 CREATES POSSIBLE RACE CONDITION
make buf_read_page_low() to treat DB_TABLESPACE_DELETED error correctly rb#1129 approved by Inaam
This commit is contained in:
parent
247262347e
commit
6058319dba
@ -3470,9 +3470,10 @@ buf_mark_space_corrupt(
|
|||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Completes an asynchronous read or write request of a file page to or from
|
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
|
UNIV_INTERN
|
||||||
void
|
ibool
|
||||||
buf_page_io_complete(
|
buf_page_io_complete(
|
||||||
/*=================*/
|
/*=================*/
|
||||||
buf_page_t* bpage) /*!< in: pointer to the block in question */
|
buf_page_t* bpage) /*!< in: pointer to the block in question */
|
||||||
@ -3599,7 +3600,7 @@ corrupt:
|
|||||||
table as corrupted instead of crashing server */
|
table as corrupted instead of crashing server */
|
||||||
if (bpage->space > TRX_SYS_SPACE
|
if (bpage->space > TRX_SYS_SPACE
|
||||||
&& buf_mark_space_corrupt(bpage)) {
|
&& buf_mark_space_corrupt(bpage)) {
|
||||||
return;
|
return(FALSE);
|
||||||
} else {
|
} else {
|
||||||
fputs("InnoDB: Ending processing"
|
fputs("InnoDB: Ending processing"
|
||||||
" because of"
|
" because of"
|
||||||
@ -3689,6 +3690,8 @@ corrupt:
|
|||||||
|
|
||||||
mutex_exit(buf_page_get_mutex(bpage));
|
mutex_exit(buf_page_get_mutex(bpage));
|
||||||
buf_pool_mutex_exit(buf_pool);
|
buf_pool_mutex_exit(buf_pool);
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
|
@ -2164,9 +2164,23 @@ buf_LRU_free_one_page(
|
|||||||
be in a state where it can be freed; there
|
be in a state where it can be freed; there
|
||||||
may or may not be a hash index to the page */
|
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)
|
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
|
||||||
!= BUF_BLOCK_ZIP_FREE) {
|
!= BUF_BLOCK_ZIP_FREE) {
|
||||||
buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,44 @@ read-ahead is not done: this is to prevent flooding the buffer pool with
|
|||||||
i/o-fixed buffer blocks */
|
i/o-fixed buffer blocks */
|
||||||
#define BUF_READ_AHEAD_PEND_LIMIT 2
|
#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
|
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.
|
buffer buf_pool if it is not already there, in which case does nothing.
|
||||||
@ -152,12 +190,20 @@ buf_read_page_low(
|
|||||||
((buf_block_t*) bpage)->frame, bpage);
|
((buf_block_t*) bpage)->frame, bpage);
|
||||||
}
|
}
|
||||||
thd_wait_end(NULL);
|
thd_wait_end(NULL);
|
||||||
|
|
||||||
|
if (*err == DB_TABLESPACE_DELETED) {
|
||||||
|
buf_read_page_handle_error(bpage);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
ut_a(*err == DB_SUCCESS);
|
ut_a(*err == DB_SUCCESS);
|
||||||
|
|
||||||
if (sync) {
|
if (sync) {
|
||||||
/* The i/o is already completed when we arrive from
|
/* The i/o is already completed when we arrive from
|
||||||
fil_read */
|
fil_read */
|
||||||
buf_page_io_complete(bpage);
|
if (!buf_page_io_complete(bpage)) {
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
|
@ -1162,9 +1162,10 @@ buf_page_init_for_read(
|
|||||||
ulint offset);/*!< in: page number */
|
ulint offset);/*!< in: page number */
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Completes an asynchronous read or write request of a file page to or from
|
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
|
UNIV_INTERN
|
||||||
void
|
ibool
|
||||||
buf_page_io_complete(
|
buf_page_io_complete(
|
||||||
/*=================*/
|
/*=================*/
|
||||||
buf_page_t* bpage); /*!< in: pointer to the block in question */
|
buf_page_t* bpage); /*!< in: pointer to the block in question */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user