diff options
author | Jan Lindström <jplindst@mariadb.org> | 2013-11-15 11:32:02 +0200 |
---|---|---|
committer | Jan Lindström <jplindst@mariadb.org> | 2013-11-15 11:32:02 +0200 |
commit | 338587d2f4f1c0e977af8e924b13de7428007097 (patch) | |
tree | c8194855886f4fbac48451bf6cd258fc3f012c1e /storage/xtradb/buf | |
parent | 718c8c6044e05e666898b4ad3f3637d35bf67661 (diff) | |
download | mariadb-git-338587d2f4f1c0e977af8e924b13de7428007097.tar.gz |
MDEV-5247: DB locked up at btr0cur.c line 568. Additional fixes to inconsistent usage of have_LRU_mutex and added additional debug assertions to guard incorrect usage of this mutex. Fixes issues found on additional testing and mysql test suite.
Diffstat (limited to 'storage/xtradb/buf')
-rw-r--r-- | storage/xtradb/buf/buf0buf.c | 96 | ||||
-rw-r--r-- | storage/xtradb/buf/buf0lru.c | 24 |
2 files changed, 98 insertions, 22 deletions
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c index 2500edb5b5a..dee747b3c9d 100644 --- a/storage/xtradb/buf/buf0buf.c +++ b/storage/xtradb/buf/buf0buf.c @@ -1823,6 +1823,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 +1977,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(); @@ -2041,24 +2043,28 @@ err_exit: goto got_block; case BUF_BLOCK_FILE_PAGE: { - ibool have_LRU_mutex = FALSE; 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); - have_LRU_mutex = TRUE; if (UNIV_UNLIKELY(bpage->space != space || bpage->offset != offset || !bpage->in_LRU_list || !bpage->zip.data)) { /* someone should interrupt, retry */ - mutex_exit(&buf_pool->LRU_list_mutex); - have_LRU_mutex = FALSE; + if (have_LRU_mutex) { + mutex_exit(&buf_pool->LRU_list_mutex); + have_LRU_mutex = FALSE; + } mutex_exit(block_mutex); goto lookup; } @@ -2067,6 +2073,7 @@ err_exit: 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; @@ -2074,6 +2081,7 @@ err_exit: if (have_LRU_mutex) { mutex_exit(&buf_pool->LRU_list_mutex); + have_LRU_mutex = FALSE; } buf_block_buf_fix_inc((buf_block_t*) bpage, @@ -2458,6 +2466,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); @@ -2560,6 +2569,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); @@ -2675,7 +2691,11 @@ wait_until_unfixed: block_mutex = &block->mutex; //buf_pool_mutex_enter(buf_pool); - mutex_enter(&buf_pool->LRU_list_mutex); + 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); @@ -2699,7 +2719,12 @@ wait_until_unfixed: ut_a(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 loop2; } } @@ -2720,7 +2745,12 @@ wait_until_unfixed: //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; } @@ -2758,7 +2788,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); @@ -2831,7 +2864,6 @@ wait_until_unfixed: /* Try to evict the block from the buffer pool, to use the insert buffer (change buffer) as much as possible. */ ulint page_no = buf_block_get_page_no(block); - ibool have_LRU_mutex = FALSE; if (buf_LRU_free_block(&block->page, TRUE, &have_LRU_mutex)) { mutex_exit(block_mutex); @@ -2870,12 +2902,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 */ @@ -3472,6 +3513,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); @@ -3690,6 +3732,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); @@ -3830,6 +3873,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)); @@ -4068,11 +4112,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 @@ -4085,7 +4130,6 @@ retry_mutex: && !have_LRU_mutex) { mutex_exit(block_mutex); - have_LRU_mutex = TRUE; goto retry_mutex; } buf_pool_mutex_enter(buf_pool); @@ -4111,6 +4155,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--; @@ -4129,8 +4178,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, @@ -4205,6 +4256,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); @@ -4274,6 +4326,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); @@ -4331,6 +4384,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... */ @@ -4596,6 +4650,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); @@ -4955,6 +5010,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); diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c index c05de76cfa2..cfb45232084 100644 --- a/storage/xtradb/buf/buf0lru.c +++ b/storage/xtradb/buf/buf0lru.c @@ -294,6 +294,8 @@ buf_LRU_drop_page_hash_for_tablespace( sizeof(ulint) * BUF_LRU_DROP_SEARCH_SIZE); //buf_pool_mutex_enter(buf_pool); + + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); num_entries = 0; @@ -362,6 +364,7 @@ next_page: num_entries = 0; //buf_pool_mutex_enter(buf_pool); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); /* Note that we released the buf_pool mutex above @@ -438,6 +441,7 @@ buf_flush_yield( /* Try and force a context switch. */ os_thread_yield(); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); mutex_enter(block_mutex); @@ -690,6 +694,7 @@ buf_flush_dirty_pages( ibool all_freed; do { + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); all_freed = buf_flush_or_remove_pages(buf_pool, id); @@ -720,6 +725,7 @@ buf_LRU_remove_all_pages( scan_again: //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); @@ -1087,6 +1093,7 @@ buf_LRU_search_and_free_block( //buf_pool_mutex_enter(buf_pool); if (UT_LIST_GET_LEN(buf_pool->unzip_LRU)) { + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); have_LRU_mutex = TRUE; } @@ -1169,6 +1176,7 @@ buf_LRU_buf_pool_running_out(void) buf_pool = buf_pool_from_array(i); //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); @@ -2095,9 +2103,9 @@ not_freed: } //buf_pool_mutex_enter(buf_pool); - if (*have_LRU_mutex) { + if (!*have_LRU_mutex) { mutex_enter(&buf_pool->LRU_list_mutex); - *have_LRU_mutex = FALSE; + *have_LRU_mutex = TRUE; } mutex_enter(block_mutex); @@ -2108,6 +2116,12 @@ not_freed: } buf_LRU_block_free_hashed_page((buf_block_t*) bpage, FALSE); + + if (*have_LRU_mutex) { + mutex_exit(&buf_pool->LRU_list_mutex); + *have_LRU_mutex = FALSE; + } + } else { /* The block_mutex should have been released by buf_LRU_block_remove_hashed_page() when it returns @@ -2488,6 +2502,7 @@ buf_LRU_old_ratio_update_instance( if (adjust) { //buf_pool_mutex_enter(buf_pool); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); if (ratio != buf_pool->LRU_old_ratio) { @@ -2661,6 +2676,7 @@ buf_LRU_file_dump(void) buf_pool = buf_pool_from_array(i); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); bpage = first_bpage = UT_LIST_GET_FIRST(buf_pool->LRU); total_pages = UT_LIST_GET_LEN(buf_pool->LRU); @@ -2717,6 +2733,7 @@ buf_LRU_file_dump(void) /* Grab this here so that next_bpage can't be purged when we drop the fix_count */ + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); if (next_bpage) { @@ -2968,6 +2985,7 @@ buf_LRU_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); if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) { @@ -3043,6 +3061,7 @@ buf_LRU_validate_instance( } mutex_exit(&buf_pool->free_list_mutex); + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); mutex_enter(&buf_pool->LRU_list_mutex); UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU, @@ -3096,6 +3115,7 @@ buf_LRU_print_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); bpage = UT_LIST_GET_FIRST(buf_pool->LRU); |