diff options
Diffstat (limited to 'storage/innobase/include/buf0buf.h')
-rw-r--r-- | storage/innobase/include/buf0buf.h | 276 |
1 files changed, 197 insertions, 79 deletions
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 62e4f54559a..5326ca9c14f 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -63,7 +63,14 @@ Created 11/5/1995 Heikki Tuuri position of the block. */ /* @} */ -extern buf_pool_t* buf_pool; /*!< The buffer pool of the database */ +#define MAX_BUFFER_POOLS 64 /*!< The maximum number of buffer + pools that can be defined */ + +#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 + of the database */ #ifdef UNIV_DEBUG extern ibool buf_debug_prints;/*!< If this is set TRUE, the program prints info whenever read or flush @@ -71,6 +78,8 @@ extern ibool buf_debug_prints;/*!< If this is set TRUE, the program #endif /* UNIV_DEBUG */ extern ulint srv_buf_pool_write_requests; /*!< variable to count write request issued */ +extern ulint srv_buf_pool_instances; +extern ulint srv_buf_pool_curr_size; #else /* !UNIV_HOTBACKUP */ extern buf_block_t* back_block1; /*!< first block, for --apply-log */ extern buf_block_t* back_block2; /*!< second block, for page reorganize */ @@ -109,19 +118,36 @@ enum buf_page_state { #ifndef UNIV_HOTBACKUP /********************************************************************//** +Acquire mutex on all buffer pool instances */ +UNIV_INLINE +void +buf_pool_mutex_enter_all(void); +/*===========================*/ + +/********************************************************************//** +Release mutex on all buffer pool instances */ +UNIV_INLINE +void +buf_pool_mutex_exit_all(void); +/*==========================*/ + +/********************************************************************//** Creates the buffer pool. @return own: buf_pool object, NULL if not enough memory or error */ UNIV_INTERN -buf_pool_t* -buf_pool_init(void); -/*===============*/ +ulint +buf_pool_init( +/*=========*/ + ulint size, /*!< in: Size of the total pool in bytes */ + ulint n_instances); /*!< in: Number of instances */ /********************************************************************//** Frees the buffer pool at shutdown. This must not be invoked before freeing all mutexes. */ UNIV_INTERN void -buf_pool_free(void); -/*===============*/ +buf_pool_free( +/*==========*/ + ulint n_instances); /*!< in: numbere of instances to free */ /********************************************************************//** Drops the adaptive hash index. To prevent a livelock, this function @@ -158,23 +184,31 @@ UNIV_INLINE ulint buf_pool_get_curr_size(void); /*========================*/ +/*********************************************************************//** +Gets the current size of buffer buf_pool in frames. +@return size in pages */ +UNIV_INLINE +ulint +buf_pool_get_n_pages(void); +/*=======================*/ /********************************************************************//** Gets the smallest oldest_modification lsn for any page in the pool. Returns zero if all modified pages have been flushed to disk. @return oldest modification in pool, zero if none */ -UNIV_INLINE +UNIV_INTERN ib_uint64_t buf_pool_get_oldest_modification(void); /*==================================*/ /********************************************************************//** Allocates a buffer block. @return own: the allocated block, in state BUF_BLOCK_MEMORY */ -UNIV_INLINE +UNIV_INTERN buf_block_t* buf_block_alloc( /*============*/ - ulint zip_size); /*!< in: compressed page size in bytes, - or 0 if uncompressed tablespace */ + buf_pool_t* buf_pool, /*!< buffer pool instance */ + ulint zip_size); /*!< in: compressed page size in bytes, + or 0 if uncompressed tablespace */ /********************************************************************//** Frees a buffer block which does not contain a file page. */ UNIV_INLINE @@ -454,7 +488,7 @@ buf_page_get_newest_modification( page frame */ /********************************************************************//** Increments the modify clock of a frame by 1. The caller must (1) own the -buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock +buf_pool->mutex and block bufferfix count has to be zero, (2) or own an x-lock on the block. */ UNIV_INLINE void @@ -536,7 +570,8 @@ UNIV_INTERN buf_block_t* buf_pool_contains_zip( /*==================*/ - const void* data); /*!< in: pointer to compressed page */ + buf_pool_t* buf_pool, /*!< in: buffer pool instance */ + const void* data); /*!< in: pointer to compressed page */ #endif /* UNIV_DEBUG */ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /*********************************************************************//** @@ -610,8 +645,15 @@ buf_get_modified_ratio_pct(void); Refreshes the statistics used to print per-second averages. */ UNIV_INTERN void -buf_refresh_io_stats(void); -/*======================*/ +buf_refresh_io_stats( +/*=================*/ + buf_pool_t* buf_pool); /*!< buffer pool instance */ +/**********************************************************************//** +Refreshes the statistics used to print per-second averages. */ +UNIV_INTERN +void +buf_refresh_io_stats_all(void); +/*=================*/ /*********************************************************************//** Asserts that all file pages in the buffer are in a replaceable state. @return TRUE */ @@ -992,15 +1034,51 @@ buf_page_address_fold( ulint offset) /*!< in: offset of the page within space */ __attribute__((const)); /******************************************************************//** +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 */ +/******************************************************************//** +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 */ +/******************************************************************//** +Returns the buffer pool instance given space and offset of page +@return buffer pool */ +UNIV_INLINE +buf_pool_t* +buf_pool_get( +/*==========*/ + ulint space, /*!< in: space id */ + ulint offset);/*!< in: offset of the page within space */ +/******************************************************************//** +Returns the buffer pool instance given its array index +@return buffer pool */ +UNIV_INLINE +buf_pool_t* +buf_pool_from_array( +/*====================*/ + 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 */ UNIV_INLINE buf_page_t* buf_page_hash_get_low( /*==================*/ - ulint space, /*!< in: space id */ - ulint offset, /*!< in: offset of the page within space */ - ulint fold); /*!< in: buf_page_address_fold(space, offset) */ + buf_pool_t* buf_pool, /*!< buffer pool instance */ + ulint space, /*!< in: space id */ + ulint offset, /*!< in: offset of the page + within space */ + ulint fold); /*!< in: buf_page_address_fold( + space, offset) */ /******************************************************************//** Returns the control block of a file page, NULL if not found. @return block, NULL if not found or not a real control block */ @@ -1008,8 +1086,10 @@ UNIV_INLINE buf_page_t* buf_page_hash_get( /*==============*/ - ulint space, /*!< in: space id */ - ulint offset);/*!< in: offset of the page within space */ + buf_pool_t* buf_pool, /*!< in: buffer pool instance */ + ulint space, /*!< in: space id */ + ulint offset); /*!< in: offset of the page + within space */ /******************************************************************//** Returns the control block of a file page, NULL if not found or an uncompressed page frame does not exist. @@ -1018,8 +1098,10 @@ UNIV_INLINE buf_block_t* buf_block_hash_get( /*===============*/ - ulint space, /*!< in: space id */ - ulint offset);/*!< in: offset of the page within space */ + buf_pool_t* buf_pool, /*!< in: buffer pool instance */ + ulint space, /*!< in: space id */ + ulint offset); /*!< in: offset of the page + within space */ /*********************************************************************//** Gets the current length of the free list of buffer blocks. @return length of the free list */ @@ -1033,9 +1115,10 @@ Determine if a block is a sentinel for a buffer pool watch. @return TRUE if a sentinel for a buffer pool watch, FALSE if not */ UNIV_INTERN ibool -buf_pool_watch_is( -/*==============*/ - const buf_page_t* bpage) /*!< in: block */ +buf_pool_watch_is_sentinel( +/*=======================*/ + buf_pool_t* buf_pool, /*!< buffer pool instance */ + const buf_page_t* bpage) /*!< in: block */ __attribute__((nonnull, warn_unused_result)); /****************************************************************//** Add watch for the given page to be read in. Caller must have the buffer pool @@ -1069,6 +1152,23 @@ buf_pool_watch_occurred( ulint space, /*!< in: space id */ ulint offset) /*!< in: page number */ __attribute__((warn_unused_result)); +/********************************************************************//** +Get total buffer pool statistics. */ +UNIV_INTERN +void +buf_get_total_list_len( +/*===================*/ + ulint* LRU_len, /*!< out: length of all LRU lists */ + ulint* free_len, /*!< out: length of all free lists */ + ulint* flush_list_len);/*!< out: length of all flush lists */ +/********************************************************************//** +Get total buffer pool statistics. */ +UNIV_INTERN +void +buf_get_total_stat( +/*===============*/ + buf_pool_stat_t*tot_stat); /*!< out: buffer pool stats */ + #endif /* !UNIV_HOTBACKUP */ /** The common buffer control block structure @@ -1078,18 +1178,18 @@ struct buf_page_struct{ /** @name General fields None of these bit-fields must be modified without holding buf_page_get_mutex() [buf_block_struct::mutex or - buf_pool_zip_mutex], since they can be stored in the same + buf_pool->zip_mutex], since they can be stored in the same machine word. Some of these fields are additionally protected - by buf_pool_mutex. */ + by buf_pool->mutex. */ /* @{ */ unsigned space:32; /*!< tablespace id; also protected - by buf_pool_mutex. */ + by buf_pool->mutex. */ unsigned offset:32; /*!< page number; also protected - by buf_pool_mutex. */ + by buf_pool->mutex. */ unsigned state:3; /*!< state of the control block; also - protected by buf_pool_mutex. + protected by buf_pool->mutex. State transitions from BUF_BLOCK_READY_FOR_USE to BUF_BLOCK_MEMORY need not be @@ -1101,7 +1201,7 @@ struct buf_page_struct{ flush_type. @see enum buf_flush */ unsigned io_fix:2; /*!< type of pending I/O operation; - also protected by buf_pool_mutex + also protected by buf_pool->mutex @see enum buf_io_fix */ unsigned buf_fix_count:25;/*!< count of how manyfold this block is currently bufferfixed */ @@ -1190,8 +1290,8 @@ struct buf_page_struct{ any one of the two mutexes */ /* @} */ /** @name LRU replacement algorithm fields - These fields are protected by buf_pool_mutex only (not - buf_pool_zip_mutex or buf_block_struct::mutex). */ + These fields are protected by buf_pool->mutex only (not + buf_pool->zip_mutex or buf_block_struct::mutex). */ /* @{ */ UT_LIST_NODE_T(buf_page_t) LRU; @@ -1221,6 +1321,8 @@ 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 */ @@ -1260,7 +1362,7 @@ struct buf_block_struct{ unsigned lock_hash_val:32;/*!< hashed value of the page address in the record lock hash table; protected by buf_block_t::lock - (or buf_block_t::mutex, buf_pool_mutex + (or buf_block_t::mutex, buf_pool->mutex in buf_page_get_gen(), buf_page_init_for_read() and buf_page_create()) */ @@ -1389,6 +1491,16 @@ struct buf_pool_stat_struct{ buf_page_peek_if_too_old() */ }; +/** Statistics of buddy blocks of a given size. */ +struct buf_buddy_stat_struct { + /** Number of blocks allocated from the buddy system. */ + ulint used; + /** Number of blocks relocated by the buddy system. */ + ib_uint64_t relocated; + /** Total duration of block relocations, in microseconds. */ + ib_uint64_t relocated_usec; +}; + /** @brief The buffer pool structure. NOTE! The definition appears here only for other modules of this @@ -1398,7 +1510,25 @@ struct buf_pool_struct{ /** @name General fields */ /* @{ */ - + mutex_t mutex; /*!< Buffer pool mutex of this + instance */ + mutex_t zip_mutex; /*!< Zip mutex of this buffer + pool instance, protects compressed + only pages (of type buf_page_t, not + buf_block_t */ + ulint instance_no; /*!< Array index of this buffer + pool instance */ + ulint old_pool_size; /*!< Old pool size in bytes */ + ulint curr_pool_size; /*!< Current pool size in bytes */ + ulint LRU_old_ratio; /*!< Reserve this much of the buffer + pool for "old" blocks */ +#ifdef UNIV_DEBUG + ulint buddy_n_frames; /*!< Number of frames allocated from + the buffer pool to the buddy system */ +#endif +#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG + ulint mutex_exit_forbidden; /*!< Forbid release mutex */ +#endif ulint n_chunks; /*!< number of buffer pool chunks */ buf_chunk_t* chunks; /*!< buffer pool chunks */ ulint curr_size; /*!< current pool size in pages */ @@ -1410,12 +1540,16 @@ struct buf_pool_struct{ whose frames are allocated to the zip buddy system, indexed by block->frame */ - ulint n_pend_reads; /*!< number of pending read operations */ + ulint n_pend_reads; /*!< number of pending read + operations */ ulint n_pend_unzip; /*!< number of pending decompressions */ time_t last_printout_time; /*!< when buf_print_io was last time called */ + buf_buddy_stat_t buddy_stat[BUF_BUDDY_SIZES + 1]; + /*!< Statistics of buddy system, + indexed by block size */ buf_pool_stat_t stat; /*!< current statistics */ buf_pool_stat_t old_stat; /*!< old statistics */ @@ -1432,14 +1566,6 @@ struct buf_pool_struct{ the bpage is on flush_list. It also protects writes to bpage::oldest_modification */ - mutex_t flush_order_mutex;/*!< mutex to serialize access to - the flush list when we are putting - dirty blocks in the list. The idea - behind this mutex is to be able - to release log_sys->mutex during - mtr_commit and still ensure that - insertions in the flush_list happen - in the LSN order. */ UT_LIST_BASE_NODE_T(buf_page_t) flush_list; /*!< base node of the modified block list */ @@ -1519,6 +1645,12 @@ struct buf_pool_struct{ /*!< unmodified compressed pages */ UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES]; /*!< buddy free lists */ + + buf_page_t watch[BUF_POOL_WATCH_SIZE]; + /*!< Sentinel records for buffer + pool watches. Protected by + buf_pool->mutex. */ + #if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE # error "BUF_BUDDY_HIGH != UNIV_PAGE_SIZE" #endif @@ -1540,65 +1672,51 @@ Use these instead of accessing buf_pool_mutex directly. */ /* @{ */ /** Test if buf_pool_mutex is owned. */ -#define buf_pool_mutex_own() mutex_own(&buf_pool_mutex) +#define buf_pool_mutex_own(b) mutex_own(&b->mutex) /** Acquire the buffer pool mutex. */ -#define buf_pool_mutex_enter() do { \ - ut_ad(!mutex_own(&buf_pool_zip_mutex)); \ - mutex_enter(&buf_pool_mutex); \ +#define buf_pool_mutex_enter(b) do { \ + ut_ad(!mutex_own(&b->zip_mutex)); \ + mutex_enter(&b->mutex); \ } while (0) /** Test if flush list mutex is owned. */ -#define buf_flush_list_mutex_own() mutex_own(&buf_pool->flush_list_mutex) +#define buf_flush_list_mutex_own(b) mutex_own(&b->flush_list_mutex) /** Acquire the flush list mutex. */ -#define buf_flush_list_mutex_enter() do { \ - mutex_enter(&buf_pool->flush_list_mutex); \ +#define buf_flush_list_mutex_enter(b) do { \ + mutex_enter(&b->flush_list_mutex); \ } while (0) /** Release the flush list mutex. */ -# define buf_flush_list_mutex_exit() do { \ - mutex_exit(&buf_pool->flush_list_mutex); \ +# define buf_flush_list_mutex_exit(b) do { \ + mutex_exit(&b->flush_list_mutex); \ } while (0) -/** Test if flush order mutex is owned. */ -#define buf_flush_order_mutex_own() mutex_own(&buf_pool->flush_order_mutex) - -/** Acquire the flush order mutex. */ -#define buf_flush_order_mutex_enter() do { \ - mutex_enter(&buf_pool->flush_order_mutex); \ -} while (0) -/** Release the flush order mutex. */ -# define buf_flush_order_mutex_exit() do { \ - mutex_exit(&buf_pool->flush_order_mutex); \ -} while (0) #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG -/** Flag to forbid the release of the buffer pool mutex. -Protected by buf_pool_mutex. */ -extern ulint buf_pool_mutex_exit_forbidden; /** Forbid the release of the buffer pool mutex. */ -# define buf_pool_mutex_exit_forbid() do { \ - ut_ad(buf_pool_mutex_own()); \ - buf_pool_mutex_exit_forbidden++; \ +# define buf_pool_mutex_exit_forbid(b) do { \ + ut_ad(buf_pool_mutex_own(b)); \ + b->mutex_exit_forbidden++; \ } while (0) /** Allow the release of the buffer pool mutex. */ -# define buf_pool_mutex_exit_allow() do { \ - ut_ad(buf_pool_mutex_own()); \ - ut_a(buf_pool_mutex_exit_forbidden); \ - buf_pool_mutex_exit_forbidden--; \ +# define buf_pool_mutex_exit_allow(b) do { \ + ut_ad(buf_pool_mutex_own(b)); \ + ut_a(b->mutex_exit_forbidden); \ + b->mutex_exit_forbidden--; \ } while (0) /** Release the buffer pool mutex. */ -# define buf_pool_mutex_exit() do { \ - ut_a(!buf_pool_mutex_exit_forbidden); \ - mutex_exit(&buf_pool_mutex); \ +# define buf_pool_mutex_exit(b) do { \ + ut_a(!b->mutex_exit_forbidden); \ + mutex_exit(&b->mutex); \ } while (0) #else /** Forbid the release of the buffer pool mutex. */ -# define buf_pool_mutex_exit_forbid() ((void) 0) +# define buf_pool_mutex_exit_forbid(b) ((void) 0) /** Allow the release of the buffer pool mutex. */ -# define buf_pool_mutex_exit_allow() ((void) 0) +# define buf_pool_mutex_exit_allow(b) ((void) 0) /** Release the buffer pool mutex. */ -# define buf_pool_mutex_exit() mutex_exit(&buf_pool_mutex) +# define buf_pool_mutex_exit(b) mutex_exit(&b->mutex) #endif #endif /* !UNIV_HOTBACKUP */ /* @} */ |