mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 14:33:32 +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:
		@@ -3470,9 +3470,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 */
 | 
			
		||||
@@ -3599,7 +3600,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"
 | 
			
		||||
@@ -3689,6 +3690,8 @@ corrupt:
 | 
			
		||||
 | 
			
		||||
	mutex_exit(buf_page_get_mutex(bpage));
 | 
			
		||||
	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
 | 
			
		||||
				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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,6 +50,44 @@ read-ahead is not done: this is to prevent flooding the buffer pool with
 | 
			
		||||
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.
 | 
			
		||||
@@ -152,12 +190,20 @@ buf_read_page_low(
 | 
			
		||||
			      ((buf_block_t*) bpage)->frame, bpage);
 | 
			
		||||
	}
 | 
			
		||||
	thd_wait_end(NULL);
 | 
			
		||||
 | 
			
		||||
	if (*err == DB_TABLESPACE_DELETED) {
 | 
			
		||||
		buf_read_page_handle_error(bpage);
 | 
			
		||||
		return(0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ut_a(*err == DB_SUCCESS);
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
 
 | 
			
		||||
@@ -1162,9 +1162,10 @@ buf_page_init_for_read(
 | 
			
		||||
	ulint		offset);/*!< in: page number */
 | 
			
		||||
/********************************************************************//**
 | 
			
		||||
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 */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user