diff options
-rw-r--r-- | storage/innodb_plugin/buf/buf0buf.c | 80 | ||||
-rw-r--r-- | storage/innodb_plugin/include/buf0buf.h | 10 | ||||
-rw-r--r-- | storage/innodb_plugin/include/buf0buf.ic | 8 |
3 files changed, 37 insertions, 61 deletions
diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index b49f5288681..755fa947c8f 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -1108,32 +1108,21 @@ buf_page_make_young( } /********************************************************************//** -Sets the time of the first access of a page and moves a page to the -start of the buffer pool LRU list if it is too old. This high-level -function can be used to prevent an important page from slipping -out of the buffer pool. */ +Moves a page to the start of the buffer pool LRU list if it is too old. +This high-level function can be used to prevent an important page from +slipping out of the buffer pool. */ static void -buf_page_set_accessed_make_young( -/*=============================*/ - buf_page_t* bpage, /*!< in/out: buffer block of a +buf_page_make_young_if_needed( +/*==========================*/ + buf_page_t* bpage) /*!< in/out: buffer block of a file page */ - unsigned access_time) /*!< in: bpage->access_time - read under mutex protection, - or 0 if unknown */ { ut_ad(!buf_pool_mutex_own()); ut_a(buf_page_in_file(bpage)); if (buf_page_peek_if_too_old(bpage)) { - buf_pool_mutex_enter(); - buf_LRU_make_block_young(bpage); - buf_pool_mutex_exit(); - } else if (!access_time) { - ulint time_ms = ut_time_ms(); - buf_pool_mutex_enter(); - buf_page_set_accessed(bpage, time_ms); - buf_pool_mutex_exit(); + buf_page_make_young(bpage); } } @@ -1217,7 +1206,6 @@ buf_page_get_zip( buf_page_t* bpage; mutex_t* block_mutex; ibool must_read; - unsigned access_time; #ifndef UNIV_LOG_DEBUG ut_ad(!ibuf_inside()); @@ -1284,13 +1272,14 @@ err_exit: got_block: must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ; - access_time = buf_page_is_accessed(bpage); buf_pool_mutex_exit(); + buf_page_set_accessed(bpage); + mutex_exit(block_mutex); - buf_page_set_accessed_make_young(bpage, access_time); + buf_page_make_young_if_needed(bpage); #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG ut_a(!bpage->file_page_was_freed); @@ -1861,16 +1850,16 @@ wait_until_unfixed: buf_block_buf_fix_inc(block, file, line); - mutex_exit(&block->mutex); - - /* Check if this is the first access to the page */ + buf_pool_mutex_exit(); access_time = buf_page_is_accessed(&block->page); - buf_pool_mutex_exit(); + buf_page_set_accessed(&block->page); + + mutex_exit(&block->mutex); if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) { - buf_page_set_accessed_make_young(&block->page, access_time); + buf_page_make_young_if_needed(&block->page); } #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG @@ -1925,7 +1914,7 @@ wait_until_unfixed: mtr_memo_push(mtr, block, fix_type); - if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL) && !access_time) { + if (mode != BUF_PEEK_IF_IN_POOL && !access_time) { /* In the case of a first access, try to apply linear read-ahead */ @@ -1975,15 +1964,13 @@ buf_page_optimistic_get( buf_block_buf_fix_inc(block, file, line); - mutex_exit(&block->mutex); + access_time = buf_page_is_accessed(&block->page); - /* Check if this is the first access to the page. - We do a dirty read on purpose, to avoid mutex contention. - This field is only used for heuristic purposes; it does not - affect correctness. */ + buf_page_set_accessed(&block->page); - access_time = buf_page_is_accessed(&block->page); - buf_page_set_accessed_make_young(&block->page, access_time); + mutex_exit(&block->mutex); + + buf_page_make_young_if_needed(&block->page); ut_ad(!ibuf_inside() || ibuf_page(buf_block_get_space(block), @@ -2035,7 +2022,7 @@ buf_page_optimistic_get( #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG ut_a(block->page.file_page_was_freed == FALSE); #endif - if (UNIV_UNLIKELY(!access_time)) { + if (!access_time) { /* In the case of a first access, try to apply linear read-ahead */ @@ -2095,22 +2082,12 @@ buf_page_get_known_nowait( buf_block_buf_fix_inc(block, file, line); - mutex_exit(&block->mutex); + buf_page_set_accessed(&block->page); - if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) { - buf_pool_mutex_enter(); - buf_LRU_make_block_young(&block->page); - buf_pool_mutex_exit(); - } else if (!buf_page_is_accessed(&block->page)) { - /* Above, we do a dirty read on purpose, to avoid - mutex contention. The field buf_page_t::access_time - is only used for heuristic purposes. Writes to the - field must be protected by mutex, however. */ - ulint time_ms = ut_time_ms(); + mutex_exit(&block->mutex); - buf_pool_mutex_enter(); - buf_page_set_accessed(&block->page, time_ms); - buf_pool_mutex_exit(); + if (mode == BUF_MAKE_YOUNG) { + buf_page_make_young_if_needed(&block->page); } ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD)); @@ -2542,7 +2519,6 @@ buf_page_create( buf_frame_t* frame; buf_block_t* block; buf_block_t* free_block = NULL; - ulint time_ms = ut_time_ms(); ut_ad(mtr); ut_ad(mtr->state == MTR_ACTIVE); @@ -2627,12 +2603,12 @@ buf_page_create( rw_lock_x_unlock(&block->lock); } - buf_page_set_accessed(&block->page, time_ms); - buf_pool_mutex_exit(); mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX); + buf_page_set_accessed(&block->page); + mutex_exit(&block->mutex); /* Delete possible entries for the page from the insert buffer: diff --git a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h index fd286f6c26c..b3fcff14f0d 100644 --- a/storage/innodb_plugin/include/buf0buf.h +++ b/storage/innodb_plugin/include/buf0buf.h @@ -927,8 +927,7 @@ UNIV_INLINE void buf_page_set_accessed( /*==================*/ - buf_page_t* bpage, /*!< in/out: control block */ - ulint time_ms) /*!< in: ut_time_ms() */ + buf_page_t* bpage) /*!< in/out: control block */ __attribute__((nonnull)); /*********************************************************************//** Gets the buf_block_t handle of a buffered file block if an uncompressed @@ -1260,10 +1259,11 @@ struct buf_page_struct{ to read this for heuristic purposes without holding any mutex or latch */ - unsigned access_time:32; /*!< time of first access, or - 0 if the block was never accessed - in the buffer pool */ /* @} */ + unsigned access_time; /*!< time of first access, or + 0 if the block was never accessed + in the buffer pool. Protected by + block mutex */ # if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG ibool file_page_was_freed; /*!< this is set to TRUE when fsp diff --git a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic index 39135a2ece1..098ec379761 100644 --- a/storage/innodb_plugin/include/buf0buf.ic +++ b/storage/innodb_plugin/include/buf0buf.ic @@ -531,15 +531,15 @@ UNIV_INLINE void buf_page_set_accessed( /*==================*/ - buf_page_t* bpage, /*!< in/out: control block */ - ulint time_ms) /*!< in: ut_time_ms() */ + buf_page_t* bpage) /*!< in/out: control block */ { ut_a(buf_page_in_file(bpage)); - ut_ad(buf_pool_mutex_own()); + ut_ad(!buf_pool_mutex_own()); + ut_ad(mutex_own(buf_page_get_mutex(bpage))); if (!bpage->access_time) { /* Make this the time of the first access. */ - bpage->access_time = time_ms; + bpage->access_time = ut_time_ms(); } } |