diff options
Diffstat (limited to 'storage/xtradb/buf/buf0buf.c')
-rw-r--r-- | storage/xtradb/buf/buf0buf.c | 148 |
1 files changed, 95 insertions, 53 deletions
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c index 91c5fbcbba9..f06fd4abfb1 100644 --- a/storage/xtradb/buf/buf0buf.c +++ b/storage/xtradb/buf/buf0buf.c @@ -989,7 +989,6 @@ buf_block_init( block->check_index_page_at_flush = FALSE; block->index = NULL; - block->btr_search_latch = NULL; #ifdef UNIV_DEBUG block->page.in_page_hash = FALSE; @@ -1468,7 +1467,7 @@ buf_pool_clear_hash_index(void) ulint j; for (j = 0; j < btr_search_index_num; j++) { - ut_ad(rw_lock_own(btr_search_latch_part[j], RW_LOCK_EX)); + ut_ad(rw_lock_own(&btr_search_latch_arr[j], RW_LOCK_EX)); } #endif /* UNIV_SYNC_DEBUG */ ut_ad(!btr_search_enabled); @@ -1823,6 +1822,7 @@ buf_page_make_young( buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); //buf_pool_mutex_enter(buf_pool); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); ut_a(buf_page_in_file(bpage)); @@ -1976,6 +1976,7 @@ buf_page_get_zip( ib_uint64_t start_time; ib_uint64_t finish_time; buf_pool_t* buf_pool = buf_pool_get(space, offset); + ibool have_LRU_mutex = FALSE; if (UNIV_UNLIKELY(innobase_get_slow_log())) { trx = innobase_get_trx(); @@ -2040,13 +2041,18 @@ err_exit: bpage->buf_fix_count++; goto got_block; case BUF_BLOCK_FILE_PAGE: + { ut_a(block_mutex == &((buf_block_t*) bpage)->mutex); /* release mutex to obey to latch-order */ mutex_exit(block_mutex); /* get LRU_list_mutex for buf_LRU_free_block() */ - mutex_enter(&buf_pool->LRU_list_mutex); + if (!have_LRU_mutex) { + mutex_enter(&buf_pool->LRU_list_mutex); + have_LRU_mutex = TRUE; + } + mutex_enter(block_mutex); if (UNIV_UNLIKELY(bpage->space != space @@ -2054,23 +2060,33 @@ err_exit: || !bpage->in_LRU_list || !bpage->zip.data)) { /* someone should interrupt, retry */ - mutex_exit(&buf_pool->LRU_list_mutex); + if (have_LRU_mutex) { + mutex_exit(&buf_pool->LRU_list_mutex); + have_LRU_mutex = FALSE; + } mutex_exit(block_mutex); goto lookup; } /* Discard the uncompressed page frame if possible. */ - if (buf_LRU_free_block(bpage, FALSE, TRUE)) { - mutex_exit(&buf_pool->LRU_list_mutex); + if (buf_LRU_free_block(bpage, FALSE, &have_LRU_mutex)) { + if (have_LRU_mutex) { + mutex_exit(&buf_pool->LRU_list_mutex); + have_LRU_mutex = FALSE; + } mutex_exit(block_mutex); goto lookup; } - mutex_exit(&buf_pool->LRU_list_mutex); + if (have_LRU_mutex) { + mutex_exit(&buf_pool->LRU_list_mutex); + have_LRU_mutex = FALSE; + } buf_block_buf_fix_inc((buf_block_t*) bpage, __FILE__, __LINE__); goto got_block; + } } ut_error; @@ -2147,7 +2163,6 @@ buf_block_init_low( { block->check_index_page_at_flush = FALSE; block->index = NULL; - block->btr_search_latch = NULL; block->n_hash_helps = 0; block->n_fields = 1; @@ -2449,6 +2464,7 @@ buf_page_get_gen( ib_uint64_t start_time; ib_uint64_t finish_time; buf_pool_t* buf_pool = buf_pool_get(space, offset); + ibool have_LRU_mutex = FALSE; ut_ad(mtr); ut_ad(mtr->state == MTR_ACTIVE); @@ -2551,6 +2567,13 @@ loop2: return(NULL); } + /* We should not hold LRU mutex below when trying + to read the page */ + if (have_LRU_mutex) { + mutex_exit(&buf_pool->LRU_list_mutex); + have_LRU_mutex = FALSE; + } + if (buf_read_page(space, zip_size, offset, trx)) { buf_read_ahead_random(space, zip_size, offset, ibuf_inside(mtr), trx); @@ -2656,6 +2679,11 @@ wait_until_unfixed: goto loop; } + /* Buffer-fix the block so that it cannot be evicted + or relocated while we are attempting to allocate an + uncompressed page. */ + bpage->buf_fix_count++; + /* Allocate an uncompressed page. */ //buf_pool_mutex_exit(buf_pool); //mutex_exit(&buf_pool->zip_mutex); @@ -2666,52 +2694,39 @@ wait_until_unfixed: block_mutex = &block->mutex; //buf_pool_mutex_enter(buf_pool); - mutex_enter(&buf_pool->LRU_list_mutex); - rw_lock_x_lock(&buf_pool->page_hash_latch); - mutex_enter(block_mutex); - - { - buf_page_t* hash_bpage; - - hash_bpage = buf_page_hash_get_low( - buf_pool, space, offset, fold); - - if (UNIV_UNLIKELY(bpage != hash_bpage)) { - /* The buf_pool->page_hash was modified - while buf_pool->mutex was released. - Free the block that was allocated. */ - - buf_LRU_block_free_non_file_page(block, TRUE); - mutex_exit(block_mutex); - - block = (buf_block_t*) hash_bpage; - if (block) { - block_mutex = buf_page_get_mutex_enter((buf_page_t*)block); - ut_a(block_mutex); - } - rw_lock_x_unlock(&buf_pool->page_hash_latch); - mutex_exit(&buf_pool->LRU_list_mutex); - goto loop2; - } + if (!have_LRU_mutex) { + mutex_enter(&buf_pool->LRU_list_mutex); + have_LRU_mutex = TRUE; } + rw_lock_x_lock(&buf_pool->page_hash_latch); + mutex_enter(&block->mutex); mutex_enter(&buf_pool->zip_mutex); + /* Buffer-fixing prevents the page_hash from changing. */ + ut_ad(bpage == buf_page_hash_get_low(buf_pool, + space, offset, fold)); if (UNIV_UNLIKELY - (bpage->buf_fix_count + (--bpage->buf_fix_count || buf_page_get_io_fix(bpage) != BUF_IO_NONE)) { mutex_exit(&buf_pool->zip_mutex); - /* The block was buffer-fixed or I/O-fixed - while buf_pool->mutex was not held by this thread. - Free the block that was allocated and try again. - This should be extremely unlikely. */ + /* The block was buffer-fixed or I/O-fixed while + buf_pool->mutex was not held by this thread. + Free the block that was allocated and retry. + This should be extremely unlikely, for example, + if buf_page_get_zip() was invoked. */ buf_LRU_block_free_non_file_page(block, TRUE); //mutex_exit(&block->mutex); rw_lock_x_unlock(&buf_pool->page_hash_latch); - mutex_exit(&buf_pool->LRU_list_mutex); + + if (have_LRU_mutex) { + mutex_exit(&buf_pool->LRU_list_mutex); + have_LRU_mutex = FALSE; + } + goto wait_until_unfixed; } @@ -2749,7 +2764,10 @@ wait_until_unfixed: /* Insert at the front of unzip_LRU list */ buf_unzip_LRU_add_block(block, FALSE); - mutex_exit(&buf_pool->LRU_list_mutex); + if (have_LRU_mutex) { + mutex_exit(&buf_pool->LRU_list_mutex); + have_LRU_mutex = FALSE; + } block->page.buf_fix_count = 1; buf_block_set_io_fix(block, BUF_IO_READ); @@ -2823,7 +2841,7 @@ wait_until_unfixed: insert buffer (change buffer) as much as possible. */ ulint page_no = buf_block_get_page_no(block); - if (buf_LRU_free_block(&block->page, TRUE, FALSE)) { + if (buf_LRU_free_block(&block->page, TRUE, &have_LRU_mutex)) { mutex_exit(block_mutex); if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) { /* Set the watch, as it would have @@ -2860,12 +2878,21 @@ wait_until_unfixed: block = NULL; goto loop2; - } else if (buf_flush_page_try(buf_pool, block)) { - fprintf(stderr, - "innodb_change_buffering_debug flush %u %u\n", - (unsigned) space, (unsigned) offset); - guess = block; - goto loop; + } else { + /* We should not hold LRU mutex below when trying + to flush page */ + if (have_LRU_mutex) { + mutex_exit(&buf_pool->LRU_list_mutex); + have_LRU_mutex = FALSE; + } + + if (buf_flush_page_try(buf_pool, block)) { + fprintf(stderr, + "innodb_change_buffering_debug flush %u %u\n", + (unsigned) space, (unsigned) offset); + guess = block; + goto loop; + } } /* Failed to evict the page; change it directly */ @@ -3462,6 +3489,7 @@ buf_page_init_for_read( fold = buf_page_address_fold(space, offset); //buf_pool_mutex_enter(buf_pool); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); rw_lock_x_lock(&buf_pool->page_hash_latch); @@ -3680,6 +3708,7 @@ buf_page_create( fold = buf_page_address_fold(space, offset); //buf_pool_mutex_enter(buf_pool); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); rw_lock_x_lock(&buf_pool->page_hash_latch); @@ -3820,6 +3849,7 @@ buf_mark_space_corrupt( /* First unfix and release lock on the bpage */ //buf_pool_mutex_enter(buf_pool); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); rw_lock_x_lock(&buf_pool->page_hash_latch); mutex_enter(buf_page_get_mutex(bpage)); @@ -4058,11 +4088,12 @@ corrupt: buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY || #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ buf_page_get_flush_type(bpage) == BUF_FLUSH_LRU)) { - have_LRU_mutex = TRUE; /* optimistic */ } retry_mutex: - if (have_LRU_mutex) + if (!have_LRU_mutex) { mutex_enter(&buf_pool->LRU_list_mutex); + have_LRU_mutex = TRUE; + } block_mutex = buf_page_get_mutex_enter(bpage); ut_a(block_mutex); if (io_type == BUF_IO_WRITE @@ -4075,7 +4106,6 @@ retry_mutex: && !have_LRU_mutex) { mutex_exit(block_mutex); - have_LRU_mutex = TRUE; goto retry_mutex; } buf_pool_mutex_enter(buf_pool); @@ -4101,6 +4131,11 @@ retry_mutex: the x-latch to this OS thread: do not let this confuse you in debugging! */ + if (have_LRU_mutex) { + mutex_exit(&buf_pool->LRU_list_mutex); + have_LRU_mutex = FALSE; + } + ut_a(!have_LRU_mutex); ut_ad(buf_pool->n_pend_reads > 0); buf_pool->n_pend_reads--; @@ -4119,8 +4154,10 @@ retry_mutex: buf_flush_write_complete(bpage); - if (have_LRU_mutex) + if (have_LRU_mutex) { mutex_exit(&buf_pool->LRU_list_mutex); + have_LRU_mutex = FALSE; + } if (uncompressed) { rw_lock_s_unlock_gen(&((buf_block_t*) bpage)->lock, @@ -4195,6 +4232,7 @@ buf_all_freed_instance( ut_ad(buf_pool); //buf_pool_mutex_enter(buf_pool); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); rw_lock_x_lock(&buf_pool->page_hash_latch); @@ -4264,6 +4302,7 @@ buf_pool_invalidate_instance( } //buf_pool_mutex_enter(buf_pool); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0); @@ -4321,6 +4360,7 @@ buf_pool_validate_instance( ut_ad(buf_pool); //buf_pool_mutex_enter(buf_pool); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); rw_lock_x_lock(&buf_pool->page_hash_latch); /* for keep the new latch order, it cannot validate correctly... */ @@ -4586,6 +4626,7 @@ buf_print_instance( counts = mem_alloc(sizeof(ulint) * size); //buf_pool_mutex_enter(buf_pool); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); mutex_enter(&buf_pool->free_list_mutex); buf_flush_list_mutex_enter(buf_pool); @@ -4945,6 +4986,7 @@ buf_stats_get_pool_info( /* Find appropriate pool_info to store stats for this buffer pool */ pool_info = &all_pool_info[pool_id]; + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); mutex_enter(&buf_pool->free_list_mutex); buf_pool_mutex_enter(buf_pool); |