summaryrefslogtreecommitdiff
path: root/storage/xtradb/buf/buf0buf.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/buf/buf0buf.c')
-rw-r--r--storage/xtradb/buf/buf0buf.c148
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);