diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 983603e..34fb1eb 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -731,6 +731,36 @@ static void pfs_register_buffer_block( } #endif /* PFS_GROUP_BUFFER_SYNC */ +/** +Initializes mutex and rwlock of a buffer control block +@param[in] block buffer control block */ +void +buf_block_init_locks( + buf_block_t* block) +{ + mutex_create(LATCH_ID_BUF_BLOCK_MUTEX, &block->mutex); + +#if defined PFS_SKIP_BUFFER_MUTEX_RWLOCK || defined PFS_GROUP_BUFFER_SYNC + /* If PFS_SKIP_BUFFER_MUTEX_RWLOCK is defined, skip registration + of buffer block rwlock with performance schema. + + If PFS_GROUP_BUFFER_SYNC is defined, skip the registration + since buffer block rwlock will be registered later in + pfs_register_buffer_block(). */ + + rw_lock_create(PFS_NOT_INSTRUMENTED, &block->lock, SYNC_LEVEL_VARYING); + ut_d(rw_lock_create(PFS_NOT_INSTRUMENTED, &block->debug_latch, + SYNC_NO_ORDER_CHECK)); +#else /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */ + rw_lock_create(buf_block_lock_key, &block->lock, SYNC_LEVEL_VARYING); + ut_d(rw_lock_create(buf_block_debug_latch_key, &block->debug_latch, + SYNC_NO_ORDER_CHECK)); +#endif /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */ + + ut_ad(rw_lock_validate(&(block->lock))); + block->locks_inited = true; +} + /** Initializes a buffer control block when the buf_pool is created. */ static void buf_block_init( buf_pool_t *buf_pool, /*!< in: buffer pool instance */ @@ -768,33 +798,7 @@ static void buf_block_init( page_zip_des_init(&block->page.zip); - mutex_create(LATCH_ID_BUF_BLOCK_MUTEX, &block->mutex); - -#if defined PFS_SKIP_BUFFER_MUTEX_RWLOCK || defined PFS_GROUP_BUFFER_SYNC - /* If PFS_SKIP_BUFFER_MUTEX_RWLOCK is defined, skip registration - of buffer block rwlock with performance schema. - - If PFS_GROUP_BUFFER_SYNC is defined, skip the registration - since buffer block rwlock will be registered later in - pfs_register_buffer_block(). */ - - rw_lock_create(PFS_NOT_INSTRUMENTED, &block->lock, SYNC_LEVEL_VARYING); - - ut_d(rw_lock_create(PFS_NOT_INSTRUMENTED, &block->debug_latch, - SYNC_NO_ORDER_CHECK)); - -#else /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */ - - rw_lock_create(buf_block_lock_key, &block->lock, SYNC_LEVEL_VARYING); - - ut_d(rw_lock_create(buf_block_debug_latch_key, &block->debug_latch, - SYNC_NO_ORDER_CHECK)); - -#endif /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */ - block->lock.is_block_lock = 1; - - ut_ad(rw_lock_validate(&(block->lock))); } /* We maintain our private view of innobase_should_madvise_buf_pool() which we initialize at the beginning of buf_pool_init() and then update when the @@ -1267,10 +1271,11 @@ static void buf_pool_create(buf_pool_t *buf_pool, ulint buf_pool_size, buf_block_t *block = chunk->blocks; for (i = chunk->size; i--; block++) { - mutex_free(&block->mutex); - rw_lock_free(&block->lock); - - ut_d(rw_lock_free(&block->debug_latch)); + if (block->locks_inited) { + mutex_free(&block->mutex); + rw_lock_free(&block->lock); + ut_d(rw_lock_free(&block->debug_latch)); + } } buf_pool->deallocate_chunk(chunk); } @@ -1393,12 +1398,13 @@ static void buf_pool_free_instance(buf_pool_t *buf_pool) { buf_block_t *block = chunk->blocks; for (ulint i = chunk->size; i--; block++) { - mutex_free(&block->mutex); - rw_lock_free(&block->lock); + if (block->locks_inited) { + mutex_free(&block->mutex); + rw_lock_free(&block->lock); - ut_d(rw_lock_free(&block->debug_latch)); + ut_d(rw_lock_free(&block->debug_latch)); + } } - buf_pool->deallocate_chunk(chunk); } @@ -2264,10 +2270,12 @@ withdraw_retry: buf_block_t *block = chunk->blocks; for (ulint j = chunk->size; j--; block++) { - mutex_free(&block->mutex); - rw_lock_free(&block->lock); + if (block->locks_inited) { + mutex_free(&block->mutex); + rw_lock_free(&block->lock); - ut_d(rw_lock_free(&block->debug_latch)); + ut_d(rw_lock_free(&block->debug_latch)); + } } buf_pool->deallocate_chunk(chunk); diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index dedb6af..446ac16 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1119,6 +1119,9 @@ buf_block_t *buf_LRU_get_free_only(buf_pool_t *buf_pool) { /* found valid free block */ /* No adaptive hash index entries may point to a free block. */ + if (block->locks_inited == false) + buf_block_init_locks(block); + assert_block_ahi_empty(block); buf_block_set_state(block, BUF_BLOCK_READY_FOR_USE); diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 6025e2f..897b99c 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -4507,10 +4507,12 @@ static int i_s_innodb_fill_buffer_pool( /* GO through each block in the chunk */ for (n_blocks = num_to_process; n_blocks--; block++) { - i_s_innodb_buffer_page_get_info(&block->page, pool_id, block_id, - info_buffer + num_page); - block_id++; - num_page++; + if (block->locks_inited) { + i_s_innodb_buffer_page_get_info(&block->page, pool_id, block_id, + info_buffer + num_page); + block_id++; + num_page++; + } } /* Fill in information schema table with information diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index c46fd6f..f921f5e 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -349,6 +349,13 @@ UNIV_INLINE void buf_block_free(buf_block_t *block); /*!< in, own: block to be freed */ #endif /* !UNIV_HOTBACKUP */ +/** +Initializes mutex and rwlock of a buffer control block +@param[in] block buffer control block */ +void +buf_block_init_locks( + buf_block_t* block); + /** Copies contents of a buffer frame to a given buffer. @param[in] buf buffer to copy to @param[in] frame buffer frame @@ -1479,6 +1486,9 @@ struct buf_block_t { mutex in InnoDB-5.1 to relieve contention on the buffer pool mutex */ + /** Mark if this block's locks has been inited. */ + bool locks_inited; + /** Get the page number of the current buffer block. @return page number of the current buffer block. */ page_no_t get_page_no() const { return (page.id.page_no()); } @@ -1996,6 +2006,7 @@ Use these instead of accessing buffer pool mutexes directly. */ /** Acquire the block->mutex. */ #define buf_page_mutex_enter(b) \ do { \ + ut_ad(b->locks_inited); \ mutex_enter(&(b)->mutex); \ } while (0) diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 63baef3..dd68d8a 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -960,6 +960,10 @@ buf_page_t *buf_page_hash_get_low(buf_pool_t *buf_pool, ut_ad(bpage->in_page_hash); ut_ad(!bpage->in_zip_hash); ut_ad(buf_pool_from_bpage(bpage) == buf_pool); + ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY + || buf_page_get_state(bpage) == BUF_BLOCK_ZIP_PAGE + || buf_page_get_state(bpage) == BUF_BLOCK_POOL_WATCH + || ((buf_block_t*)bpage)->locks_inited); } return (bpage);