diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 1af019dfc45..9146106d0b9 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -1657,34 +1657,24 @@ 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 */ { +#ifdef UNIV_DEBUG buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); - ut_ad(!buf_pool_mutex_own(buf_pool)); +#endif /* UNIV_DEBUG */ ut_a(buf_page_in_file(bpage)); if (buf_page_peek_if_too_old(bpage)) { - buf_pool_mutex_enter(buf_pool); - buf_LRU_make_block_young(bpage); - buf_pool_mutex_exit(buf_pool); - } else if (!access_time) { - ulint time_ms = ut_time_ms(); - buf_pool_mutex_enter(buf_pool); - buf_page_set_accessed(bpage, time_ms); - buf_pool_mutex_exit(buf_pool); + buf_page_make_young(bpage); } } @@ -1797,7 +1787,6 @@ buf_page_get_zip( buf_page_t* bpage; mutex_t* block_mutex; ibool must_read; - unsigned access_time; buf_pool_t* buf_pool = buf_pool_get(space, offset); buf_pool->stat.n_page_gets++; @@ -1865,13 +1854,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_pool); + 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); @@ -2550,16 +2540,17 @@ wait_until_unfixed: ut_a(mode == BUF_GET_POSSIBLY_FREED || !block->page.file_page_was_freed); #endif - mutex_exit(&block->mutex); - - /* Check if this is the first access to the page */ - - access_time = buf_page_is_accessed(&block->page); - buf_pool_mutex_exit(buf_pool); - if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) { - buf_page_set_accessed_make_young(&block->page, access_time); + /* Check if this is the first access to the page */ + access_time = buf_page_is_accessed(&block->page); + + buf_page_set_accessed(&block->page); + + mutex_exit(&block->mutex); + + if (mode != BUF_PEEK_IF_IN_POOL) { + buf_page_make_young_if_needed(&block->page); } #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG @@ -2610,7 +2601,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 */ @@ -2662,15 +2653,13 @@ buf_page_optimistic_get( buf_block_buf_fix_inc(block, file, line); + access_time = buf_page_is_accessed(&block->page); + + buf_page_set_accessed(&block->page); + mutex_exit(&block->mutex); - /* 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. */ - - access_time = buf_page_is_accessed(&block->page); - buf_page_set_accessed_make_young(&block->page, access_time); + buf_page_make_young_if_needed(&block->page); ut_ad(!ibuf_inside(mtr) || ibuf_page(buf_block_get_space(block), @@ -2722,7 +2711,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 */ @@ -2785,24 +2774,14 @@ buf_page_get_known_nowait( buf_block_buf_fix_inc(block, file, line); + buf_page_set_accessed(&block->page); + mutex_exit(&block->mutex); buf_pool = buf_pool_from_block(block); - if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) { - buf_pool_mutex_enter(buf_pool); - buf_LRU_make_block_young(&block->page); - buf_pool_mutex_exit(buf_pool); - } 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(); - - buf_pool_mutex_enter(buf_pool); - buf_page_set_accessed(&block->page, time_ms); - buf_pool_mutex_exit(buf_pool); + if (mode == BUF_MAKE_YOUNG) { + buf_page_make_young_if_needed(&block->page); } ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD); @@ -3284,7 +3263,6 @@ buf_page_create( buf_block_t* block; ulint fold; buf_block_t* free_block = NULL; - ulint time_ms = ut_time_ms(); buf_pool_t* buf_pool = buf_pool_get(space, offset); ut_ad(mtr); @@ -3375,12 +3353,12 @@ buf_page_create( rw_lock_x_unlock(&block->lock); } - buf_page_set_accessed(&block->page, time_ms); - buf_pool_mutex_exit(buf_pool); 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/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index fd8620eab3b..9c8051ad867 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1024,8 +1024,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 @@ -1504,10 +1503,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/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 84c0ab9d610..bcbe454b037 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -614,18 +614,18 @@ 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 */ { #ifdef UNIV_DEBUG buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); - ut_ad(buf_pool_mutex_own(buf_pool)); + ut_ad(!buf_pool_mutex_own(buf_pool)); + ut_ad(mutex_own(buf_page_get_mutex(bpage))); #endif ut_a(buf_page_in_file(bpage)); if (!bpage->access_time) { /* Make this the time of the first access. */ - bpage->access_time = time_ms; + bpage->access_time = ut_time_ms(); } }