diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index abfde83a3bd..03133e81ceb 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -246,8 +246,8 @@ static const int WAIT_FOR_READ = 5000; /** Number of attemtps made to read in a page in the buffer pool */ static const ulint BUF_PAGE_READ_MAX_RETRIES = 100; -/** The buffer buf_pool of the database */ -UNIV_INTERN buf_pool_t* buf_pool_ptr[MAX_BUFFER_POOLS]; +/** The buffer pools of the database */ +UNIV_INTERN buf_pool_t* buf_pool_ptr; #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG static ulint buf_dbg_counter = 0; /*!< This is used to insert validation @@ -858,7 +858,7 @@ buf_block_init( block->frame = frame; - block->page.buf_pool = buf_pool; + block->page.buf_pool_index = buf_pool_index(buf_pool); block->page.state = BUF_BLOCK_NOT_USED; block->page.buf_fix_count = 0; block->page.io_fix = BUF_IO_NONE; @@ -1280,8 +1280,6 @@ buf_pool_free_instance( mem_free(buf_pool->chunks); hash_table_free(buf_pool->page_hash); hash_table_free(buf_pool->zip_hash); - mem_free(buf_pool); - buf_pool = NULL; } /********************************************************************//** @@ -1294,25 +1292,22 @@ buf_pool_init( ulint total_size, /*!< in: size of the total pool in bytes */ ulint n_instances) /*!< in: number of instances */ { - ulint i; + ulint i; + const ulint size = total_size / n_instances; + + ut_ad(n_instances < MAX_BUFFER_POOLS); + ut_ad(n_instances == srv_buf_pool_instances); /* We create an extra buffer pool instance, this instance is used for flushing the flush lists, to keep track of n_flush for all the buffer pools and also used as a waiting object during flushing. */ + buf_pool_ptr = mem_zalloc(n_instances * sizeof *buf_pool_ptr); + for (i = 0; i < n_instances; i++) { - buf_pool_t* ptr; - ulint size; - - ptr = mem_zalloc(sizeof(*ptr)); - - size = total_size / n_instances; - - buf_pool_ptr[i] = ptr; + buf_pool_t* ptr = &buf_pool_ptr[i]; if (buf_pool_init_instance(ptr, size, i) != DB_SUCCESS) { - mem_free(buf_pool_ptr[i]); - /* Free all the instances created so far. */ buf_pool_free(i); @@ -1341,8 +1336,10 @@ buf_pool_free( for (i = 0; i < n_instances; i++) { buf_pool_free_instance(buf_pool_from_array(i)); - buf_pool_ptr[i] = NULL; } + + mem_free(buf_pool_ptr); + buf_pool_ptr = NULL; } /********************************************************************//** @@ -3685,7 +3682,7 @@ err_exit: bpage = buf_buddy_alloc(buf_pool, sizeof *bpage, &lru); /* Initialize the buf_pool pointer. */ - bpage->buf_pool = buf_pool; + bpage->buf_pool_index = buf_pool_index(buf_pool); /* If buf_buddy_alloc() allocated storage from the LRU list, it released and reacquired buf_pool->mutex. Thus, we must diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index b0fff919918..a42eba57fd2 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -69,7 +69,7 @@ Created 11/5/1995 Heikki Tuuri #define BUF_POOL_WATCH_SIZE 1 /*!< Maximum number of concurrent buffer pool watches */ -extern buf_pool_t* buf_pool_ptr[MAX_BUFFER_POOLS]; /*!< The buffer pools +extern buf_pool_t* buf_pool_ptr; /*!< The buffer pools of the database */ #ifdef UNIV_DEBUG extern ibool buf_debug_prints;/*!< If this is set TRUE, the program @@ -1034,6 +1034,15 @@ buf_page_address_fold( ulint space, /*!< in: space id */ ulint offset) /*!< in: offset of the page within space */ __attribute__((const)); +/********************************************************************//** +Calculates the index of a buffer pool to the buf_pool[] array. +@return the position of the buffer pool in buf_pool[] */ +UNIV_INLINE +ulint +buf_pool_index( +/*===========*/ + const buf_pool_t* buf_pool) /*!< in: buffer pool */ + __attribute__((nonnull, const)); /******************************************************************//** Returns the buffer pool instance given a page instance @return buf_pool */ @@ -1065,8 +1074,9 @@ Returns the buffer pool instance given its array index UNIV_INLINE buf_pool_t* buf_pool_from_array( -/*====================*/ - ulint index); /*!< in: array index to get buffer pool instance from */ +/*================*/ + ulint index); /*!< in: array index to get + buffer pool instance from */ /******************************************************************//** Returns the control block of a file page, NULL if not found. @return block, NULL if not found */ @@ -1204,8 +1214,13 @@ struct buf_page_struct{ unsigned io_fix:2; /*!< type of pending I/O operation; also protected by buf_pool->mutex @see enum buf_io_fix */ - unsigned buf_fix_count:25;/*!< count of how manyfold this block + unsigned buf_fix_count:19;/*!< count of how manyfold this block is currently bufferfixed */ + unsigned buf_pool_index:6;/*!< index number of the buffer pool + that this block belongs to */ +# if MAX_BUFFER_POOLS > 64 +# error "MAX_BUFFER_POOLS > 64; redefine buf_pool_index:6" +# endif /* @} */ #endif /* !UNIV_HOTBACKUP */ page_zip_des_t zip; /*!< compressed page; zip.data @@ -1324,8 +1339,6 @@ struct buf_page_struct{ frees a page in buffer pool */ # endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* !UNIV_HOTBACKUP */ - buf_pool_t* buf_pool; /*!< buffer pool instance this - page belongs to */ }; /** The buffer control block structure */ diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 713b7cb990d..e2e83de0a78 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -46,6 +46,48 @@ buf_pool_get_curr_size(void) return(srv_buf_pool_curr_size); } +/********************************************************************//** +Calculates the index of a buffer pool to the buf_pool[] array. +@return the position of the buffer pool in buf_pool[] */ +UNIV_INLINE +ulint +buf_pool_index( +/*===========*/ + const buf_pool_t* buf_pool) /*!< in: buffer pool */ +{ + ulint i = buf_pool - buf_pool_ptr; + ut_ad(i < MAX_BUFFER_POOLS); + ut_ad(i < srv_buf_pool_instances); + return(i); +} + +/******************************************************************//** +Returns the buffer pool instance given a page instance +@return buf_pool */ +UNIV_INLINE +buf_pool_t* +buf_pool_from_bpage( +/*================*/ + const buf_page_t* bpage) /*!< in: buffer pool page */ +{ + ulint i; + i = bpage->buf_pool_index; + ut_ad(i < srv_buf_pool_instances); + return(&buf_pool_ptr[i]); +} + +/******************************************************************//** +Returns the buffer pool instance given a block instance +@return buf_pool */ +UNIV_INLINE +buf_pool_t* +buf_pool_from_block( +/*================*/ + const buf_block_t* block) /*!< in: block */ +{ + return(buf_pool_from_bpage(&block->page)); +} + /*********************************************************************//** Gets the current size of buffer buf_pool in pages. @return size in pages*/ @@ -885,33 +927,6 @@ buf_block_buf_fix_dec( #endif } -/******************************************************************//** -Returns the buffer pool instance given a page instance -@return buf_pool */ -UNIV_INLINE -buf_pool_t* -buf_pool_from_bpage( -/*================*/ - const buf_page_t* bpage) /*!< in: buffer pool page */ -{ - /* Every page must be in some buffer pool. */ - ut_ad(bpage->buf_pool != NULL); - - return(bpage->buf_pool); -} - -/******************************************************************//** -Returns the buffer pool instance given a block instance -@return buf_pool */ -UNIV_INLINE -buf_pool_t* -buf_pool_from_block( -/*================*/ - const buf_block_t* block) /*!< in: block */ -{ - return(buf_pool_from_bpage(&block->page)); -} - /******************************************************************//** Returns the buffer pool instance given space and offset of page @return buffer pool */ @@ -929,7 +944,7 @@ buf_pool_get( ignored_offset = offset >> 6; /* 2log of BUF_READ_AHEAD_AREA (64)*/ fold = buf_page_address_fold(space, ignored_offset); index = fold % srv_buf_pool_instances; - return buf_pool_ptr[index]; + return(&buf_pool_ptr[index]); } /******************************************************************//** @@ -939,10 +954,12 @@ UNIV_INLINE buf_pool_t* buf_pool_from_array( /*================*/ - ulint index) /*!< in: array index to get + ulint index) /*!< in: array index to get buffer pool instance from */ { - return buf_pool_ptr[index]; + ut_ad(index < MAX_BUFFER_POOLS); + ut_ad(index < srv_buf_pool_instances); + return(&buf_pool_ptr[index]); } /******************************************************************//**