diff options
Diffstat (limited to 'storage/innobase/buf/buf0buf.cc')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 112 |
1 files changed, 82 insertions, 30 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 5858d9cd2d3..cfc79868482 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -5564,14 +5564,13 @@ buf_page_create( buf_frame_t* frame; buf_block_t* block; buf_block_t* free_block = NULL; - buf_pool_t* buf_pool = buf_pool_get(page_id); + buf_pool_t* buf_pool= buf_pool_get(page_id); rw_lock_t* hash_lock; ut_ad(mtr->is_active()); ut_ad(page_id.space() != 0 || !page_size.is_compressed()); - +loop: free_block = buf_LRU_get_free_block(buf_pool); - buf_pool_mutex_enter(buf_pool); hash_lock = buf_page_hash_lock_get(buf_pool, page_id); @@ -5583,20 +5582,67 @@ buf_page_create( && buf_page_in_file(&block->page) && !buf_pool_watch_is_sentinel(buf_pool, &block->page)) { ut_d(block->page.file_page_was_freed = FALSE); - + buf_page_state page_state = buf_block_get_state(block); #ifdef BTR_CUR_HASH_ADAPT - bool drop_hash_entry = - (block->page.state == BUF_BLOCK_FILE_PAGE - && block->index); + const dict_index_t *drop_hash_entry= NULL; +#endif + switch (page_state) { + default: + ut_ad(0); + break; + case BUF_BLOCK_ZIP_PAGE: + case BUF_BLOCK_ZIP_DIRTY: + buf_block_init_low(free_block); + mutex_enter(&buf_pool->zip_mutex); - if (drop_hash_entry) { - mutex_enter(&block->mutex); - /* Avoid a hang if I/O is going on. Release - the buffer pool mutex and page hash lock - and wait for I/O to complete */ - while (buf_block_get_io_fix(block) != BUF_IO_NONE) { - buf_block_fix(block); - mutex_exit(&block->mutex); + buf_page_mutex_enter(free_block); + if (buf_page_get_io_fix(&block->page) != BUF_IO_NONE) { + mutex_exit(&buf_pool->zip_mutex); + rw_lock_x_unlock(hash_lock); + buf_LRU_block_free_non_file_page(free_block); + buf_pool_mutex_exit(buf_pool); + buf_page_mutex_exit(free_block); + + goto loop; + } + + rw_lock_x_lock(&free_block->lock); + + buf_relocate(&block->page, &free_block->page); + if (page_state == BUF_BLOCK_ZIP_DIRTY) { + ut_ad(block->page.in_flush_list); + ut_ad(block->page.oldest_modification > 0); + buf_flush_relocate_on_flush_list( + &block->page, &free_block->page); + } else { + ut_ad(block->page.oldest_modification == 0); + ut_ad(!block->page.in_flush_list); +#ifdef UNIV_DEBUG + UT_LIST_REMOVE( + buf_pool->zip_clean, &block->page); +#endif + } + + free_block->page.state = BUF_BLOCK_FILE_PAGE; + mutex_exit(&buf_pool->zip_mutex); + free_block->lock_hash_val = lock_rec_hash( + page_id.space(), page_id.page_no()); + buf_unzip_LRU_add_block(free_block, false); + buf_page_free_descriptor(&block->page); + block = free_block; + buf_block_fix(block); + buf_page_mutex_exit(free_block); + free_block = NULL; + break; + case BUF_BLOCK_FILE_PAGE: + buf_block_fix(block); + const int32_t num_fix_count = + mtr->get_fix_count(block) + 1; + buf_page_mutex_enter(block); + while (buf_block_get_io_fix(block) != BUF_IO_NONE + || (num_fix_count + != block->page.buf_fix_count)) { + buf_page_mutex_exit(block); buf_pool_mutex_exit(buf_pool); rw_lock_x_unlock(hash_lock); @@ -5604,33 +5650,39 @@ buf_page_create( buf_pool_mutex_enter(buf_pool); rw_lock_x_lock(hash_lock); - mutex_enter(&block->mutex); - buf_block_unfix(block); + buf_page_mutex_enter(block); } + rw_lock_x_lock(&block->lock); - mutex_exit(&block->mutex); - } + buf_page_mutex_exit(block); +#ifdef BTR_CUR_HASH_ADAPT + drop_hash_entry = block->index; #endif + break; + } /* Page can be found in buf_pool */ buf_pool_mutex_exit(buf_pool); rw_lock_x_unlock(hash_lock); - buf_block_free(free_block); + if (free_block) { + buf_block_free(free_block); + } #ifdef BTR_CUR_HASH_ADAPT if (drop_hash_entry) { btr_search_drop_page_hash_index(block); - rw_lock_x_unlock(&block->lock); } #endif /* BTR_CUR_HASH_ADAPT */ - if (!recv_recovery_is_on()) { - return buf_page_get_with_no_latch(page_id, page_size, - mtr); +#ifdef UNIV_DEBUG + if (!fsp_is_system_temporary(page_id.space())) { + rw_lock_s_lock_nowait( + &block->debug_latch, + __FILE__, __LINE__); } +#endif /* UNIV_DEBUG */ + + mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX); - mutex_exit(&recv_sys->mutex); - block = buf_page_get_with_no_latch(page_id, page_size, mtr); - mutex_enter(&recv_sys->mutex); return block; } @@ -5645,6 +5697,8 @@ buf_page_create( buf_page_init(buf_pool, page_id, page_size, block); + rw_lock_x_lock(&block->lock); + rw_lock_x_unlock(hash_lock); /* The block must be put to the LRU list */ @@ -5662,7 +5716,6 @@ buf_page_create( by IO-fixing and X-latching the block. */ buf_page_set_io_fix(&block->page, BUF_IO_READ); - rw_lock_x_lock(&block->lock); buf_page_mutex_exit(block); /* buf_pool->mutex may be released and reacquired by @@ -5684,12 +5737,11 @@ buf_page_create( buf_unzip_LRU_add_block(block, FALSE); buf_page_set_io_fix(&block->page, BUF_IO_NONE); - rw_lock_x_unlock(&block->lock); } buf_pool_mutex_exit(buf_pool); - mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX); + mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX); buf_page_set_accessed(&block->page); |