diff options
Diffstat (limited to 'storage/xtradb/include/buf0buf.ic')
-rw-r--r-- | storage/xtradb/include/buf0buf.ic | 383 |
1 files changed, 267 insertions, 116 deletions
diff --git a/storage/xtradb/include/buf0buf.ic b/storage/xtradb/include/buf0buf.ic index 93cc68e7fc9..1a96b575d9b 100644 --- a/storage/xtradb/include/buf0buf.ic +++ b/storage/xtradb/include/buf0buf.ic @@ -31,11 +31,74 @@ Created 11/5/1995 Heikki Tuuri *******************************************************/ #include "mtr0mtr.h" -#ifndef UNIV_HOTBACKUP #include "buf0flu.h" #include "buf0lru.h" #include "buf0rea.h" #include "srv0srv.h" +/*********************************************************************//** +Gets the current size of buffer buf_pool in bytes. +@return size in bytes */ +UNIV_INLINE +ulint +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*/ +UNIV_INLINE +ulint +buf_pool_get_n_pages(void) +/*======================*/ +{ + return(buf_pool_get_curr_size() / UNIV_PAGE_SIZE); +} + /********************************************************************//** Reads the freed_page_clock of a buffer block. @return freed_page_clock */ @@ -45,7 +108,7 @@ buf_page_get_freed_page_clock( /*==========================*/ const buf_page_t* bpage) /*!< in: block */ { - /* This is sometimes read without holding buf_pool_mutex. */ + /* This is sometimes read without holding buf_pool->mutex. */ return(bpage->freed_page_clock); } @@ -72,6 +135,8 @@ buf_page_peek_if_too_old( /*=====================*/ const buf_page_t* bpage) /*!< in: block to make younger */ { + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) { /* If eviction has not started yet, do not update the statistics or move blocks in the LRU list. This is @@ -93,62 +158,12 @@ buf_page_peek_if_too_old( return((buf_pool->freed_page_clock & ((1UL << 31) - 1)) > ((ulint) bpage->freed_page_clock + (buf_pool->curr_size - * (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio) + * (BUF_LRU_OLD_RATIO_DIV - buf_pool->LRU_old_ratio) / (BUF_LRU_OLD_RATIO_DIV * 4)))); } } /*********************************************************************//** -Gets the current size of buffer buf_pool in bytes. -@return size in bytes */ -UNIV_INLINE -ulint -buf_pool_get_curr_size(void) -/*========================*/ -{ - return(buf_pool->curr_size * UNIV_PAGE_SIZE); -} - -/********************************************************************//** -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 -ib_uint64_t -buf_pool_get_oldest_modification(void) -/*==================================*/ -{ - buf_page_t* bpage; - ib_uint64_t lsn; - -try_again: - //buf_pool_mutex_enter(); - mutex_enter(&flush_list_mutex); - - bpage = UT_LIST_GET_LAST(buf_pool->flush_list); - - if (bpage == NULL) { - lsn = 0; - } else { - ut_ad(bpage->in_flush_list); - lsn = bpage->oldest_modification; - if (lsn == 0) { - mutex_exit(&flush_list_mutex); - goto try_again; - } - } - - //buf_pool_mutex_exit(); - mutex_exit(&flush_list_mutex); - - /* The returned answer may be out of date: the flush_list can - change after the mutex has been released. */ - - return(lsn); -} -#endif /* !UNIV_HOTBACKUP */ - -/*********************************************************************//** Gets the state of a block. @return state */ UNIV_INLINE @@ -300,13 +315,22 @@ buf_page_get_mutex( /*===============*/ const buf_page_t* bpage) /*!< in: pointer to control block */ { + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + + if (/*equivalent to buf_pool_watch_is_sentinel(buf_pool, bpage)*/ + bpage >= &buf_pool->watch[0] + && bpage < &buf_pool->watch[BUF_POOL_WATCH_SIZE]) { + /* TODO: this code is the interim. should be confirmed later. */ + return(&buf_pool->zip_mutex); + } + switch (buf_page_get_state(bpage)) { case BUF_BLOCK_ZIP_FREE: /* ut_error; */ /* optimistic */ return(NULL); case BUF_BLOCK_ZIP_PAGE: case BUF_BLOCK_ZIP_DIRTY: - return(&buf_pool_zip_mutex); + return(&buf_pool->zip_mutex); default: return(&((buf_block_t*) bpage)->mutex); } @@ -384,6 +408,7 @@ buf_block_set_file_page( buf_block_set_state(block, BUF_BLOCK_FILE_PAGE); block->page.space = space; block->page.offset = page_no; + block->page.space_was_being_deleted = FALSE; } /*********************************************************************//** @@ -414,7 +439,7 @@ Gets the io_fix state of a block. UNIV_INLINE enum buf_io_fix buf_block_get_io_fix( -/*================*/ +/*=================*/ const buf_block_t* block) /*!< in: pointer to the control block */ { return(buf_page_get_io_fix(&block->page)); @@ -429,7 +454,10 @@ buf_page_set_io_fix( buf_page_t* bpage, /*!< in/out: control block */ enum buf_io_fix io_fix) /*!< in: io_fix state */ { - //ut_ad(buf_pool_mutex_own()); +#ifdef UNIV_DEBUG + //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + //ut_ad(buf_pool_mutex_own(buf_pool)); +#endif ut_ad(mutex_own(buf_page_get_mutex(bpage))); bpage->io_fix = io_fix; @@ -457,10 +485,12 @@ buf_page_can_relocate( /*==================*/ const buf_page_t* bpage) /*!< control block being relocated */ { - //ut_ad(buf_pool_mutex_own()); +#ifdef UNIV_DEBUG + //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + //ut_ad(buf_pool_mutex_own(buf_pool)); +#endif ut_ad(mutex_own(buf_page_get_mutex(bpage))); ut_ad(buf_page_in_file(bpage)); - /* optimistic */ //ut_ad(bpage->in_LRU_list); return(bpage->in_LRU_list && bpage->io_fix == BUF_IO_NONE @@ -476,8 +506,11 @@ buf_page_is_old( /*============*/ const buf_page_t* bpage) /*!< in: control block */ { +#ifdef UNIV_DEBUG + //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + //ut_ad(buf_pool_mutex_own(buf_pool)); +#endif ut_ad(buf_page_in_file(bpage)); - //ut_ad(buf_pool_mutex_own()); /* This is used in optimistic */ return(bpage->old); } @@ -491,9 +524,12 @@ buf_page_set_old( buf_page_t* bpage, /*!< in/out: control block */ ibool old) /*!< in: old */ { +#ifdef UNIV_DEBUG + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); +#endif /* UNIV_DEBUG */ ut_a(buf_page_in_file(bpage)); - //ut_ad(buf_pool_mutex_own()); - ut_ad(mutex_own(&LRU_list_mutex)); + //ut_ad(buf_pool_mutex_own(buf_pool)); + ut_ad(mutex_own(&buf_pool->LRU_list_mutex)); ut_ad(bpage->in_LRU_list); #ifdef UNIV_LRU_DEBUG @@ -539,9 +575,12 @@ buf_page_set_accessed( buf_page_t* bpage, /*!< in/out: control block */ ulint time_ms) /*!< in: ut_time_ms() */ { - ut_a(buf_page_in_file(bpage)); - //ut_ad(buf_pool_mutex_own()); +#ifdef UNIV_DEBUG + //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + //ut_ad(buf_pool_mutex_own(buf_pool)); +#endif ut_ad(mutex_own(buf_page_get_mutex(bpage))); + ut_a(buf_page_in_file(bpage)); if (!bpage->access_time) { /* Make this the time of the first access. */ @@ -753,25 +792,6 @@ buf_block_get_lock_hash_val( } /********************************************************************//** -Allocates a buffer block. -@return own: the allocated block, in state BUF_BLOCK_MEMORY */ -UNIV_INLINE -buf_block_t* -buf_block_alloc( -/*============*/ - ulint zip_size) /*!< in: compressed page size in bytes, - or 0 if uncompressed tablespace */ -{ - buf_block_t* block; - - block = buf_LRU_get_free_block(zip_size); - - buf_block_set_state(block, BUF_BLOCK_MEMORY); - - return(block); -} - -/********************************************************************//** Frees a buffer block which does not contain a file page. */ UNIV_INLINE void @@ -779,7 +799,9 @@ buf_block_free( /*===========*/ buf_block_t* block) /*!< in, own: block to be freed */ { - //buf_pool_mutex_enter(); + //buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block); + + //buf_pool_mutex_enter(buf_pool); mutex_enter(&block->mutex); @@ -789,7 +811,7 @@ buf_block_free( mutex_exit(&block->mutex); - //buf_pool_mutex_exit(); + //buf_pool_mutex_exit(buf_pool); } #endif /* !UNIV_HOTBACKUP */ @@ -863,7 +885,9 @@ buf_block_modify_clock_inc( buf_block_t* block) /*!< in: block */ { #ifdef UNIV_SYNC_DEBUG - ut_ad((mutex_own(&LRU_list_mutex) + buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block); + + ut_ad((mutex_own(&buf_pool->LRU_list_mutex) && (block->page.buf_fix_count == 0)) || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE)); #endif /* UNIV_SYNC_DEBUG */ @@ -942,29 +966,66 @@ buf_block_buf_fix_dec( } /******************************************************************//** +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 */ +{ + ulint fold; + ulint index; + ulint ignored_offset; + + 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]); +} + +/******************************************************************//** +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 */ +{ + ut_ad(index < MAX_BUFFER_POOLS); + ut_ad(index < srv_buf_pool_instances); + return(&buf_pool_ptr[index]); +} + +/******************************************************************//** 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( -/*==============*/ - ulint space, /*!< in: space id */ - ulint offset) /*!< in: offset of the page within space */ +buf_page_hash_get_low( +/*==================*/ + 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) */ { buf_page_t* bpage; - ulint fold; ut_ad(buf_pool); - //ut_ad(buf_pool_mutex_own()); + //ut_ad(buf_pool_mutex_own(buf_pool)); #ifdef UNIV_SYNC_DEBUG - ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX) - || rw_lock_own(&page_hash_latch, RW_LOCK_SHARED)); + ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX) + || rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_SHARED)); #endif + ut_ad(fold == buf_page_address_fold(space, offset)); /* Look for the page in the hash table */ - fold = buf_page_address_fold(space, offset); - HASH_SEARCH(hash, buf_pool->page_hash, fold, buf_page_t*, bpage, ut_ad(bpage->in_page_hash && !bpage->in_zip_hash && buf_page_in_file(bpage)), @@ -985,6 +1046,30 @@ buf_page_hash_get( } /******************************************************************//** +Returns the control block of a file page, NULL if not found. +@return block, NULL if not found or not a real control block */ +UNIV_INLINE +buf_page_t* +buf_page_hash_get( +/*==============*/ + buf_pool_t* buf_pool, /*!< in: buffer pool instance */ + ulint space, /*!< in: space id */ + ulint offset) /*!< in: offset of the page + within space */ +{ + buf_page_t* bpage; + ulint fold = buf_page_address_fold(space, offset); + + bpage = buf_page_hash_get_low(buf_pool, space, offset, fold); + + if (bpage && buf_pool_watch_is_sentinel(buf_pool, bpage)) { + bpage = NULL; + } + + return(bpage); +} + +/******************************************************************//** Returns the control block of a file page, NULL if not found or an uncompressed page frame does not exist. @return block, NULL if not found */ @@ -992,10 +1077,16 @@ 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 */ { - return(buf_page_get_block(buf_page_hash_get(space, offset))); + buf_block_t* block; + + block = buf_page_get_block(buf_page_hash_get(buf_pool, space, offset)); + + return(block); } /********************************************************************//** @@ -1013,14 +1104,15 @@ buf_page_peek( ulint offset) /*!< in: page number */ { const buf_page_t* bpage; + buf_pool_t* buf_pool = buf_pool_get(space, offset); - //buf_pool_mutex_enter(); - rw_lock_s_lock(&page_hash_latch); + //buf_pool_mutex_enter(buf_pool); + rw_lock_s_lock(&buf_pool->page_hash_latch); - bpage = buf_page_hash_get(space, offset); + bpage = buf_page_hash_get(buf_pool, space, offset); - //buf_pool_mutex_exit(); - rw_lock_s_unlock(&page_hash_latch); + //buf_pool_mutex_exit(buf_pool); + rw_lock_s_unlock(&buf_pool->page_hash_latch); return(bpage != NULL); } @@ -1034,6 +1126,7 @@ buf_page_release_zip( buf_page_t* bpage) /*!< in: buffer block */ { buf_block_t* block; + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); ut_ad(bpage); ut_a(bpage->buf_fix_count > 0); @@ -1041,9 +1134,9 @@ buf_page_release_zip( switch (buf_page_get_state(bpage)) { case BUF_BLOCK_ZIP_PAGE: case BUF_BLOCK_ZIP_DIRTY: - mutex_enter(&buf_pool_zip_mutex); + mutex_enter(&buf_pool->zip_mutex); bpage->buf_fix_count--; - mutex_exit(&buf_pool_zip_mutex); + mutex_exit(&buf_pool->zip_mutex); return; case BUF_BLOCK_FILE_PAGE: block = (buf_block_t*) bpage; @@ -1062,6 +1155,7 @@ buf_page_release_zip( break; } + ut_error; } @@ -1073,24 +1167,14 @@ void buf_page_release( /*=============*/ buf_block_t* block, /*!< in: buffer block */ - ulint rw_latch, /*!< in: RW_S_LATCH, RW_X_LATCH, + ulint rw_latch) /*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */ - mtr_t* mtr __attribute__((unused))) /*!< in: mtr */ { ut_ad(block); ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(block->page.buf_fix_count > 0); - /* buf_flush_note_modification() should be called before this function. */ -/* - if (rw_latch == RW_X_LATCH && mtr->modifications) { - buf_pool_mutex_enter(); - buf_flush_note_modification(block, mtr); - buf_pool_mutex_exit(); - } -*/ - mutex_enter(&block->mutex); #ifdef UNIV_SYNC_DEBUG @@ -1123,4 +1207,71 @@ buf_block_dbg_add_level( sync_thread_add_level(&block->lock, level); } #endif /* UNIV_SYNC_DEBUG */ +/********************************************************************//** +Acquire mutex on all buffer pool instances. */ +UNIV_INLINE +void +buf_pool_mutex_enter_all(void) +/*==========================*/ +{ + ulint i; + + for (i = 0; i < srv_buf_pool_instances; i++) { + buf_pool_t* buf_pool; + + buf_pool = buf_pool_from_array(i); + buf_pool_mutex_enter(buf_pool); + } +} + +/********************************************************************//** +Release mutex on all buffer pool instances. */ +UNIV_INLINE +void +buf_pool_mutex_exit_all(void) +/*=========================*/ +{ + ulint i; + + for (i = 0; i < srv_buf_pool_instances; i++) { + buf_pool_t* buf_pool; + + buf_pool = buf_pool_from_array(i); + buf_pool_mutex_exit(buf_pool); + } +} + +/********************************************************************//** +*/ +UNIV_INLINE +void +buf_pool_page_hash_x_lock_all(void) +/*===============================*/ +{ + ulint i; + + for (i = 0; i < srv_buf_pool_instances; i++) { + buf_pool_t* buf_pool; + + buf_pool = buf_pool_from_array(i); + rw_lock_x_lock(&buf_pool->page_hash_latch); + } +} + +/********************************************************************//** +*/ +UNIV_INLINE +void +buf_pool_page_hash_x_unlock_all(void) +/*=================================*/ +{ + ulint i; + + for (i = 0; i < srv_buf_pool_instances; i++) { + buf_pool_t* buf_pool; + + buf_pool = buf_pool_from_array(i); + rw_lock_x_unlock(&buf_pool->page_hash_latch); + } +} #endif /* !UNIV_HOTBACKUP */ |