#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
---- a/storage/innobase/btr/btr0cur.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/btr/btr0cur.c 2010-12-03 15:48:29.268957148 +0900
-@@ -4069,7 +4069,8 @@
+--- a/storage/innobase/btr/btr0cur.c
++++ b/storage/innobase/btr/btr0cur.c
+@@ -4070,7 +4070,8 @@
mtr_commit(mtr);
mutex_enter(&block->mutex);
/* Only free the block if it is still allocated to
-@@ -4080,16 +4081,21 @@
+@@ -4081,16 +4082,21 @@
&& buf_block_get_space(block) == space
&& buf_block_get_page_no(block) == page_no) {
-- if (buf_LRU_free_block(&block->page, all) != BUF_LRU_FREED
+- if (!buf_LRU_free_block(&block->page, all)
- && all && block->page.zip.data) {
-+ if (buf_LRU_free_block(&block->page, all, TRUE) != BUF_LRU_FREED
++ if (!buf_LRU_free_block(&block->page, all, TRUE)
+ && all && block->page.zip.data
+ /* Now, buf_LRU_free_block() may release mutex temporarily */
+ && buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
mutex_exit(&block->mutex);
}
-diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
---- a/storage/innobase/btr/btr0sea.c 2010-12-03 15:48:03.033037049 +0900
-+++ b/storage/innobase/btr/btr0sea.c 2010-12-03 15:48:29.271024260 +0900
-@@ -1943,7 +1943,7 @@
+--- a/storage/innobase/btr/btr0sea.c
++++ b/storage/innobase/btr/btr0sea.c
+@@ -1972,7 +1972,7 @@
rec_offs_init(offsets_);
rw_lock_x_lock(&btr_search_latch);
cell_count = hash_get_n_cells(btr_search_sys->hash_index);
-@@ -1951,11 +1951,11 @@
+@@ -1980,11 +1980,11 @@
/* We release btr_search_latch every once in a while to
give other queries a chance to run. */
if ((i != 0) && ((i % chunk_size) == 0)) {
}
node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
-@@ -2066,11 +2066,11 @@
+@@ -2093,11 +2093,11 @@
/* We release btr_search_latch every once in a while to
give other queries a chance to run. */
if (i != 0) {
}
if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
-@@ -2078,7 +2078,7 @@
+@@ -2105,7 +2105,7 @@
}
}
rw_lock_x_unlock(&btr_search_latch);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
-diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
---- a/storage/innobase/buf/buf0buddy.c 2010-12-03 15:22:36.307986907 +0900
-+++ b/storage/innobase/buf/buf0buddy.c 2010-12-03 15:48:29.275025723 +0900
-@@ -73,10 +73,11 @@
- if (b) UNIV_MEM_VALID(b, BUF_BUDDY_LOW << i);
- #endif /* UNIV_DEBUG_VALGRIND */
-
+--- a/storage/innobase/buf/buf0buddy.c
++++ b/storage/innobase/buf/buf0buddy.c
+@@ -58,7 +58,7 @@
+
+ /** Validate a given zip_free list. */
+ #define BUF_BUDDY_LIST_VALIDATE(b, i) \
+- UT_LIST_VALIDATE(list, buf_page_t, \
++ UT_LIST_VALIDATE(zip_list, buf_page_t, \
+ b->zip_free[i], \
+ ut_ad(buf_page_get_state( \
+ ut_list_node_313) \
+@@ -75,10 +75,11 @@
+ ulint i) /*!< in: index of
+ buf_pool->zip_free[] */
+ {
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
ut_ad(buf_pool->zip_free[i].start != bpage);
- UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], bpage);
+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_free[i], bpage);
+ }
- #ifdef UNIV_DEBUG_VALGRIND
- if (b) UNIV_MEM_FREE(b, BUF_BUDDY_LOW << i);
-@@ -96,8 +97,8 @@
+ /**********************************************************************//**
+@@ -93,16 +94,17 @@
buf_pool->zip_free[] */
{
- #ifdef UNIV_DEBUG_VALGRIND
+ #ifdef UNIV_DEBUG
- buf_page_t* prev = UT_LIST_GET_PREV(list, bpage);
- buf_page_t* next = UT_LIST_GET_NEXT(list, bpage);
+ buf_page_t* prev = UT_LIST_GET_PREV(zip_list, bpage);
+ buf_page_t* next = UT_LIST_GET_NEXT(zip_list, bpage);
- if (prev) UNIV_MEM_VALID(prev, BUF_BUDDY_LOW << i);
- if (next) UNIV_MEM_VALID(next, BUF_BUDDY_LOW << i);
-@@ -106,9 +107,10 @@
+ ut_ad(!prev || buf_page_get_state(prev) == BUF_BLOCK_ZIP_FREE);
ut_ad(!next || buf_page_get_state(next) == BUF_BLOCK_ZIP_FREE);
- #endif /* UNIV_DEBUG_VALGRIND */
+ #endif /* UNIV_DEBUG */
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
- UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
+ UT_LIST_REMOVE(zip_list, buf_pool->zip_free[i], bpage);
+ }
- #ifdef UNIV_DEBUG_VALGRIND
- if (prev) UNIV_MEM_FREE(prev, BUF_BUDDY_LOW << i);
-@@ -128,12 +130,13 @@
+ /**********************************************************************//**
+@@ -117,7 +119,8 @@
{
buf_page_t* bpage;
+ //ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
ut_a(i < BUF_BUDDY_SIZES);
+ ut_a(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
- #ifndef UNIV_DEBUG_VALGRIND
- /* Valgrind would complain about accessing free memory. */
-- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
- ut_ad(buf_page_get_state(ut_list_node_313)
- == BUF_BLOCK_ZIP_FREE)));
- #endif /* !UNIV_DEBUG_VALGRIND */
-@@ -177,16 +180,19 @@
+@@ -159,16 +162,19 @@
buf_buddy_block_free(
/*=================*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
HASH_SEARCH(hash, buf_pool->zip_hash, fold, buf_page_t*, bpage,
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_MEMORY
&& bpage->in_zip_hash && !bpage->in_page_hash),
-@@ -198,12 +204,14 @@
+@@ -180,12 +186,14 @@
ut_d(bpage->in_zip_hash = FALSE);
HASH_DELETE(buf_page_t, hash, buf_pool->zip_hash, fold, bpage);
mutex_exit(&block->mutex);
ut_ad(buf_pool->buddy_n_frames > 0);
-@@ -220,7 +228,7 @@
+@@ -202,7 +210,7 @@
{
buf_pool_t* buf_pool = buf_pool_from_block(block);
const ulint fold = BUF_POOL_ZIP_FOLD(block);
ut_ad(!mutex_own(&buf_pool->zip_mutex));
ut_ad(buf_block_get_state(block) == BUF_BLOCK_READY_FOR_USE);
-@@ -232,7 +240,10 @@
+@@ -214,7 +222,10 @@
ut_ad(!block->page.in_page_hash);
ut_ad(!block->page.in_zip_hash);
ut_d(block->page.in_zip_hash = TRUE);
ut_d(buf_pool->buddy_n_frames++);
}
-@@ -268,7 +279,7 @@
- bpage->state = BUF_BLOCK_ZIP_FREE;
- #ifndef UNIV_DEBUG_VALGRIND
- /* Valgrind would complain about accessing free memory. */
-- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
- ut_ad(buf_page_get_state(
- ut_list_node_313)
- == BUF_BLOCK_ZIP_FREE)));
-@@ -291,25 +302,29 @@
- buf_pool_t* buf_pool, /*!< in: buffer pool instance */
+@@ -268,26 +279,30 @@
+ buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
- ibool* lru) /*!< in: pointer to a variable that
will be assigned TRUE if storage was
allocated from the LRU list and
buf_pool->mutex was temporarily
- released, or NULL if the LRU list
- should not be used */
+ released */
+ ibool have_page_hash_mutex)
{
buf_block_t* block;
+ ut_ad(lru);
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
ut_ad(!mutex_own(&buf_pool->zip_mutex));
+ ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
if (i < BUF_BUDDY_SIZES) {
/* Try to allocate from the buddy system. */
}
/* Try allocating from the buf_pool->free list. */
-@@ -326,19 +341,30 @@
+@@ -299,19 +314,30 @@
}
/* Try replacing an uncompressed page in the buffer pool. */
return(block);
}
-@@ -355,7 +381,10 @@
- buf_page_t* b;
- buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
-
-- ut_ad(buf_pool_mutex_own(buf_pool));
-+ //ut_ad(buf_pool_mutex_own(buf_pool));
-+#ifdef UNIV_SYNC_DEBUG
-+ ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX));
-+#endif
-
- switch (buf_page_get_state(bpage)) {
- case BUF_BLOCK_ZIP_FREE:
-@@ -364,7 +393,7 @@
- case BUF_BLOCK_FILE_PAGE:
- case BUF_BLOCK_MEMORY:
- case BUF_BLOCK_REMOVE_HASH:
-- ut_error;
-+ /* ut_error; */ /* optimistic */
- case BUF_BLOCK_ZIP_DIRTY:
- /* Cannot relocate dirty pages. */
- return(FALSE);
-@@ -374,9 +403,18 @@
- }
-
- mutex_enter(&buf_pool->zip_mutex);
-+ mutex_enter(&buf_pool->zip_free_mutex);
-
- if (!buf_page_can_relocate(bpage)) {
- mutex_exit(&buf_pool->zip_mutex);
-+ mutex_exit(&buf_pool->zip_free_mutex);
-+ return(FALSE);
-+ }
-+
-+ if (bpage != buf_page_hash_get(buf_pool,
-+ bpage->space, bpage->offset)) {
-+ mutex_exit(&buf_pool->zip_mutex);
-+ mutex_exit(&buf_pool->zip_free_mutex);
- return(FALSE);
- }
-
-@@ -384,18 +422,19 @@
- ut_d(bpage->state = BUF_BLOCK_ZIP_FREE);
-
- /* relocate buf_pool->zip_clean */
-- b = UT_LIST_GET_PREV(list, dpage);
-- UT_LIST_REMOVE(list, buf_pool->zip_clean, dpage);
-+ b = UT_LIST_GET_PREV(zip_list, dpage);
-+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, dpage);
-
- if (b) {
-- UT_LIST_INSERT_AFTER(list, buf_pool->zip_clean, b, dpage);
-+ UT_LIST_INSERT_AFTER(zip_list, buf_pool->zip_clean, b, dpage);
- } else {
-- UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, dpage);
-+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_clean, dpage);
- }
-
- UNIV_MEM_INVALID(bpage, sizeof *bpage);
-
- mutex_exit(&buf_pool->zip_mutex);
-+ mutex_exit(&buf_pool->zip_free_mutex);
- return(TRUE);
- }
-
-@@ -409,14 +448,16 @@
+@@ -325,8 +351,9 @@
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
void* src, /*!< in: block to relocate */
void* dst, /*!< in: free block to relocate to */
{
buf_page_t* bpage;
const ulint size = BUF_BUDDY_LOW << i;
- ullint usec = ut_time_us(NULL);
+@@ -334,13 +361,20 @@
+ ulint space;
+ ulint page_no;
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(!mutex_own(&buf_pool->zip_mutex));
ut_ad(!ut_align_offset(src, size));
ut_ad(!ut_align_offset(dst, size));
-@@ -437,6 +478,13 @@
- if (size >= PAGE_ZIP_MIN_SIZE) {
- /* This is a compressed page. */
- mutex_t* mutex;
-+ ulint space, page_no;
-+
-+ if (!have_page_hash_mutex) {
-+ mutex_exit(&buf_pool->zip_free_mutex);
-+ mutex_enter(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_lock(&buf_pool->page_hash_latch);
-+ }
-
- /* The src block may be split into smaller blocks,
- some of which may be free. Thus, the
-@@ -446,9 +494,9 @@
- pool), so there is nothing wrong about this. The
- mach_read_from_4() calls here will only trigger bogus
- Valgrind memcheck warnings in UNIV_DEBUG_VALGRIND builds. */
-- ulint space = mach_read_from_4(
-+ space = mach_read_from_4(
- (const byte*) src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
-- ulint page_no = mach_read_from_4(
-+ page_no = mach_read_from_4(
- (const byte*) src + FIL_PAGE_OFFSET);
- /* Suppress Valgrind warnings about conditional jump
- on uninitialized value. */
-@@ -462,6 +510,11 @@
- added to buf_pool->page_hash yet. Obviously,
- it cannot be relocated. */
-
-+ if (!have_page_hash_mutex) {
-+ mutex_enter(&buf_pool->zip_free_mutex);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
-+ }
- return(FALSE);
- }
-
-@@ -473,18 +526,27 @@
- For the sake of simplicity, give up. */
- ut_ad(page_zip_get_size(&bpage->zip) < size);
-
-+ if (!have_page_hash_mutex) {
-+ mutex_enter(&buf_pool->zip_free_mutex);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
-+ }
- return(FALSE);
- }
+ ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
+ UNIV_MEM_ASSERT_W(dst, size);
-+ /* To keep latch order */
-+ if (have_page_hash_mutex)
-+ mutex_exit(&buf_pool->zip_free_mutex);
++ if (!have_page_hash_mutex) {
++ mutex_exit(&buf_pool->zip_free_mutex);
++ mutex_enter(&buf_pool->LRU_list_mutex);
++ rw_lock_x_lock(&buf_pool->page_hash_latch);
++ }
+
- /* The block must have been allocated, but it may
- contain uninitialized data. */
- UNIV_MEM_ASSERT_W(src, size);
+ /* We assume that all memory from buf_buddy_alloc()
+ is used for compressed page frames. */
-- mutex = buf_page_get_mutex(bpage);
-+ mutex = buf_page_get_mutex_enter(bpage);
+@@ -374,6 +408,11 @@
+ added to buf_pool->page_hash yet. Obviously,
+ it cannot be relocated. */
-- mutex_enter(mutex);
-+ mutex_enter(&buf_pool->zip_free_mutex);
++ if (!have_page_hash_mutex) {
++ mutex_enter(&buf_pool->zip_free_mutex);
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ rw_lock_x_unlock(&buf_pool->page_hash_latch);
++ }
+ return(FALSE);
+ }
-- if (buf_page_can_relocate(bpage)) {
-+ if (mutex && buf_page_can_relocate(bpage)) {
- /* Relocate the compressed page. */
- ut_a(bpage->zip.data == src);
- memcpy(dst, src, size);
-@@ -499,10 +561,22 @@
- buddy_stat->relocated_usec
- += ut_time_us(NULL) - usec;
- }
-+
-+ if (!have_page_hash_mutex) {
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
-+ }
- return(TRUE);
- }
+@@ -383,18 +422,27 @@
+ For the sake of simplicity, give up. */
+ ut_ad(page_zip_get_size(&bpage->zip) < size);
-- mutex_exit(mutex);
+ if (!have_page_hash_mutex) {
++ mutex_enter(&buf_pool->zip_free_mutex);
+ mutex_exit(&buf_pool->LRU_list_mutex);
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
+ }
-+
-+ if (mutex) {
-+ mutex_exit(mutex);
-+ }
- } else if (i == buf_buddy_get_slot(sizeof(buf_page_t))) {
- /* This must be a buf_page_t object. */
- #if UNIV_WORD_SIZE == 4
-@@ -511,10 +585,31 @@
- about uninitialized pad bytes. */
- UNIV_MEM_ASSERT_RW(src, size);
- #endif
-+
+ return(FALSE);
+ }
+
++ /* To keep latch order */
++ if (have_page_hash_mutex)
+ mutex_exit(&buf_pool->zip_free_mutex);
+
-+ if (!have_page_hash_mutex) {
-+ mutex_enter(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_lock(&buf_pool->page_hash_latch);
-+ }
-+
- if (buf_buddy_relocate_block(src, dst)) {
-+ mutex_enter(&buf_pool->zip_free_mutex);
-+
-+ if (!have_page_hash_mutex) {
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
-+ }
+ /* The block must have been allocated, but it may
+ contain uninitialized data. */
+ UNIV_MEM_ASSERT_W(src, size);
+
+- mutex = buf_page_get_mutex(bpage);
++ mutex = buf_page_get_mutex_enter(bpage);
+
+- mutex_enter(mutex);
++ mutex_enter(&buf_pool->zip_free_mutex);
- goto success;
+- if (buf_page_can_relocate(bpage)) {
++ if (mutex && buf_page_can_relocate(bpage)) {
+ /* Relocate the compressed page. */
+ ullint usec = ut_time_us(NULL);
+ ut_a(bpage->zip.data == src);
+@@ -409,10 +457,22 @@
+ buddy_stat->relocated_usec
+ += ut_time_us(NULL) - usec;
}
+
-+ mutex_enter(&buf_pool->zip_free_mutex);
-+
+ if (!have_page_hash_mutex) {
+ mutex_exit(&buf_pool->LRU_list_mutex);
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
+ }
+ return(TRUE);
}
+- mutex_exit(mutex);
++ if (!have_page_hash_mutex) {
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ rw_lock_x_unlock(&buf_pool->page_hash_latch);
++ }
++
++ if (mutex) {
++ mutex_exit(mutex);
++ }
return(FALSE);
-@@ -529,13 +624,15 @@
+ }
+
+@@ -425,13 +485,15 @@
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
ut_ad(!mutex_own(&buf_pool->zip_mutex));
ut_ad(i <= BUF_BUDDY_SIZES);
- ut_ad(buf_pool->buddy_stat[i].used > 0);
-@@ -546,7 +643,9 @@
- ut_d(((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE);
+ ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
+@@ -443,7 +505,9 @@
+ ((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE;
if (i == BUF_BUDDY_SIZES) {
- buf_buddy_block_free(buf_pool, buf);
return;
}
-@@ -591,7 +690,7 @@
+@@ -491,7 +555,7 @@
+
ut_a(bpage != buf);
+ UNIV_MEM_ASSERT_W(bpage, BUF_BUDDY_LOW << i);
+- bpage = UT_LIST_GET_NEXT(list, bpage);
++ bpage = UT_LIST_GET_NEXT(zip_list, bpage);
+ }
- {
-- buf_page_t* next = UT_LIST_GET_NEXT(list, bpage);
-+ buf_page_t* next = UT_LIST_GET_NEXT(zip_list, bpage);
- UNIV_MEM_ASSERT_AND_FREE(bpage, BUF_BUDDY_LOW << i);
- bpage = next;
- }
-@@ -600,13 +699,13 @@
#ifndef UNIV_DEBUG_VALGRIND
- buddy_nonfree:
- /* Valgrind would complain about accessing free memory. */
-- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
- ut_ad(buf_page_get_state(ut_list_node_313)
- == BUF_BLOCK_ZIP_FREE)));
- #endif /* UNIV_DEBUG_VALGRIND */
+@@ -501,7 +565,7 @@
+ ut_d(BUF_BUDDY_LIST_VALIDATE(buf_pool, i));
/* The buddy is not free. Is there a free block of this size? */
- bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
+ bpage = UT_LIST_GET_LAST(buf_pool->zip_free[i]);
if (bpage) {
- /* Remove the block from the free list, because a successful
-@@ -616,7 +715,7 @@
+
+@@ -510,7 +574,7 @@
buf_buddy_remove_from_free(buf_pool, bpage, i);
/* Try to relocate the buddy of buf to the free block. */
- if (buf_buddy_relocate(buf_pool, buddy, bpage, i)) {
+ if (buf_buddy_relocate(buf_pool, buddy, bpage, i, have_page_hash_mutex)) {
- ut_d(buddy->state = BUF_BLOCK_ZIP_FREE);
- goto buddy_free2;
-@@ -636,14 +735,14 @@
-
- (Parts of the buddy can be free in
- buf_pool->zip_free[j] with j < i.) */
-- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
- ut_ad(buf_page_get_state(
- ut_list_node_313)
- == BUF_BLOCK_ZIP_FREE
- && ut_list_node_313 != buddy)));
- #endif /* !UNIV_DEBUG_VALGRIND */
-
-- if (buf_buddy_relocate(buf_pool, buddy, buf, i)) {
-+ if (buf_buddy_relocate(buf_pool, buddy, buf, i, have_page_hash_mutex)) {
-
- buf = bpage;
- UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-12-03 15:22:36.314943336 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-03 15:48:29.282947357 +0900
+ buddy->state = BUF_BLOCK_ZIP_FREE;
+ goto buddy_is_free;
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
@@ -263,6 +263,7 @@
#ifdef UNIV_PFS_RWLOCK
/* Keys to register buffer block related rwlocks and mutexes with
UNIV_INTERN mysql_pfs_key_t flush_list_mutex_key;
#endif /* UNIV_PFS_MUTEX */
-@@ -881,9 +886,13 @@
+@@ -890,9 +895,13 @@
block->page.in_zip_hash = FALSE;
block->page.in_flush_list = FALSE;
block->page.in_free_list = FALSE;
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
block->n_pointers = 0;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-@@ -981,9 +990,11 @@
+@@ -997,9 +1006,11 @@
memset(block->frame, '\0', UNIV_PAGE_SIZE);
#endif
/* Add the block to the free list */
ut_ad(buf_pool_from_block(block) == buf_pool);
block++;
-@@ -1038,7 +1049,8 @@
+@@ -1054,7 +1065,8 @@
buf_chunk_t* chunk = buf_pool->chunks;
ut_ad(buf_pool);
for (n = buf_pool->n_chunks; n--; chunk++) {
buf_block_t* block = buf_chunk_contains_zip(chunk, data);
-@@ -1138,7 +1150,7 @@
- buf_block_t* block;
- const buf_block_t* block_end;
-
-- ut_ad(buf_pool_mutex_own(buf_pool));
-+ //ut_ad(buf_pool_mutex_own(buf_pool)); /* but we need all mutex here */
-
- block_end = chunk->blocks + chunk->size;
-
-@@ -1150,8 +1162,10 @@
- ut_ad(!block->in_unzip_LRU_list);
- ut_ad(!block->page.in_flush_list);
- /* Remove the block from the free list. */
-+ mutex_enter(&buf_pool->free_list_mutex);
- ut_ad(block->page.in_free_list);
-- UT_LIST_REMOVE(list, buf_pool->free, (&block->page));
-+ UT_LIST_REMOVE(free, buf_pool->free, (&block->page));
-+ mutex_exit(&buf_pool->free_list_mutex);
-
- /* Free the latches. */
- mutex_free(&block->mutex);
-@@ -1208,9 +1222,21 @@
+@@ -1160,9 +1172,21 @@
------------------------------- */
mutex_create(buf_pool_mutex_key,
&buf_pool->mutex, SYNC_BUF_POOL);
buf_pool_mutex_enter(buf_pool);
if (buf_pool_size > 0) {
-@@ -1223,6 +1249,8 @@
+@@ -1175,6 +1199,8 @@
mem_free(chunk);
mem_free(buf_pool);
buf_pool_mutex_exit(buf_pool);
return(DB_ERROR);
-@@ -1253,6 +1281,8 @@
+@@ -1205,6 +1231,8 @@
/* All fields are initialized by mem_zalloc(). */
buf_pool_mutex_exit(buf_pool);
return(DB_SUCCESS);
-@@ -1467,7 +1497,11 @@
+@@ -1376,7 +1404,11 @@
ulint fold;
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
ut_a(bpage->buf_fix_count == 0);
-@@ -1554,7 +1588,8 @@
-
- try_again:
- btr_search_disable(); /* Empty the adaptive hash index again */
-- buf_pool_mutex_enter(buf_pool);
-+ //buf_pool_mutex_enter(buf_pool);
-+ mutex_enter(&buf_pool->LRU_list_mutex);
-
- shrink_again:
- if (buf_pool->n_chunks <= 1) {
-@@ -1625,7 +1660,7 @@
-
- buf_LRU_make_block_old(&block->page);
- dirty++;
-- } else if (buf_LRU_free_block(&block->page, TRUE)
-+ } else if (buf_LRU_free_block(&block->page, TRUE, TRUE)
- != BUF_LRU_FREED) {
- nonfree++;
- }
-@@ -1633,7 +1668,8 @@
- mutex_exit(&block->mutex);
- }
-
-- buf_pool_mutex_exit(buf_pool);
-+ //buf_pool_mutex_exit(buf_pool);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-
- /* Request for a flush of the chunk if it helps.
- Do not flush if there are non-free blocks, since
-@@ -1683,7 +1719,8 @@
- func_done:
- buf_pool->old_pool_size = buf_pool->curr_pool_size;
- func_exit:
-- buf_pool_mutex_exit(buf_pool);
-+ //buf_pool_mutex_exit(buf_pool);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
- btr_search_enable();
- }
-
-@@ -1724,7 +1761,9 @@
- hash_table_t* zip_hash;
- hash_table_t* page_hash;
-
-- buf_pool_mutex_enter(buf_pool);
-+ //buf_pool_mutex_enter(buf_pool);
-+ mutex_enter(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_lock(&buf_pool->page_hash_latch);
-
- /* Free, create, and populate the hash table. */
- hash_table_free(buf_pool->page_hash);
-@@ -1765,8 +1804,9 @@
- All such blocks are either in buf_pool->zip_clean or
- in buf_pool->flush_list. */
-
-+ mutex_enter(&buf_pool->zip_mutex);
- for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
-- b = UT_LIST_GET_NEXT(list, b)) {
-+ b = UT_LIST_GET_NEXT(zip_list, b)) {
- ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
- ut_ad(!b->in_flush_list);
- ut_ad(b->in_LRU_list);
-@@ -1776,10 +1816,11 @@
- HASH_INSERT(buf_page_t, hash, page_hash,
- buf_page_address_fold(b->space, b->offset), b);
- }
-+ mutex_exit(&buf_pool->zip_mutex);
-
- buf_flush_list_mutex_enter(buf_pool);
- for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
-- b = UT_LIST_GET_NEXT(list, b)) {
-+ b = UT_LIST_GET_NEXT(flush_list, b)) {
- ut_ad(b->in_flush_list);
- ut_ad(b->in_LRU_list);
- ut_ad(b->in_page_hash);
-@@ -1806,7 +1847,9 @@
- }
-
- buf_flush_list_mutex_exit(buf_pool);
-- buf_pool_mutex_exit(buf_pool);
-+ //buf_pool_mutex_exit(buf_pool);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
- }
-
- /********************************************************************
-@@ -1853,21 +1896,32 @@
+@@ -1487,21 +1519,32 @@
buf_page_t* bpage;
ulint i;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
+ rw_lock_x_lock(&buf_pool->page_hash_latch);
bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
-+ if (bpage) {
-+ block_mutex = buf_page_get_mutex_enter(bpage);
-+ ut_a(block_mutex);
-+ }
if (UNIV_LIKELY_NULL(bpage)) {
++
++ block_mutex = buf_page_get_mutex_enter(bpage);
++ ut_a(block_mutex);
++
if (!buf_pool_watch_is_sentinel(buf_pool, bpage)) {
/* The page was loaded meanwhile. */
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
for (i = 0; i < BUF_POOL_WATCH_SIZE; i++) {
bpage = &buf_pool->watch[i];
-@@ -1891,10 +1945,12 @@
+@@ -1525,10 +1568,12 @@
bpage->space = space;
bpage->offset = offset;
bpage->buf_fix_count = 1;
return(NULL);
case BUF_BLOCK_ZIP_PAGE:
ut_ad(bpage->in_page_hash);
-@@ -1912,6 +1968,8 @@
+@@ -1546,6 +1591,8 @@
ut_error;
/* Fix compiler warning */
return(NULL);
}
-@@ -1941,6 +1999,8 @@
- buf_chunk_t* chunks;
- buf_chunk_t* chunk;
-
-+ mutex_enter(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_lock(&buf_pool->page_hash_latch);
- buf_pool_mutex_enter(buf_pool);
- chunks = mem_alloc((buf_pool->n_chunks + 1) * sizeof *chunks);
-
-@@ -1959,6 +2019,8 @@
- buf_pool->n_chunks++;
- }
-
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
- buf_pool_mutex_exit(buf_pool);
- }
-
-@@ -2046,7 +2108,11 @@
+@@ -1563,7 +1610,11 @@
space, offset) */
buf_page_t* watch) /*!< in/out: sentinel for watch */
{
HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, watch);
ut_d(watch->in_page_hash = FALSE);
-@@ -2068,28 +2134,31 @@
+@@ -1585,28 +1636,31 @@
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ulint fold = buf_page_address_fold(space, offset);
}
/****************************************************************//**
-@@ -2109,14 +2178,16 @@
+@@ -1626,14 +1680,16 @@
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ulint fold = buf_page_address_fold(space, offset);
return(ret);
}
-@@ -2133,13 +2204,15 @@
+@@ -1650,13 +1706,15 @@
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
}
/********************************************************************//**
-@@ -2163,14 +2236,20 @@
+@@ -1680,14 +1738,20 @@
ut_a(buf_page_in_file(bpage));
if (buf_page_peek_if_too_old(bpage)) {
}
}
-@@ -2187,7 +2266,8 @@
+@@ -1704,7 +1768,8 @@
buf_block_t* block;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset);
-@@ -2196,7 +2276,8 @@
+@@ -1713,7 +1778,8 @@
block->check_index_page_at_flush = FALSE;
}
+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
}
- /********************************************************************//**
-@@ -2215,7 +2296,8 @@
- ibool is_hashed;
- buf_pool_t* buf_pool = buf_pool_get(space, offset);
-
-- buf_pool_mutex_enter(buf_pool);
-+ //buf_pool_mutex_enter(buf_pool);
-+ rw_lock_s_lock(&buf_pool->page_hash_latch);
-
- block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset);
-
-@@ -2226,7 +2308,8 @@
- is_hashed = block->is_hashed;
- }
-
-- buf_pool_mutex_exit(buf_pool);
-+ //buf_pool_mutex_exit(buf_pool);
-+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
-
- return(is_hashed);
- }
-@@ -2248,7 +2331,8 @@
+ #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
+@@ -1733,7 +1799,8 @@
buf_page_t* bpage;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
bpage = buf_page_hash_get(buf_pool, space, offset);
-@@ -2259,7 +2343,8 @@
+@@ -1744,7 +1811,8 @@
bpage->file_page_was_freed = TRUE;
}
return(bpage);
}
-@@ -2280,7 +2365,8 @@
+@@ -1765,7 +1833,8 @@
buf_page_t* bpage;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
bpage = buf_page_hash_get(buf_pool, space, offset);
-@@ -2289,7 +2375,8 @@
+@@ -1774,7 +1843,8 @@
bpage->file_page_was_freed = FALSE;
}
return(bpage);
}
-@@ -2321,8 +2408,9 @@
+@@ -1806,8 +1876,9 @@
buf_pool->stat.n_page_gets++;
for (;;) {
bpage = buf_page_hash_get(buf_pool, space, offset);
if (bpage) {
ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
-@@ -2331,7 +2419,8 @@
+@@ -1816,7 +1887,8 @@
/* Page not in buf_pool: needs to be read from file */
buf_read_page(space, zip_size, offset);
-@@ -2343,10 +2432,15 @@
+@@ -1828,10 +1900,15 @@
if (UNIV_UNLIKELY(!bpage->zip.data)) {
/* There is no compressed page. */
err_exit:
ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
switch (buf_page_get_state(bpage)) {
-@@ -2355,19 +2449,19 @@
+@@ -1840,24 +1917,43 @@
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
case BUF_BLOCK_ZIP_FREE:
goto got_block;
case BUF_BLOCK_FILE_PAGE:
- block_mutex = &((buf_block_t*) bpage)->mutex;
-- mutex_enter(block_mutex);
+ 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);
+ mutex_enter(block_mutex);
- /* Discard the uncompressed page frame if possible. */
-- if (buf_LRU_free_block(bpage, FALSE) == BUF_LRU_FREED) {
-+ if (buf_LRU_free_block(bpage, FALSE, FALSE) == BUF_LRU_FREED) {
+- /* Discard the uncompressed page frame if possible. */
+- if (buf_LRU_free_block(bpage, FALSE)) {
++ 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);
++ 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);
mutex_exit(block_mutex);
goto lookup;
-@@ -2385,7 +2479,7 @@
+ }
+
++ mutex_exit(&buf_pool->LRU_list_mutex);
++
+ buf_block_buf_fix_inc((buf_block_t*) bpage,
+ __FILE__, __LINE__);
+ goto got_block;
+@@ -1870,7 +1966,7 @@
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
access_time = buf_page_is_accessed(bpage);
mutex_exit(block_mutex);
-@@ -2697,7 +2791,7 @@
+@@ -2181,7 +2277,7 @@
const buf_block_t* block) /*!< in: pointer to block,
not dereferenced */
{
if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
/* The pointer should be aligned. */
-@@ -2733,6 +2827,7 @@
+@@ -2217,6 +2313,7 @@
ulint fix_type;
ibool must_read;
ulint retries = 0;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ut_ad(mtr);
-@@ -2765,9 +2860,11 @@
+@@ -2250,18 +2347,24 @@
fold = buf_page_address_fold(space, offset);
loop:
block = guess;
+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
+
/* If the guess is a compressed page descriptor that
- has been allocated by buf_buddy_alloc(), it may have
- been invalidated by buf_buddy_relocate(). In that
-@@ -2776,11 +2873,15 @@
- the guess may be pointing to a buffer pool chunk that
- has been released when resizing the buffer pool. */
+ has been allocated by buf_page_alloc_descriptor(),
+ it may have been freed by buf_relocate(). */
- if (!buf_block_is_uncompressed(buf_pool, block)
+ if (!block_mutex) {
block = guess = NULL;
} else {
ut_ad(!block->page.in_zip_hash);
-@@ -2789,12 +2890,19 @@
+@@ -2270,12 +2373,19 @@
}
if (block == NULL) {
block = NULL;
}
-@@ -2806,12 +2914,14 @@
+@@ -2287,12 +2397,14 @@
space, offset, fold);
if (UNIV_LIKELY_NULL(block)) {
if (mode == BUF_GET_IF_IN_POOL
|| mode == BUF_PEEK_IF_IN_POOL
-@@ -2861,7 +2971,8 @@
+@@ -2345,7 +2457,8 @@
/* The page is being read to buffer pool,
but we cannot wait around for the read to
complete. */
return(NULL);
}
-@@ -2871,38 +2982,49 @@
+@@ -2355,38 +2468,49 @@
ibool success;
case BUF_BLOCK_FILE_PAGE:
{
buf_page_t* hash_bpage;
-@@ -2915,35 +3037,47 @@
+@@ -2399,35 +2523,47 @@
while buf_pool->mutex was released.
Free the block that was allocated. */
buf_block_init_low(block);
block->lock_hash_val = lock_rec_hash(space, offset);
-@@ -2952,7 +3086,7 @@
-
+@@ -2437,7 +2573,7 @@
if (buf_page_get_state(&block->page)
== BUF_BLOCK_ZIP_PAGE) {
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- UT_LIST_REMOVE(list, buf_pool->zip_clean,
+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean,
&block->page);
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
ut_ad(!block->page.in_flush_list);
- } else {
-@@ -2969,20 +3103,25 @@
+@@ -2455,18 +2591,23 @@
/* Insert at the front of unzip_LRU list */
buf_unzip_LRU_add_block(block, FALSE);
- mutex_exit(&block->mutex);
+ mutex_exit(block_mutex);
mutex_exit(&buf_pool->zip_mutex);
-+
-+ buf_pool_mutex_enter(buf_pool);
- buf_pool->n_pend_unzip++;
-+ buf_pool_mutex_exit(buf_pool);
+- buf_pool->n_pend_unzip++;
- bpage->state = BUF_BLOCK_ZIP_FREE;
-- buf_buddy_free(buf_pool, bpage, sizeof *bpage);
-+ buf_buddy_free(buf_pool, bpage, sizeof *bpage, FALSE);
++ buf_pool_mutex_enter(buf_pool);
++ buf_pool->n_pend_unzip++;
+ buf_pool_mutex_exit(buf_pool);
-- buf_pool_mutex_exit(buf_pool);
+ //buf_pool_mutex_exit(buf_pool);
++
+ buf_page_free_descriptor(bpage);
/* Decompress the page and apply buffered operations
- while not holding buf_pool->mutex or block->mutex. */
-@@ -2995,12 +3134,15 @@
+@@ -2480,12 +2621,15 @@
}
/* Unfix and unlatch the block. */
rw_lock_x_unlock(&block->lock);
break;
-@@ -3016,7 +3158,7 @@
+@@ -2501,7 +2645,7 @@
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#if UNIV_WORD_SIZE == 4
/* On 32-bit systems, there is no padding in buf_page_t. On
other systems, Valgrind could complain about uninitialized pad
-@@ -3029,8 +3171,8 @@
+@@ -2514,8 +2658,8 @@
/* Try to evict the block from the buffer pool, to use the
insert buffer (change buffer) as much as possible. */
-- if (buf_LRU_free_block(&block->page, TRUE) == BUF_LRU_FREED) {
+- if (buf_LRU_free_block(&block->page, TRUE)) {
- mutex_exit(&block->mutex);
-+ if (buf_LRU_free_block(&block->page, TRUE, FALSE) == BUF_LRU_FREED) {
++ if (buf_LRU_free_block(&block->page, TRUE, FALSE)) {
+ mutex_exit(block_mutex);
if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
/* Set the watch, as it would have
been set if the page were not in the
-@@ -3039,6 +3181,9 @@
+@@ -2524,6 +2668,9 @@
space, offset, fold);
if (UNIV_LIKELY_NULL(block)) {
/* The page entered the buffer
pool for some reason. Try to
-@@ -3046,7 +3191,7 @@
+@@ -2531,7 +2678,7 @@
goto got_block;
}
}
fprintf(stderr,
"innodb_change_buffering_debug evict %u %u\n",
(unsigned) space, (unsigned) offset);
-@@ -3065,13 +3210,14 @@
-
- buf_block_buf_fix_inc(block, file, line);
-
+@@ -2553,13 +2700,14 @@
+ ut_a(mode == BUF_GET_POSSIBLY_FREED
+ || !block->page.file_page_was_freed);
+ #endif
- mutex_exit(&block->mutex);
+ //mutex_exit(&block->mutex);
if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
buf_page_set_accessed_make_young(&block->page, access_time);
-@@ -3308,9 +3454,11 @@
+@@ -2792,9 +2940,11 @@
buf_pool = buf_pool_from_block(block);
if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
} else if (!buf_page_is_accessed(&block->page)) {
/* Above, we do a dirty read on purpose, to avoid
mutex contention. The field buf_page_t::access_time
-@@ -3318,9 +3466,11 @@
+@@ -2802,9 +2952,11 @@
field must be protected by mutex, however. */
ulint time_ms = ut_time_ms();
}
ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
-@@ -3387,18 +3537,21 @@
+@@ -2871,18 +3023,21 @@
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
-@@ -3487,7 +3640,10 @@
+@@ -2972,7 +3127,10 @@
buf_page_t* hash_page;
- buf_pool_t* buf_pool = buf_pool_get(space, offset);
+ ut_ad(buf_pool == buf_pool_get(space, offset));
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
+#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(block->mutex)));
ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
-@@ -3516,11 +3672,14 @@
+@@ -3001,11 +3159,14 @@
if (UNIV_LIKELY(!hash_page)) {
} else if (buf_pool_watch_is_sentinel(buf_pool, hash_page)) {
/* Preserve the reference count. */
} else {
fprintf(stderr,
"InnoDB: Error: page %lu %lu already found"
-@@ -3530,7 +3689,8 @@
+@@ -3015,7 +3176,8 @@
(const void*) hash_page, (const void*) block);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
mutex_exit(&block->mutex);
buf_print();
buf_LRU_print();
buf_validate();
-@@ -3613,7 +3773,9 @@
+@@ -3098,7 +3260,9 @@
fold = buf_page_address_fold(space, offset);
watch_page = buf_page_hash_get_low(buf_pool, space, offset, fold);
if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) {
-@@ -3622,9 +3784,15 @@
+@@ -3107,9 +3271,15 @@
err_exit:
if (block) {
mutex_enter(&block->mutex);
bpage = NULL;
goto func_exit;
-@@ -3647,6 +3815,8 @@
+@@ -3132,6 +3302,8 @@
- buf_page_init(space, offset, fold, block);
+ buf_page_init(buf_pool, space, offset, fold, block);
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
+
/* The block must be put to the LRU list, to the old blocks */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
-@@ -3674,7 +3844,7 @@
+@@ -3159,7 +3331,7 @@
been added to buf_pool->LRU and
buf_pool->page_hash. */
mutex_exit(&block->mutex);
mutex_enter(&block->mutex);
block->page.zip.data = data;
-@@ -3687,6 +3857,7 @@
+@@ -3172,13 +3344,14 @@
buf_unzip_LRU_add_block(block, TRUE);
}
+ mutex_exit(&buf_pool->LRU_list_mutex);
mutex_exit(&block->mutex);
} else {
- /* Defer buf_buddy_alloc() until after the block has
-@@ -3698,8 +3869,8 @@
+ /* The compressed page must be allocated before the
control block (bpage), in order to avoid the
invocation of buf_buddy_relocate_block() on
uninitialized data. */
- data = buf_buddy_alloc(buf_pool, zip_size, &lru);
-- bpage = buf_buddy_alloc(buf_pool, sizeof *bpage, &lru);
+ data = buf_buddy_alloc(buf_pool, zip_size, &lru, TRUE);
-+ bpage = buf_buddy_alloc(buf_pool, sizeof *bpage, &lru, TRUE);
- /* Initialize the buf_pool pointer. */
- bpage->buf_pool_index = buf_pool_index(buf_pool);
-@@ -3719,8 +3890,11 @@
+ /* If buf_buddy_alloc() allocated storage from the LRU list,
+ it released and reacquired buf_pool->mutex. Thus, we must
+@@ -3194,7 +3367,10 @@
+
/* The block was added by some other thread. */
watch_page = NULL;
- bpage->state = BUF_BLOCK_ZIP_FREE;
-- buf_buddy_free(buf_pool, bpage, sizeof *bpage);
- buf_buddy_free(buf_pool, data, zip_size);
-+ buf_buddy_free(buf_pool, bpage, sizeof *bpage, TRUE);
+ buf_buddy_free(buf_pool, data, zip_size, TRUE);
+
+ mutex_exit(&buf_pool->LRU_list_mutex);
bpage = NULL;
goto func_exit;
-@@ -3764,18 +3938,24 @@
+@@ -3242,20 +3418,26 @@
HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold,
bpage);
+
/* The block must be put to the LRU list, to the old blocks */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(bpage);
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
+ mutex_exit(&buf_pool->LRU_list_mutex);
+
if (mode == BUF_READ_IBUF_PAGES_ONLY) {
-@@ -3817,7 +3997,9 @@
+@@ -3297,7 +3479,9 @@
fold = buf_page_address_fold(space, offset);
block = (buf_block_t*) buf_page_hash_get_low(
buf_pool, space, offset, fold);
-@@ -3833,7 +4015,9 @@
+@@ -3313,7 +3497,9 @@
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/* Page can be found in buf_pool */
buf_block_free(free_block);
-@@ -3855,6 +4039,7 @@
+@@ -3335,6 +3521,7 @@
mutex_enter(&block->mutex);
- buf_page_init(space, offset, fold, block);
+ buf_page_init(buf_pool, space, offset, fold, block);
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
/* The block must be put to the LRU list */
buf_LRU_add_block(&block->page, FALSE);
-@@ -3881,7 +4066,7 @@
+@@ -3361,7 +3548,7 @@
the reacquisition of buf_pool->mutex. We also must
defer this operation until after the block descriptor
has been added to buf_pool->LRU and buf_pool->page_hash. */
mutex_enter(&block->mutex);
block->page.zip.data = data;
-@@ -3899,7 +4084,8 @@
+@@ -3379,7 +3566,8 @@
buf_page_set_accessed(&block->page, time_ms);
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
-@@ -3950,6 +4136,8 @@
+@@ -3434,7 +3622,9 @@
+ ibool ret = TRUE;
+
+ /* First unfix and release lock on the bpage */
+- buf_pool_mutex_enter(buf_pool);
++ //buf_pool_mutex_enter(buf_pool);
++ mutex_enter(&buf_pool->LRU_list_mutex);
++ rw_lock_x_lock(&buf_pool->page_hash_latch);
+ mutex_enter(buf_page_get_mutex(bpage));
+ ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ);
+ ut_ad(bpage->buf_fix_count == 0);
+@@ -3455,11 +3645,15 @@
+ ret = FALSE;
+ }
+
++ buf_pool_mutex_enter(buf_pool);
+ ut_ad(buf_pool->n_pend_reads > 0);
+ buf_pool->n_pend_reads--;
++ buf_pool_mutex_exit(buf_pool);
+
+ mutex_exit(buf_page_get_mutex(bpage));
+- buf_pool_mutex_exit(buf_pool);
++ //buf_pool_mutex_exit(buf_pool);
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ rw_lock_x_unlock(&buf_pool->page_hash_latch);
+
+ return(ret);
+ }
+@@ -3477,6 +3671,8 @@
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
const ibool uncompressed = (buf_page_get_state(bpage)
== BUF_BLOCK_FILE_PAGE);
ut_a(buf_page_in_file(bpage));
-@@ -4083,8 +4271,26 @@
+@@ -3619,8 +3815,26 @@
}
}
#ifdef UNIV_IBUF_COUNT_DEBUG
if (io_type == BUF_IO_WRITE || uncompressed) {
-@@ -4107,6 +4313,7 @@
+@@ -3643,6 +3857,7 @@
the x-latch to this OS thread: do not let this confuse you in
debugging! */
ut_ad(buf_pool->n_pend_reads > 0);
buf_pool->n_pend_reads--;
buf_pool->stat.n_pages_read++;
-@@ -4124,6 +4331,9 @@
+@@ -3660,6 +3875,9 @@
buf_flush_write_complete(bpage);
if (uncompressed) {
rw_lock_s_unlock_gen(&((buf_block_t*) bpage)->lock,
BUF_IO_WRITE);
-@@ -4146,8 +4356,8 @@
+@@ -3682,8 +3900,8 @@
}
#endif /* UNIV_DEBUG */
}
/*********************************************************************//**
-@@ -4164,7 +4374,9 @@
+@@ -3700,7 +3918,9 @@
ut_ad(buf_pool);
chunk = buf_pool->chunks;
-@@ -4181,7 +4393,9 @@
+@@ -3717,7 +3937,9 @@
}
}
return(TRUE);
}
-@@ -4229,7 +4443,8 @@
+@@ -3765,7 +3987,8 @@
freed = buf_LRU_search_and_free_block(buf_pool, 100);
}
ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
-@@ -4242,7 +4457,8 @@
+@@ -3778,7 +4001,8 @@
memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
buf_refresh_io_stats(buf_pool);
}
/*********************************************************************//**
-@@ -4284,7 +4500,10 @@
+@@ -3820,7 +4044,10 @@
ut_ad(buf_pool);
chunk = buf_pool->chunks;
-@@ -4379,7 +4598,7 @@
+@@ -3918,7 +4145,7 @@
/* Check clean compressed-only blocks. */
for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
switch (buf_page_get_io_fix(b)) {
case BUF_IO_NONE:
-@@ -4410,7 +4629,7 @@
+@@ -3950,7 +4177,7 @@
buf_flush_list_mutex_enter(buf_pool);
for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
ut_ad(b->in_flush_list);
ut_a(b->oldest_modification);
n_flush++;
-@@ -4469,6 +4688,8 @@
+@@ -4010,6 +4237,8 @@
}
ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru);
if (UT_LIST_GET_LEN(buf_pool->free) != n_free) {
fprintf(stderr, "Free list len %lu, free blocks %lu\n",
(ulong) UT_LIST_GET_LEN(buf_pool->free),
-@@ -4479,8 +4700,11 @@
+@@ -4020,8 +4249,11 @@
ut_a(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE] == n_single_flush);
ut_a(buf_pool->n_flush[BUF_FLUSH_LIST] == n_list_flush);
ut_a(buf_pool->n_flush[BUF_FLUSH_LRU] == n_lru_flush);
ut_a(buf_LRU_validate());
ut_a(buf_flush_validate(buf_pool));
-@@ -4536,7 +4760,9 @@
+@@ -4077,7 +4309,9 @@
index_ids = mem_alloc(size * sizeof *index_ids);
counts = mem_alloc(sizeof(ulint) * size);
buf_flush_list_mutex_enter(buf_pool);
fprintf(stderr,
-@@ -4605,7 +4831,9 @@
+@@ -4146,7 +4380,9 @@
}
}
for (i = 0; i < n_found; i++) {
index = dict_index_get_if_in_cache(index_ids[i]);
-@@ -4662,7 +4890,7 @@
+@@ -4203,7 +4439,7 @@
buf_chunk_t* chunk;
ulint fixed_pages_number = 0;
chunk = buf_pool->chunks;
-@@ -4696,7 +4924,7 @@
+@@ -4237,7 +4473,7 @@
/* Traverse the lists of clean and dirty compressed-only blocks. */
for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
ut_a(buf_page_get_io_fix(b) != BUF_IO_WRITE);
-@@ -4708,7 +4936,7 @@
+@@ -4249,7 +4485,7 @@
buf_flush_list_mutex_enter(buf_pool);
for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
ut_ad(b->in_flush_list);
switch (buf_page_get_state(b)) {
-@@ -4734,7 +4962,7 @@
+@@ -4275,7 +4511,7 @@
buf_flush_list_mutex_exit(buf_pool);
mutex_exit(&buf_pool->zip_mutex);
return(fixed_pages_number);
}
-@@ -4890,6 +5118,8 @@
+@@ -4433,6 +4669,8 @@
/* Find appropriate pool_info to store stats for this buffer pool */
pool_info = &all_pool_info[pool_id];
buf_pool_mutex_enter(buf_pool);
buf_flush_list_mutex_enter(buf_pool);
-@@ -5000,6 +5230,8 @@
+@@ -4548,6 +4786,8 @@
pool_info->unzip_cur = buf_LRU_stat_cur.unzip;
buf_refresh_io_stats(buf_pool);
buf_pool_mutex_exit(buf_pool);
}
-@@ -5241,11 +5473,13 @@
+@@ -4792,11 +5032,13 @@
{
ulint len;
return(len);
}
-diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
---- a/storage/innobase/buf/buf0flu.c 2010-12-03 15:22:36.318955693 +0900
-+++ b/storage/innobase/buf/buf0flu.c 2010-12-03 15:48:29.289024083 +0900
+--- a/storage/innobase/buf/buf0flu.c
++++ b/storage/innobase/buf/buf0flu.c
@@ -307,7 +307,7 @@
ut_d(block->page.in_flush_list = TRUE);
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
ut_ad(bpage->in_flush_list);
-@@ -526,11 +526,11 @@
+@@ -526,13 +526,13 @@
return;
case BUF_BLOCK_ZIP_DIRTY:
buf_page_set_state(bpage, BUF_BLOCK_ZIP_PAGE);
- UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
+ UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(bpage);
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
break;
case BUF_BLOCK_FILE_PAGE:
- UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
break;
}
-@@ -574,7 +574,7 @@
+@@ -576,7 +576,7 @@
buf_page_t* prev_b = NULL;
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
/* Must reside in the same buffer pool. */
ut_ad(buf_pool == buf_pool_from_bpage(dpage));
-@@ -603,18 +603,18 @@
+@@ -605,18 +605,18 @@
because we assert on in_flush_list in comparison function. */
ut_d(bpage->in_flush_list = FALSE);
buf_pool->flush_list,
dpage);
}
-@@ -1083,7 +1083,7 @@
+@@ -1085,7 +1085,7 @@
#ifdef UNIV_DEBUG
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
#endif
#ifdef UNIV_LOG_DEBUG
-@@ -1097,7 +1097,8 @@
+@@ -1099,7 +1099,8 @@
io_fixed and oldest_modification != 0. Thus, it cannot be
relocated in the buffer pool or removed from flush_list or
LRU_list. */
ut_ad(!buf_flush_list_mutex_own(buf_pool));
ut_ad(!mutex_own(buf_page_get_mutex(bpage)));
ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_WRITE);
-@@ -1177,7 +1178,7 @@
+@@ -1179,7 +1180,7 @@
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
buf_block_t* block) /*!< in/out: buffer control block */
{
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
ut_ad(mutex_own(&block->mutex));
-@@ -1185,8 +1186,11 @@
+@@ -1187,8 +1188,11 @@
return(FALSE);
}
/* There is already a flush batch of the same type running */
return(FALSE);
}
-@@ -1260,12 +1264,18 @@
+@@ -1262,12 +1266,18 @@
ibool is_uncompressed;
ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
ut_ad(buf_flush_ready_for_flush(bpage, flush_type));
buf_page_set_io_fix(bpage, BUF_IO_WRITE);
-@@ -1427,14 +1437,16 @@
+@@ -1455,14 +1465,16 @@
buf_pool = buf_pool_get(space, i);
- buf_pool_mutex_exit(buf_pool);
+ //buf_pool_mutex_exit(buf_pool);
+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
- continue;
- }
+ if (srv_flush_neighbor_pages == 2) {
-@@ -1446,11 +1458,9 @@
+ /* This is contiguous neighbor page flush and
+@@ -1480,11 +1492,9 @@
if (flush_type != BUF_FLUSH_LRU
|| i == offset
|| buf_page_is_old(bpage)) {
&& (i == offset || !bpage->buf_fix_count)) {
/* We only try to flush those
neighbors != offset where the buf fix
-@@ -1466,11 +1476,12 @@
+@@ -1500,11 +1510,12 @@
ut_ad(!buf_pool_mutex_own(buf_pool));
count++;
continue;
- buf_pool_mutex_exit(buf_pool);
+ //buf_pool_mutex_exit(buf_pool);
+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
- }
- return(count);
-@@ -1503,21 +1514,25 @@
+ if (srv_flush_neighbor_pages == 2) {
+
+@@ -1553,21 +1564,25 @@
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
#endif /* UNIV_DEBUG */
/* These fields are protected by both the
buffer pool mutex and block mutex. */
-@@ -1533,13 +1548,18 @@
+@@ -1583,13 +1598,18 @@
*count,
n_to_flush);
return(flushed);
}
-@@ -1560,7 +1580,8 @@
+@@ -1610,7 +1630,8 @@
buf_page_t* bpage;
ulint count = 0;
do {
/* Start from the end of the list looking for a
-@@ -1582,7 +1603,8 @@
+@@ -1632,7 +1653,8 @@
should be flushed, we factor in this value. */
buf_lru_flush_page_count += count;
return(count);
}
-@@ -1610,9 +1632,10 @@
+@@ -1660,9 +1682,10 @@
{
ulint len;
buf_page_t* bpage;
/* If we have flushed enough, leave the loop */
do {
-@@ -1631,6 +1654,7 @@
+@@ -1681,6 +1704,7 @@
if (bpage) {
ut_a(bpage->oldest_modification > 0);
}
if (!bpage || bpage->oldest_modification >= lsn_limit) {
-@@ -1672,9 +1696,17 @@
+@@ -1722,9 +1746,17 @@
break;
}
buf_flush_list_mutex_exit(buf_pool);
-@@ -1683,7 +1715,7 @@
+@@ -1733,7 +1765,7 @@
} while (count < min_n && bpage != NULL && len > 0);
return(count);
}
-@@ -1722,13 +1754,15 @@
+@@ -1772,13 +1804,15 @@
|| sync_thread_levels_empty_except_dict());
#endif /* UNIV_SYNC_DEBUG */
break;
case BUF_FLUSH_LIST:
count = buf_flush_flush_list_batch(buf_pool, min_n, lsn_limit);
-@@ -1737,7 +1771,7 @@
+@@ -1787,7 +1821,7 @@
ut_error;
}
buf_flush_buffered_writes();
-@@ -1993,7 +2027,7 @@
+@@ -2059,7 +2093,7 @@
retry:
//buf_pool_mutex_enter(buf_pool);
if (have_LRU_mutex)
n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
-@@ -2010,15 +2044,15 @@
+@@ -2076,15 +2110,15 @@
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
continue;
}
distance++;
-@@ -2027,7 +2061,7 @@
+@@ -2093,7 +2127,7 @@
//buf_pool_mutex_exit(buf_pool);
if (have_LRU_mutex)
if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN(buf_pool)) {
-@@ -2226,7 +2260,7 @@
+@@ -2292,7 +2326,7 @@
ut_ad(buf_flush_list_mutex_own(buf_pool));
ut_ad(ut_list_node_313->in_flush_list));
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
-@@ -2266,7 +2300,7 @@
+@@ -2332,7 +2366,7 @@
rnode = rbt_next(buf_pool->flush_rbt, rnode);
}
ut_a(!bpage || om >= bpage->oldest_modification);
}
-diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
---- a/storage/innobase/buf/buf0lru.c 2010-12-03 15:22:36.321987250 +0900
-+++ b/storage/innobase/buf/buf0lru.c 2010-12-03 15:48:29.293023197 +0900
-@@ -143,8 +143,9 @@
+--- a/storage/innobase/buf/buf0lru.c
++++ b/storage/innobase/buf/buf0lru.c
+@@ -147,8 +147,9 @@
void
buf_LRU_block_free_hashed_page(
/*===========================*/
/******************************************************************//**
Determines if the unzip_LRU list should be used for evicting a victim
-@@ -154,15 +155,20 @@
+@@ -158,15 +159,20 @@
ibool
buf_LRU_evict_from_unzip_LRU(
/*=========================*/
return(FALSE);
}
-@@ -171,14 +177,20 @@
+@@ -175,14 +181,20 @@
decompressed pages in the buffer pool. */
if (UT_LIST_GET_LEN(buf_pool->unzip_LRU)
<= UT_LIST_GET_LEN(buf_pool->LRU) / 10) {
/* Calculate the average over past intervals, and add the values
of the current interval. */
-@@ -246,18 +258,25 @@
+@@ -250,18 +262,25 @@
page_arr = ut_malloc(
- sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE);
+ sizeof(ulint) * BUF_LRU_DROP_SEARCH_SIZE);
- buf_pool_mutex_enter(buf_pool);
+ //buf_pool_mutex_enter(buf_pool);
ut_a(buf_page_in_file(bpage));
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
-@@ -266,23 +285,27 @@
+@@ -270,24 +289,30 @@
/* Compressed pages are never hashed.
Skip blocks of other tablespaces.
Skip I/O-fixed blocks (to be dealt with later). */
- mutex_enter(&((buf_block_t*) bpage)->mutex);
+ //mutex_enter(&((buf_block_t*) bpage)->mutex);
is_fixed = bpage->buf_fix_count > 0
- || !((buf_block_t*) bpage)->is_hashed;
+ || !((buf_block_t*) bpage)->index;
- mutex_exit(&((buf_block_t*) bpage)->mutex);
+ //mutex_exit(&((buf_block_t*) bpage)->mutex);
/* Store the page number so that we can drop the hash
index in a batch later. */
page_arr[num_entries] = bpage->offset;
++
+ mutex_exit(block_mutex);
+
- ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
+ ut_a(num_entries < BUF_LRU_DROP_SEARCH_SIZE);
++
++num_entries;
-@@ -292,14 +315,16 @@
+ if (num_entries < BUF_LRU_DROP_SEARCH_SIZE) {
+@@ -296,14 +321,16 @@
/* Array full. We release the buf_pool->mutex to obey
the latching order. */
/* Note that we released the buf_pool mutex above
after reading the prev_bpage during processing of a
-@@ -317,13 +342,23 @@
+@@ -321,13 +348,23 @@
/* If, however, bpage has been removed from LRU list
to the free list then we should restart the scan.
bpage->state is protected by buf_pool mutex. */
/* Drop any remaining batch of search hashed pages. */
buf_LRU_drop_page_hash_batch(id, zip_size, page_arr, num_entries);
-@@ -345,7 +380,9 @@
- ibool all_freed;
+@@ -351,7 +388,9 @@
+ ulint i;
scan_again:
- buf_pool_mutex_enter(buf_pool);
+ //buf_pool_mutex_enter(buf_pool);
+ mutex_enter(&buf_pool->LRU_list_mutex);
+ rw_lock_x_lock(&buf_pool->page_hash_latch);
+ buf_flush_list_mutex_enter(buf_pool);
all_freed = TRUE;
+@@ -364,7 +403,7 @@
-@@ -373,8 +410,16 @@
+ ut_a(buf_page_in_file(bpage));
- all_freed = FALSE;
- } else {
-- mutex_t* block_mutex = buf_page_get_mutex(bpage);
-- mutex_enter(block_mutex);
-+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
-+
-+ if (!block_mutex) {
-+ /* It may be impossible case...
-+ Something wrong, so will be scan_again */
-+
-+ all_freed = FALSE;
-+
-+ goto next_page_no_mutex;
-+ }
+- prev_bpage = UT_LIST_GET_PREV(list, bpage);
++ prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
- if (bpage->buf_fix_count > 0) {
+ /* bpage->space and bpage->io_fix are protected by
+ buf_pool->mutex and block_mutex. It is safe to check
+@@ -388,8 +427,14 @@
+ will stay in the flush_list because buf_flush_remove()
+ needs buf_pool->mutex as well. */
+ buf_flush_list_mutex_exit(buf_pool);
+- block_mutex = buf_page_get_mutex(bpage);
+- mutex_enter(block_mutex);
++ block_mutex = buf_page_get_mutex_enter(bpage);
++
++ if (!block_mutex) {
++ /* It may be impossible case...
++ Something wrong, so will be scan_again */
++ all_freed = FALSE;
++ goto next_page;
++ }
-@@ -433,7 +478,9 @@
- ulint page_no;
- ulint zip_size;
+ if (bpage->buf_fix_count > 0) {
+ mutex_exit(block_mutex);
+@@ -440,9 +485,15 @@
+ mutex_exit(block_mutex);
-- buf_pool_mutex_exit(buf_pool);
-+ //buf_pool_mutex_exit(buf_pool);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
+ /* Now it is safe to release the buf_pool->mutex. */
+- buf_pool_mutex_exit(buf_pool);
++ //buf_pool_mutex_exit(buf_pool);
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ rw_lock_x_unlock(&buf_pool->page_hash_latch);
++
+ os_thread_yield();
+- buf_pool_mutex_enter(buf_pool);
++ //buf_pool_mutex_enter(buf_pool);
++ mutex_enter(&buf_pool->LRU_list_mutex);
++ rw_lock_x_lock(&buf_pool->page_hash_latch);
++
- zip_size = buf_page_get_zip_size(bpage);
- page_no = buf_page_get_page_no(bpage);
-@@ -458,7 +505,7 @@
- if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
- != BUF_BLOCK_ZIP_FREE) {
- buf_LRU_block_free_hashed_page((buf_block_t*)
-- bpage);
-+ bpage, TRUE);
- } else {
- /* The block_mutex should have been
- released by buf_LRU_block_remove_hashed_page()
-@@ -490,7 +537,9 @@
- bpage = prev_bpage;
+ mutex_enter(block_mutex);
+ buf_page_unset_sticky(bpage);
+@@ -454,7 +505,9 @@
+ i = 0;
}
- buf_pool_mutex_exit(buf_pool);
-+ //buf_pool_mutex_exit(buf_pool);
++// buf_pool_mutex_exit(buf_pool);
+ mutex_exit(&buf_pool->LRU_list_mutex);
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
+ buf_flush_list_mutex_exit(buf_pool);
- if (!all_freed) {
- os_thread_sleep(20000);
-@@ -536,7 +585,9 @@
+ ut_ad(buf_flush_validate(buf_pool));
+@@ -504,7 +557,9 @@
buf_page_t* b;
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_PAGE);
/* Find the first successor of bpage in the LRU list
-@@ -544,17 +595,17 @@
+@@ -512,17 +567,17 @@
b = bpage;
do {
b = UT_LIST_GET_NEXT(LRU, b);
+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_clean, bpage);
}
}
-
-@@ -567,18 +618,19 @@
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
+@@ -536,18 +591,19 @@
buf_LRU_free_from_unzip_LRU_list(
/*=============================*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
/* Theoratically it should be much easier to find a victim
from unzip_LRU as we can choose even a dirty block (as we'll
-@@ -588,7 +640,7 @@
+@@ -557,7 +613,7 @@
if we have done five iterations so far. */
if (UNIV_UNLIKELY(n_iterations >= 5)
return(FALSE);
}
-@@ -596,18 +648,25 @@
+@@ -565,18 +621,25 @@
distance = 100 + (n_iterations
* UT_LIST_GET_LEN(buf_pool->unzip_LRU)) / 5;
UNIV_LIKELY(block != NULL) && UNIV_LIKELY(distance > 0);
block = UT_LIST_GET_PREV(unzip_LRU, block), distance--) {
- enum buf_lru_free_block_status freed;
+ ibool freed;
+ mutex_enter(&block->mutex);
+ if (!block->in_unzip_LRU_list || !block->page.in_LRU_list
+ freed = buf_LRU_free_block(&block->page, FALSE, have_LRU_mutex);
mutex_exit(&block->mutex);
- switch (freed) {
-@@ -641,21 +700,23 @@
+ if (freed) {
+@@ -595,35 +658,46 @@
buf_LRU_free_from_common_LRU_list(
/*==============================*/
buf_pool_t* buf_pool,
for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
UNIV_LIKELY(bpage != NULL) && UNIV_LIKELY(distance > 0);
bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
-@@ -663,14 +724,23 @@
- enum buf_lru_free_block_status freed;
- unsigned accessed;
- mutex_t* block_mutex
-- = buf_page_get_mutex(bpage);
-+ = buf_page_get_mutex_enter(bpage);
+
+ ibool freed;
+ unsigned accessed;
+- mutex_t* block_mutex = buf_page_get_mutex(bpage);
++ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
+
+ if (!block_mutex) {
+ goto restart;
+ freed = buf_LRU_free_block(bpage, TRUE, have_LRU_mutex);
mutex_exit(block_mutex);
- switch (freed) {
-@@ -722,16 +792,23 @@
+ if (freed) {
+@@ -660,16 +734,23 @@
n_iterations / 5 of the unzip_LRU list. */
{
ibool freed = FALSE;
if (!freed) {
buf_pool->LRU_flush_ended = 0;
} else if (buf_pool->LRU_flush_ended > 0) {
-@@ -739,6 +816,8 @@
+@@ -677,6 +758,8 @@
}
buf_pool_mutex_exit(buf_pool);
return(freed);
}
-@@ -799,7 +878,9 @@
+@@ -737,7 +820,9 @@
buf_pool = buf_pool_from_array(i);
if (!recv_recovery_on
&& UT_LIST_GET_LEN(buf_pool->free)
-@@ -809,7 +890,9 @@
+@@ -747,7 +832,9 @@
ret = TRUE;
}
}
return(ret);
-@@ -827,9 +910,10 @@
+@@ -765,9 +852,10 @@
{
buf_block_t* block;
if (block) {
-@@ -838,7 +922,9 @@
+@@ -776,7 +864,9 @@
ut_ad(!block->page.in_flush_list);
ut_ad(!block->page.in_LRU_list);
ut_a(!buf_page_in_file(&block->page));
mutex_enter(&block->mutex);
-@@ -848,6 +934,8 @@
+@@ -786,6 +876,8 @@
ut_ad(buf_pool_from_block(block) == buf_pool);
mutex_exit(&block->mutex);
}
return(block);
-@@ -870,7 +958,7 @@
+@@ -808,7 +900,7 @@
ibool mon_value_was = FALSE;
ibool started_monitor = FALSE;
loop:
if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->curr_size / 20) {
-@@ -938,7 +1026,7 @@
+@@ -876,7 +968,7 @@
/* If there is a block in the free list, take it */
block = buf_LRU_get_free_only(buf_pool);
if (block) {
ut_ad(buf_pool_from_block(block) == buf_pool);
-@@ -1038,7 +1126,8 @@
+@@ -976,7 +1068,8 @@
ulint new_len;
ut_a(buf_pool->LRU_old);
ut_ad(buf_pool->LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
ut_ad(buf_pool->LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
#if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
-@@ -1104,7 +1193,8 @@
+@@ -1042,7 +1135,8 @@
{
buf_page_t* bpage;
ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN);
/* We first initialize all blocks in the LRU list as old and then use
-@@ -1139,13 +1229,14 @@
+@@ -1077,13 +1171,14 @@
ut_ad(buf_pool);
ut_ad(bpage);
ut_ad(buf_page_in_file(bpage));
UT_LIST_REMOVE(unzip_LRU, buf_pool->unzip_LRU, block);
}
-@@ -1163,7 +1254,8 @@
+@@ -1101,7 +1196,8 @@
ut_ad(buf_pool);
ut_ad(bpage);
ut_a(buf_page_in_file(bpage));
-@@ -1240,12 +1332,13 @@
+@@ -1178,12 +1274,13 @@
ut_ad(buf_pool);
ut_ad(block);
if (old) {
UT_LIST_ADD_LAST(unzip_LRU, buf_pool->unzip_LRU, block);
-@@ -1266,7 +1359,8 @@
+@@ -1204,7 +1301,8 @@
ut_ad(buf_pool);
ut_ad(bpage);
ut_a(buf_page_in_file(bpage));
-@@ -1317,7 +1411,8 @@
+@@ -1255,7 +1353,8 @@
ut_ad(buf_pool);
ut_ad(bpage);
ut_a(buf_page_in_file(bpage));
ut_ad(!bpage->in_LRU_list);
-@@ -1396,7 +1491,8 @@
+@@ -1334,7 +1433,8 @@
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
if (bpage->old) {
buf_pool->stat.n_pages_made_young++;
-@@ -1436,17 +1532,18 @@
+@@ -1373,17 +1473,18 @@
buf_LRU_free_block(
/*===============*/
buf_page_t* bpage, /*!< in: block to be freed */
ut_ad(!bpage->in_flush_list == !bpage->oldest_modification);
#if UNIV_WORD_SIZE == 4
/* On 32-bit systems, there is no padding in buf_page_t. On
-@@ -1455,7 +1552,7 @@
+@@ -1392,7 +1493,7 @@
UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
#endif
+ if (!bpage->in_LRU_list || !block_mutex || !buf_page_can_relocate(bpage)) {
/* Do not free buffer-fixed or I/O-fixed blocks. */
- return(BUF_LRU_NOT_FREED);
-@@ -1487,15 +1584,15 @@
- If it cannot be allocated (without freeing a block
- from the LRU list), refuse to free bpage. */
+ return(FALSE);
+@@ -1426,7 +1527,7 @@
alloc:
-- buf_pool_mutex_exit_forbid(buf_pool);
-- b = buf_buddy_alloc(buf_pool, sizeof *b, NULL);
-- buf_pool_mutex_exit_allow(buf_pool);
-+ //buf_pool_mutex_exit_forbid(buf_pool);
-+ b = buf_buddy_alloc(buf_pool, sizeof *b, NULL, FALSE);
-+ //buf_pool_mutex_exit_allow(buf_pool);
-
- if (UNIV_UNLIKELY(!b)) {
- return(BUF_LRU_CANNOT_RELOCATE);
- }
-
+ b = buf_page_alloc_descriptor();
+ ut_a(b);
- memcpy(b, bpage, sizeof *b);
+ //memcpy(b, bpage, sizeof *b);
}
#ifdef UNIV_DEBUG
-@@ -1506,6 +1603,39 @@
+@@ -1437,6 +1538,39 @@
}
#endif /* UNIV_DEBUG */
+ if (!have_LRU_mutex)
+ mutex_exit(&buf_pool->LRU_list_mutex);
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
-+ return(BUF_LRU_NOT_FREED);
++ return(FALSE);
+ } else if (zip || !bpage->zip.data) {
+ if (bpage->oldest_modification)
+ goto not_freed;
if (buf_LRU_block_remove_hashed_page(bpage, zip)
!= BUF_BLOCK_ZIP_FREE) {
ut_a(bpage->buf_fix_count == 0);
-@@ -1522,6 +1652,10 @@
+@@ -1453,6 +1587,10 @@
ut_a(!hash_b);
b->state = b->oldest_modification
? BUF_BLOCK_ZIP_DIRTY
: BUF_BLOCK_ZIP_PAGE;
-@@ -1597,6 +1731,7 @@
+@@ -1528,6 +1666,7 @@
buf_LRU_add_block_low(b, buf_page_is_old(b));
}
+ mutex_enter(&buf_pool->zip_mutex);
if (b->state == BUF_BLOCK_ZIP_PAGE) {
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(b);
- } else {
-@@ -1612,9 +1747,12 @@
+@@ -1543,12 +1682,13 @@
+ /* Prevent buf_page_get_gen() from
+ decompressing the block while we release
buf_pool->mutex and block_mutex. */
- b->buf_fix_count++;
- b->io_fix = BUF_IO_READ;
-+ mutex_exit(&buf_pool->zip_mutex);
+- mutex_enter(&buf_pool->zip_mutex);
+ buf_page_set_sticky(b);
+ mutex_exit(&buf_pool->zip_mutex);
}
- buf_pool_mutex_exit(buf_pool);
mutex_exit(block_mutex);
/* Remove possible adaptive hash index on the page.
-@@ -1646,7 +1784,9 @@
+@@ -1580,7 +1720,9 @@
: BUF_NO_CHECKSUM_MAGIC);
}
mutex_enter(block_mutex);
if (b) {
-@@ -1656,13 +1796,17 @@
+@@ -1589,13 +1731,17 @@
mutex_exit(&buf_pool->zip_mutex);
}
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
}
- return(BUF_LRU_FREED);
-@@ -1674,13 +1818,14 @@
+ return(TRUE);
+@@ -1607,13 +1753,14 @@
void
buf_LRU_block_free_non_file_page(
/*=============================*/
ut_ad(mutex_own(&block->mutex));
switch (buf_block_get_state(block)) {
-@@ -1714,18 +1859,21 @@
+@@ -1647,18 +1794,21 @@
if (data) {
block->page.zip.data = NULL;
mutex_exit(&block->mutex);
UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
}
-@@ -1755,7 +1903,11 @@
+@@ -1688,7 +1838,11 @@
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
ut_ad(bpage);
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
-@@ -1863,7 +2015,9 @@
+@@ -1796,7 +1950,9 @@
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
mutex_exit(buf_page_get_mutex(bpage));
buf_print();
buf_LRU_print();
buf_validate();
-@@ -1884,18 +2038,18 @@
- ut_a(bpage->zip.data);
+@@ -1818,17 +1974,17 @@
ut_a(buf_page_get_zip_size(bpage));
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, bpage);
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
mutex_exit(&buf_pool->zip_mutex);
- buf_pool_mutex_exit_forbid(buf_pool);
- page_zip_get_size(&bpage->zip));
+ page_zip_get_size(&bpage->zip), TRUE);
- bpage->state = BUF_BLOCK_ZIP_FREE;
-- buf_buddy_free(buf_pool, bpage, sizeof(*bpage));
- buf_pool_mutex_exit_allow(buf_pool);
-+ buf_buddy_free(buf_pool, bpage, sizeof(*bpage), TRUE);
+ //buf_pool_mutex_exit_allow(buf_pool);
-
- UNIV_MEM_UNDESC(bpage);
+ buf_page_free_descriptor(bpage);
return(BUF_BLOCK_ZIP_FREE);
-@@ -1918,13 +2072,13 @@
+
+@@ -1850,13 +2006,13 @@
ut_ad(!bpage->in_flush_list);
ut_ad(!bpage->in_LRU_list);
mutex_exit(&((buf_block_t*) bpage)->mutex);
mutex_enter(&((buf_block_t*) bpage)->mutex);
page_zip_set_size(&bpage->zip, 0);
}
-@@ -1950,18 +2104,19 @@
+@@ -1882,18 +2038,19 @@
void
buf_LRU_block_free_hashed_page(
/*===========================*/
+ buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
}
- /**********************************************************************//**
-@@ -1988,7 +2143,8 @@
+ /******************************************************************//**
+@@ -1908,7 +2065,7 @@
+ {
+ if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
+ != BUF_BLOCK_ZIP_FREE) {
+- buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
++ buf_LRU_block_free_hashed_page((buf_block_t*) bpage, TRUE);
+ }
+ }
+
+@@ -1936,7 +2093,8 @@
}
if (adjust) {
if (ratio != buf_pool->LRU_old_ratio) {
buf_pool->LRU_old_ratio = ratio;
-@@ -2000,7 +2156,8 @@
+@@ -1948,7 +2106,8 @@
}
}
} else {
buf_pool->LRU_old_ratio = ratio;
}
-@@ -2105,7 +2262,8 @@
+@@ -2053,7 +2212,8 @@
ulint new_len;
ut_ad(buf_pool);
if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
-@@ -2166,16 +2324,22 @@
+@@ -2114,16 +2274,22 @@
ut_a(buf_pool->LRU_old_len == old_len);
UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU,
ut_ad(ut_list_node_313->in_unzip_LRU_list
&& ut_list_node_313->page.in_LRU_list));
-@@ -2189,7 +2353,8 @@
+@@ -2137,7 +2303,8 @@
ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
}
}
/**********************************************************************//**
-@@ -2225,7 +2390,8 @@
+@@ -2173,7 +2340,8 @@
const buf_page_t* bpage;
ut_ad(buf_pool);
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-@@ -2282,7 +2448,8 @@
+@@ -2230,7 +2398,8 @@
bpage = UT_LIST_GET_NEXT(LRU, bpage);
}
}
/**********************************************************************//**
-diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
---- a/storage/innobase/buf/buf0rea.c 2010-12-03 15:22:36.323977308 +0900
-+++ b/storage/innobase/buf/buf0rea.c 2010-12-03 15:48:29.296024468 +0900
-@@ -311,6 +311,7 @@
+--- a/storage/innobase/buf/buf0rea.c
++++ b/storage/innobase/buf/buf0rea.c
+@@ -478,6 +478,7 @@
return(0);
}
/* Check that almost all pages in the area have been accessed; if
offset == low, the accesses must be in a descending order, otherwise,
-@@ -329,6 +330,7 @@
+@@ -496,6 +497,7 @@
fail_count = 0;
for (i = low; i < high; i++) {
bpage = buf_page_hash_get(buf_pool, space, i);
-@@ -356,7 +358,8 @@
+@@ -523,7 +525,8 @@
if (fail_count > threshold) {
/* Too many failures: return */
return(0);
}
-@@ -371,7 +374,8 @@
+@@ -538,7 +541,8 @@
bpage = buf_page_hash_get(buf_pool, space, offset);
if (bpage == NULL) {
return(0);
}
-@@ -397,7 +401,8 @@
+@@ -564,7 +568,8 @@
pred_offset = fil_page_get_prev(frame);
succ_offset = fil_page_get_next(frame);
if ((offset == low) && (succ_offset == offset + 1)) {
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:48:03.048955897 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:48:29.304024564 +0900
-@@ -264,6 +264,10 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -265,6 +265,10 @@
# endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */
{&buf_pool_mutex_key, "buf_pool_mutex", 0},
{&buf_pool_zip_mutex_key, "buf_pool_zip_mutex", 0},
{&cache_last_read_mutex_key, "cache_last_read_mutex", 0},
{&dict_foreign_err_mutex_key, "dict_foreign_err_mutex", 0},
{&dict_sys_mutex_key, "dict_sys_mutex", 0},
-@@ -313,6 +317,7 @@
+@@ -314,6 +318,7 @@
{&archive_lock_key, "archive_lock", 0},
# endif /* UNIV_LOG_ARCHIVE */
{&btr_search_latch_key, "btr_search_latch", 0},
# ifndef PFS_SKIP_BUFFER_MUTEX_RWLOCK
{&buf_block_lock_key, "buf_block_lock", 0},
# endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */
-diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
---- a/storage/innobase/handler/i_s.cc 2010-12-03 15:37:45.517105700 +0900
-+++ b/storage/innobase/handler/i_s.cc 2010-12-03 15:48:29.331024462 +0900
-@@ -1563,7 +1563,8 @@
+--- a/storage/innobase/handler/i_s.cc
++++ b/storage/innobase/handler/i_s.cc
+@@ -1583,7 +1583,8 @@
buf_pool = buf_pool_from_array(i);
for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
buf_buddy_stat_t* buddy_stat;
-@@ -1593,7 +1594,8 @@
+@@ -1613,7 +1614,8 @@
}
}
if (status) {
break;
-diff -ruN a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
---- a/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:48:03.068954202 +0900
-+++ b/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:48:29.335988682 +0900
-@@ -3821,9 +3821,11 @@
+--- a/storage/innobase/ibuf/ibuf0ibuf.c
++++ b/storage/innobase/ibuf/ibuf0ibuf.c
+@@ -3760,9 +3760,11 @@
ulint fold = buf_page_address_fold(space, page_no);
buf_pool_t* buf_pool = buf_pool_get(space, page_no);
if (UNIV_LIKELY_NULL(bpage)) {
/* A buffer pool watch has been set or the
-diff -ruN a/storage/innobase/include/buf0buddy.h b/storage/innobase/include/buf0buddy.h
---- a/storage/innobase/include/buf0buddy.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0buddy.h 2010-12-03 15:48:29.338023826 +0900
-@@ -51,10 +51,11 @@
- buf_pool_t* buf_pool,
- /*!< buffer pool in which the block resides */
- ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
-- ibool* lru) /*!< in: pointer to a variable that will be assigned
-+ ibool* lru, /*!< in: pointer to a variable that will be assigned
- TRUE if storage was allocated from the LRU list
- and buf_pool->mutex was temporarily released,
- or NULL if the LRU list should not be used */
-+ ibool have_page_hash_mutex)
- __attribute__((malloc));
+--- a/storage/innobase/include/buf0buddy.h
++++ b/storage/innobase/include/buf0buddy.h
+@@ -49,11 +49,12 @@
+ ulint size, /*!< in: compressed page size
+ (between PAGE_ZIP_MIN_SIZE and
+ UNIV_PAGE_SIZE) */
+- ibool* lru) /*!< in: pointer to a variable
++ ibool* lru, /*!< in: pointer to a variable
+ that will be assigned TRUE if
+ storage was allocated from the
+ LRU list and buf_pool->mutex was
+ temporarily released */
++ ibool have_page_hash_mutex)
+ __attribute__((malloc, nonnull));
/**********************************************************************//**
-@@ -67,7 +68,8 @@
- /*!< buffer pool in which the block resides */
- void* buf, /*!< in: block to be freed, must not be
- pointed to by the buffer pool */
-- ulint size) /*!< in: block size, up to UNIV_PAGE_SIZE */
-+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
-+ ibool have_page_hash_mutex)
+@@ -66,8 +67,9 @@
+ the block resides */
+ void* buf, /*!< in: block to be freed, must not
+ be pointed to by the buffer pool */
+- ulint size) /*!< in: block size,
++ ulint size, /*!< in: block size,
+ up to UNIV_PAGE_SIZE */
++ ibool have_page_hash_mutex)
__attribute__((nonnull));
#ifndef UNIV_NONINL
-diff -ruN a/storage/innobase/include/buf0buddy.ic b/storage/innobase/include/buf0buddy.ic
---- a/storage/innobase/include/buf0buddy.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0buddy.ic 2010-12-03 15:48:29.339040413 +0900
-@@ -46,10 +46,11 @@
- /*!< in: buffer pool in which the page resides */
- ulint i, /*!< in: index of buf_pool->zip_free[],
- or BUF_BUDDY_SIZES */
-- ibool* lru) /*!< in: pointer to a variable that will be assigned
-+ ibool* lru, /*!< in: pointer to a variable that will be assigned
- TRUE if storage was allocated from the LRU list
- and buf_pool->mutex was temporarily released,
- or NULL if the LRU list should not be used */
-+ ibool have_page_hash_mutex)
- __attribute__((malloc));
+--- a/storage/innobase/include/buf0buddy.ic
++++ b/storage/innobase/include/buf0buddy.ic
+@@ -45,11 +45,12 @@
+ buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
+ ulint i, /*!< in: index of buf_pool->zip_free[],
+ or BUF_BUDDY_SIZES */
+- ibool* lru) /*!< in: pointer to a variable that
++ ibool* lru, /*!< in: pointer to a variable that
+ will be assigned TRUE if storage was
+ allocated from the LRU list and
+ buf_pool->mutex was temporarily
+ released */
++ ibool have_page_hash_mutex)
+ __attribute__((malloc, nonnull));
/**********************************************************************//**
@@ -61,8 +62,9 @@
__attribute__((nonnull));
/**********************************************************************//**
-@@ -102,16 +104,17 @@
- the page resides */
- ulint size, /*!< in: block size, up to
- UNIV_PAGE_SIZE */
+@@ -101,19 +103,20 @@
+ ulint size, /*!< in: compressed page size
+ (between PAGE_ZIP_MIN_SIZE and
+ UNIV_PAGE_SIZE) */
- ibool* lru) /*!< in: pointer to a variable
+ ibool* lru, /*!< in: pointer to a variable
that will be assigned TRUE if
storage was allocated from the
LRU list and buf_pool->mutex was
- temporarily released, or NULL if
- the LRU list should not be used */
+ temporarily released */
+ ibool have_page_hash_mutex)
{
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(ut_is_2pow(size));
+ ut_ad(size >= PAGE_ZIP_MIN_SIZE);
+ ut_ad(size <= UNIV_PAGE_SIZE);
-- return(buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size), lru));
-+ return(buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size), lru, have_page_hash_mutex));
+ return((byte*) buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size),
+- lru));
++ lru, have_page_hash_mutex));
}
/**********************************************************************//**
-@@ -123,12 +126,25 @@
- buf_pool_t* buf_pool, /*!< in: buffer pool instance */
- void* buf, /*!< in: block to be freed, must not be
- pointed to by the buffer pool */
-- ulint size) /*!< in: block size, up to
-+ ulint size, /*!< in: block size, up to
- UNIV_PAGE_SIZE */
+@@ -126,15 +129,28 @@
+ the block resides */
+ void* buf, /*!< in: block to be freed, must not
+ be pointed to by the buffer pool */
+- ulint size) /*!< in: block size,
++ ulint size, /*!< in: block size,
+ up to UNIV_PAGE_SIZE */
+ ibool have_page_hash_mutex)
{
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
-+
+ ut_ad(ut_is_2pow(size));
+ ut_ad(size >= PAGE_ZIP_MIN_SIZE);
+ ut_ad(size <= UNIV_PAGE_SIZE);
+
+- buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size));
+ if (!have_page_hash_mutex) {
+ mutex_enter(&buf_pool->LRU_list_mutex);
+ rw_lock_x_lock(&buf_pool->page_hash_latch);
+ }
-
-- buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size));
++
+ mutex_enter(&buf_pool->zip_free_mutex);
+ buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size), TRUE);
+ mutex_exit(&buf_pool->zip_free_mutex);
}
#ifdef UNIV_MATERIALIZE
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h 2010-12-03 15:22:36.327954660 +0900
-+++ b/storage/innobase/include/buf0buf.h 2010-12-03 15:48:29.343024683 +0900
-@@ -205,6 +205,20 @@
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -212,6 +212,20 @@
/*==========================*/
/********************************************************************//**
Creates the buffer pool.
@return own: buf_pool object, NULL if not enough memory or error */
UNIV_INTERN
-@@ -834,6 +848,15 @@
+@@ -851,6 +865,15 @@
const buf_page_t* bpage) /*!< in: pointer to control block */
__attribute__((pure));
/*********************************************************************//**
Get the flush type of a page.
@return flush type */
-@@ -1315,7 +1338,7 @@
+@@ -1352,7 +1375,7 @@
All these are protected by buf_pool->mutex. */
/* @{ */
/*!< based on state, this is a
list node, protected either by
buf_pool->mutex or by
-@@ -1343,6 +1366,10 @@
+@@ -1380,6 +1403,10 @@
BUF_BLOCK_REMOVE_HASH or
BUF_BLOCK_READY_IN_USE. */
#ifdef UNIV_DEBUG
ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;
when buf_pool->flush_list_mutex is
-@@ -1435,11 +1462,11 @@
+@@ -1472,11 +1499,11 @@
a block is in the unzip_LRU list
if page.state == BUF_BLOCK_FILE_PAGE
and page.zip.data != NULL */
mutex_t mutex; /*!< mutex protecting this block:
state (also protected by the buffer
pool mutex), io_fix, buf_fix_count,
-@@ -1614,6 +1641,11 @@
+@@ -1656,6 +1683,11 @@
pool instance, protects compressed
only pages (of type buf_page_t, not
buf_block_t */
ulint instance_no; /*!< Array index of this buffer
pool instance */
ulint old_pool_size; /*!< Old pool size in bytes */
-@@ -1765,8 +1797,8 @@
+@@ -1809,8 +1841,8 @@
/** Test if a buffer pool mutex is owned. */
#define buf_pool_mutex_own(b) mutex_own(&b->mutex)
/** Acquire a buffer pool mutex. */
mutex_enter(&b->mutex); \
} while (0)
-diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
---- a/storage/innobase/include/buf0buf.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0buf.ic 2010-12-03 15:48:29.345024524 +0900
-@@ -274,7 +274,7 @@
+--- a/storage/innobase/include/buf0buf.ic
++++ b/storage/innobase/include/buf0buf.ic
+@@ -292,7 +292,7 @@
case BUF_BLOCK_ZIP_FREE:
/* This is a free page in buf_pool->zip_free[].
Such pages should only be accessed by the buddy allocator. */
break;
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
-@@ -317,9 +317,16 @@
+@@ -335,9 +335,16 @@
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
return(NULL);
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
-@@ -329,6 +336,28 @@
+@@ -347,6 +354,28 @@
}
}
/*********************************************************************//**
Get the flush type of a page.
@return flush type */
-@@ -425,8 +454,8 @@
+@@ -444,8 +473,8 @@
enum buf_io_fix io_fix) /*!< in: io_fix state */
{
#ifdef UNIV_DEBUG
#endif
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
-@@ -456,14 +485,14 @@
+@@ -482,7 +511,7 @@
+ {
+ #ifdef UNIV_DEBUG
+ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+- ut_ad(buf_pool_mutex_own(buf_pool));
++ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
+ #endif
+ ut_ad(mutex_own(buf_page_get_mutex(bpage)));
+ ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
+@@ -500,7 +529,7 @@
+ {
+ #ifdef UNIV_DEBUG
+ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+- ut_ad(buf_pool_mutex_own(buf_pool));
++ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
+ #endif
+ ut_ad(mutex_own(buf_page_get_mutex(bpage)));
+ ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_PIN);
+@@ -518,14 +547,14 @@
const buf_page_t* bpage) /*!< control block being relocated */
{
#ifdef UNIV_DEBUG
&& bpage->buf_fix_count == 0);
}
-@@ -477,8 +506,8 @@
+@@ -539,8 +568,8 @@
const buf_page_t* bpage) /*!< in: control block */
{
#ifdef UNIV_DEBUG
#endif
ut_ad(buf_page_in_file(bpage));
-@@ -498,7 +527,8 @@
+@@ -560,7 +589,8 @@
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
#endif /* UNIV_DEBUG */
ut_a(buf_page_in_file(bpage));
ut_ad(bpage->in_LRU_list);
#ifdef UNIV_LRU_DEBUG
-@@ -545,9 +575,10 @@
+@@ -607,9 +637,10 @@
ulint time_ms) /*!< in: ut_time_ms() */
{
#ifdef UNIV_DEBUG
ut_a(buf_page_in_file(bpage));
if (!bpage->access_time) {
-@@ -761,19 +792,19 @@
+@@ -852,19 +883,19 @@
/*===========*/
buf_block_t* block) /*!< in, own: block to be freed */
{
}
#endif /* !UNIV_HOTBACKUP */
-@@ -821,17 +852,17 @@
+@@ -912,17 +943,17 @@
page frame */
{
ib_uint64_t lsn;
return(lsn);
}
-@@ -849,7 +880,7 @@
+@@ -940,7 +971,7 @@
#ifdef UNIV_SYNC_DEBUG
buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
&& (block->page.buf_fix_count == 0))
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
#endif /* UNIV_SYNC_DEBUG */
-@@ -979,7 +1010,11 @@
+@@ -1070,7 +1101,11 @@
buf_page_t* bpage;
ut_ad(buf_pool);
ut_ad(fold == buf_page_address_fold(space, offset));
/* Look for the page in the hash table */
-@@ -1064,11 +1099,13 @@
+@@ -1155,11 +1190,13 @@
const buf_page_t* bpage;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
return(bpage != NULL);
}
-@@ -1196,4 +1233,38 @@
+@@ -1287,4 +1324,38 @@
buf_pool_mutex_exit(buf_pool);
}
}
+ }
+}
#endif /* !UNIV_HOTBACKUP */
-diff -ruN a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
---- a/storage/innobase/include/buf0lru.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0lru.h 2010-12-03 15:48:29.349024701 +0900
-@@ -111,8 +111,9 @@
+--- a/storage/innobase/include/buf0lru.h
++++ b/storage/innobase/include/buf0lru.h
+@@ -100,8 +100,9 @@
buf_LRU_free_block(
/*===============*/
buf_page_t* bpage, /*!< in: block to be freed */
__attribute__((nonnull));
/******************************************************************//**
Try to free a replaceable block.
-@@ -159,7 +160,8 @@
+@@ -148,7 +149,8 @@
void
buf_LRU_block_free_non_file_page(
/*=============================*/
/******************************************************************//**
Adds a block to the LRU list. */
UNIV_INTERN
-diff -ruN a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
---- a/storage/innobase/include/sync0rw.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/sync0rw.h 2010-12-03 15:48:29.349942993 +0900
+--- a/storage/innobase/include/sync0rw.h
++++ b/storage/innobase/include/sync0rw.h
@@ -112,6 +112,7 @@
extern mysql_pfs_key_t archive_lock_key;
# endif /* UNIV_LOG_ARCHIVE */
extern mysql_pfs_key_t buf_block_lock_key;
# ifdef UNIV_SYNC_DEBUG
extern mysql_pfs_key_t buf_block_debug_latch_key;
-diff -ruN a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
---- a/storage/innobase/include/sync0sync.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/sync0sync.h 2010-12-03 15:48:29.352024614 +0900
+--- a/storage/innobase/include/sync0sync.h
++++ b/storage/innobase/include/sync0sync.h
@@ -75,6 +75,10 @@
extern mysql_pfs_key_t buffer_block_mutex_key;
extern mysql_pfs_key_t buf_pool_mutex_key;
extern mysql_pfs_key_t cache_last_read_mutex_key;
extern mysql_pfs_key_t dict_foreign_err_mutex_key;
extern mysql_pfs_key_t dict_sys_mutex_key;
-@@ -668,7 +672,7 @@
+@@ -667,7 +671,7 @@
#define SYNC_TRX_SYS_HEADER 290
#define SYNC_PURGE_QUEUE 200
#define SYNC_LOG 170
+#define SYNC_LOG_FLUSH_ORDER 156
#define SYNC_RECV 168
#define SYNC_WORK_QUEUE 162
- #define SYNC_SEARCH_SYS_CONF 161 /* for assigning btr_search_enabled */
-@@ -678,8 +682,13 @@
+ #define SYNC_SEARCH_SYS 160 /* NOTE that if we have a memory
+@@ -676,8 +680,13 @@
SYNC_SEARCH_SYS, as memory allocation
can call routines there! Otherwise
the level is SYNC_MEM_HASH. */
#define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */
#define SYNC_DOUBLEWRITE 140
#define SYNC_ANY_LATCH 135
-@@ -711,7 +720,7 @@
+@@ -708,7 +717,7 @@
os_fast_mutex; /*!< We use this OS mutex in place of lock_word
when atomic operations are not enabled */
#endif
may be) threads waiting in the global wait
array for this mutex to be released.
Otherwise, this is 0. */
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-03 15:48:03.080956216 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 15:48:29.355023766 +0900
-@@ -3098,7 +3098,7 @@
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
+@@ -3105,7 +3105,7 @@
level += log_sys->max_checkpoint_age
- (lsn - oldest_modification);
}
n_blocks++;
}
-@@ -3184,7 +3184,7 @@
+@@ -3191,7 +3191,7 @@
found = TRUE;
break;
}
new_blocks_num++;
}
if (!found) {
-diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
---- a/storage/innobase/sync/sync0sync.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/sync/sync0sync.c 2010-12-03 15:48:29.358023890 +0900
+--- a/storage/innobase/sync/sync0sync.c
++++ b/storage/innobase/sync/sync0sync.c
@@ -285,7 +285,7 @@
mutex->lock_word = 0;
#endif
}
/******************************************************************//**
-@@ -1234,7 +1244,12 @@
+@@ -1233,7 +1243,12 @@
ut_error;
}
break;
case SYNC_BUF_POOL:
/* We can have multiple mutexes of this type therefore we
can only check whether the greater than condition holds. */
-@@ -1252,7 +1267,8 @@
+@@ -1251,7 +1266,8 @@
buffer block (block->mutex or buf_pool->zip_mutex). */
if (!sync_thread_levels_g(array, level, FALSE)) {
ut_a(sync_thread_levels_g(array, level - 1, TRUE));