]> git.pld-linux.org Git - packages/mysql.git/blobdiff - innodb_split_buf_pool_mutex.patch
- updated to 5.5.32
[packages/mysql.git] / innodb_split_buf_pool_mutex.patch
index 57391dd2e75fe8683984e5cf699c25f53f8a7084..dd69aee8e416ff22e7f0322857923d47be3434c3 100644 (file)
@@ -5,10 +5,9 @@
 #!!! 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);
  
@@ -18,13 +17,13 @@ diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
        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
@@ -44,10 +43,9 @@ diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
        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);
@@ -56,7 +54,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
        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)) {
@@ -70,7 +68,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
                }
  
                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) {
@@ -84,7 +82,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
                }
  
                if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
-@@ -2078,7 +2078,7 @@
+@@ -2105,7 +2105,7 @@
                }
        }
  
@@ -93,13 +91,21 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
        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));
@@ -107,23 +113,21 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
        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));
@@ -131,10 +135,10 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
        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;
  
@@ -142,15 +146,9 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
 +      //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 */
@@ -172,7 +170,7 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
        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);
  
@@ -188,7 +186,7 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
        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);
@@ -197,7 +195,7 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
        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);
@@ -208,17 +206,8 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
  
        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
@@ -226,16 +215,17 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
                                        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. */
@@ -249,7 +239,7 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
        }
  
        /* 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. */
@@ -282,71 +272,7 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
        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 */
@@ -357,7 +283,9 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
  {
        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));
@@ -365,132 +293,86 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
        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 */
@@ -507,9 +389,9 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
 +      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);
@@ -519,60 +401,35 @@ diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
                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
@@ -592,7 +449,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  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;
@@ -607,7 +464,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  #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 */
@@ -620,7 +477,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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);
@@ -630,28 +487,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        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);
@@ -673,7 +509,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        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);
  
@@ -682,7 +518,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                        buf_pool_mutex_exit(buf_pool);
  
                        return(DB_ERROR);
-@@ -1253,6 +1281,8 @@
+@@ -1205,6 +1231,8 @@
  
        /* All fields are initialized by mem_zalloc(). */
  
@@ -691,7 +527,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        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);
  
@@ -704,92 +540,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        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);
@@ -800,12 +551,12 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
 +      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);
@@ -823,7 +574,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        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;
@@ -837,7 +588,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                        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 */
@@ -846,25 +597,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        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 */
  {
@@ -877,7 +610,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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);
  
@@ -913,7 +646,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  }
  
  /****************************************************************//**
-@@ -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);
  
@@ -932,7 +665,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        return(ret);
  }
-@@ -2133,13 +2204,15 @@
+@@ -1650,13 +1706,15 @@
  {
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
  
@@ -950,7 +683,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  }
  
  /********************************************************************//**
-@@ -2163,14 +2236,20 @@
+@@ -1680,14 +1738,20 @@
        ut_a(buf_page_in_file(bpage));
  
        if (buf_page_peek_if_too_old(bpage)) {
@@ -975,7 +708,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        }
  }
  
-@@ -2187,7 +2266,8 @@
+@@ -1704,7 +1768,8 @@
        buf_block_t*    block;
        buf_pool_t*     buf_pool = buf_pool_get(space, offset);
  
@@ -985,7 +718,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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;
        }
  
@@ -994,28 +727,8 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
 +      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);
  
@@ -1025,7 +738,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        bpage = buf_page_hash_get(buf_pool, space, offset);
  
-@@ -2259,7 +2343,8 @@
+@@ -1744,7 +1811,8 @@
                bpage->file_page_was_freed = TRUE;
        }
  
@@ -1035,7 +748,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        return(bpage);
  }
-@@ -2280,7 +2365,8 @@
+@@ -1765,7 +1833,8 @@
        buf_page_t*     bpage;
        buf_pool_t*     buf_pool = buf_pool_get(space, offset);
  
@@ -1045,7 +758,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        bpage = buf_page_hash_get(buf_pool, space, offset);
  
-@@ -2289,7 +2375,8 @@
+@@ -1774,7 +1843,8 @@
                bpage->file_page_was_freed = FALSE;
        }
  
@@ -1055,7 +768,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        return(bpage);
  }
-@@ -2321,8 +2408,9 @@
+@@ -1806,8 +1876,9 @@
        buf_pool->stat.n_page_gets++;
  
        for (;;) {
@@ -1066,7 +779,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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 */
  
@@ -1076,7 +789,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
                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:
@@ -1093,7 +806,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        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:
@@ -1109,16 +822,40 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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);
  
@@ -1127,7 +864,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        mutex_exit(block_mutex);
  
-@@ -2697,7 +2791,7 @@
+@@ -2181,7 +2277,7 @@
        const buf_block_t*      block)          /*!< in: pointer to block,
                                                not dereferenced */
  {
@@ -1136,7 +873,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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;
@@ -1144,7 +881,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        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;
@@ -1155,11 +892,8 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
 +              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) {
@@ -1174,7 +908,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                        block = guess = NULL;
                } else {
                        ut_ad(!block->page.in_zip_hash);
-@@ -2789,12 +2890,19 @@
+@@ -2270,12 +2373,19 @@
        }
  
        if (block == NULL) {
@@ -1194,7 +928,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                block = NULL;
        }
  
-@@ -2806,12 +2914,14 @@
+@@ -2287,12 +2397,14 @@
                                space, offset, fold);
  
                        if (UNIV_LIKELY_NULL(block)) {
@@ -1211,7 +945,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
                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. */
@@ -1221,7 +955,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
                return(NULL);
        }
-@@ -2871,38 +2982,49 @@
+@@ -2355,38 +2468,49 @@
                ibool           success;
  
        case BUF_BLOCK_FILE_PAGE:
@@ -1278,7 +1012,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
                {
                        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. */
  
@@ -1332,16 +1066,16 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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);
  
@@ -1356,21 +1090,18 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
 -              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. */
@@ -1389,7 +1120,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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);
  
@@ -1398,18 +1129,18 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  #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)) {
@@ -1419,7 +1150,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
                                        /* The page entered the buffer
                                        pool for some reason. Try to
-@@ -3046,7 +3191,7 @@
+@@ -2531,7 +2678,7 @@
                                        goto got_block;
                                }
                        }
@@ -1428,10 +1159,10 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                        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);
  
@@ -1445,7 +1176,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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)) {
@@ -1459,7 +1190,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        } 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();
  
@@ -1473,7 +1204,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        }
  
        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);
  
@@ -1498,10 +1229,10 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
  #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
@@ -1510,7 +1241,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        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. */
@@ -1526,7 +1257,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        } 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);
@@ -1536,7 +1267,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                buf_print();
                buf_LRU_print();
                buf_validate();
-@@ -3613,7 +3773,9 @@
+@@ -3098,7 +3260,9 @@
  
        fold = buf_page_address_fold(space, offset);
  
@@ -1547,7 +1278,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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);
@@ -1564,16 +1295,16 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
                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);
@@ -1582,32 +1313,27 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                        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);
@@ -1615,7 +1341,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
                                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);
  
@@ -1623,7 +1349,9 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
 +
                /* 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);
 +
@@ -1641,7 +1369,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        if (mode == BUF_READ_IBUF_PAGES_ONLY) {
  
-@@ -3817,7 +3997,9 @@
+@@ -3297,7 +3479,9 @@
  
        fold = buf_page_address_fold(space, offset);
  
@@ -1652,7 +1380,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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 */
@@ -1663,15 +1391,15 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
                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. */
@@ -1680,7 +1408,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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);
  
@@ -1690,7 +1418,35 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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);
@@ -1699,7 +1455,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        ut_a(buf_page_in_file(bpage));
  
-@@ -4083,8 +4271,26 @@
+@@ -3619,8 +3815,26 @@
                }
        }
  
@@ -1727,7 +1483,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
  #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! */
  
@@ -1735,7 +1491,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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);
  
@@ -1745,7 +1501,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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 */
  
@@ -1755,7 +1511,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  }
  
  /*********************************************************************//**
-@@ -4164,7 +4374,9 @@
+@@ -3700,7 +3918,9 @@
  
        ut_ad(buf_pool);
  
@@ -1766,7 +1522,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        chunk = buf_pool->chunks;
  
-@@ -4181,7 +4393,9 @@
+@@ -3717,7 +3937,9 @@
                }
        }
  
@@ -1777,7 +1533,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        return(TRUE);
  }
-@@ -4229,7 +4443,8 @@
+@@ -3765,7 +3987,8 @@
                freed = buf_LRU_search_and_free_block(buf_pool, 100);
        }
  
@@ -1787,7 +1543,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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);
  
@@ -1797,7 +1553,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  }
  
  /*********************************************************************//**
-@@ -4284,7 +4500,10 @@
+@@ -3820,7 +4044,10 @@
  
        ut_ad(buf_pool);
  
@@ -1809,7 +1565,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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;
@@ -1818,7 +1574,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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;
@@ -1827,7 +1583,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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);
@@ -1836,7 +1592,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        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);
@@ -1849,7 +1605,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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);
  
@@ -1860,7 +1616,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        buf_flush_list_mutex_enter(buf_pool);
  
        fprintf(stderr,
-@@ -4605,7 +4831,9 @@
+@@ -4146,7 +4380,9 @@
                }
        }
  
@@ -1871,7 +1627,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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;
  
@@ -1880,7 +1636,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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;
@@ -1889,7 +1645,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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;
@@ -1898,7 +1654,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
                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);
@@ -1907,7 +1663,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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];
  
@@ -1916,7 +1672,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        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);
@@ -1925,7 +1681,7 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
        buf_pool_mutex_exit(buf_pool);
  }
  
-@@ -5241,11 +5473,13 @@
+@@ -4792,11 +5032,13 @@
  {
        ulint   len;
  
@@ -1941,9 +1697,8 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  
        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);
@@ -2008,13 +1763,15 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
        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);
@@ -2022,7 +1779,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
                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);
  
@@ -2031,7 +1788,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
        /* 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);
  
@@ -2054,7 +1811,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
                        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);
@@ -2063,7 +1820,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  #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. */
@@ -2073,7 +1830,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
        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 */
  {
@@ -2082,7 +1839,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
        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);
        }
  
@@ -2094,7 +1851,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
                /* 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);
@@ -2114,7 +1871,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
        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);
  
@@ -2130,10 +1887,10 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
 -                      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)) {
@@ -2147,7 +1904,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
                            && (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;
@@ -2159,10 +1916,10 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
 -              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 */
  
@@ -2194,7 +1951,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
                /* 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);
  
@@ -2216,7 +1973,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
        return(flushed);
  }
-@@ -1560,7 +1580,8 @@
+@@ -1610,7 +1630,8 @@
        buf_page_t*     bpage;
        ulint           count = 0;
  
@@ -2226,7 +1983,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
        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;
  
@@ -2236,7 +1993,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
        return(count);
  }
-@@ -1610,9 +1632,10 @@
+@@ -1660,9 +1682,10 @@
  {
        ulint           len;
        buf_page_t*     bpage;
@@ -2248,7 +2005,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
        /* 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);
@@ -2256,7 +2013,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
                }
  
                if (!bpage || bpage->oldest_modification >= lsn_limit) {
-@@ -1672,9 +1696,17 @@
+@@ -1722,9 +1746,17 @@
                                break;
                        }
  
@@ -2276,7 +2033,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
                        buf_flush_list_mutex_exit(buf_pool);
  
-@@ -1683,7 +1715,7 @@
+@@ -1733,7 +1765,7 @@
  
        } while (count < min_n && bpage != NULL && len > 0);
  
@@ -2285,7 +2042,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
        return(count);
  }
-@@ -1722,13 +1754,15 @@
+@@ -1772,13 +1804,15 @@
              || sync_thread_levels_empty_except_dict());
  #endif /* UNIV_SYNC_DEBUG */
  
@@ -2302,7 +2059,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
                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;
        }
  
@@ -2311,7 +2068,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
        buf_flush_buffered_writes();
  
-@@ -1993,7 +2027,7 @@
+@@ -2059,7 +2093,7 @@
  retry:
        //buf_pool_mutex_enter(buf_pool);
        if (have_LRU_mutex)
@@ -2320,7 +2077,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
        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;
                }
@@ -2341,7 +2098,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
                distance++;
  
-@@ -2027,7 +2061,7 @@
+@@ -2093,7 +2127,7 @@
  
        //buf_pool_mutex_exit(buf_pool);
        if (have_LRU_mutex)
@@ -2350,7 +2107,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
        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));
  
@@ -2359,7 +2116,7 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
                         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);
                }
  
@@ -2368,10 +2125,9 @@ diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
  
                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(
  /*===========================*/
@@ -2382,7 +2138,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
  /******************************************************************//**
  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(
  /*=========================*/
@@ -2405,7 +2161,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
                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) {
@@ -2426,9 +2182,9 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        /* 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);
@@ -2453,7 +2209,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
                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). */
@@ -2466,7 +2222,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
 -              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);
  
@@ -2478,12 +2234,15 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
                /* 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. */
@@ -2502,7 +2261,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
                /* 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. */
@@ -2527,68 +2286,73 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        /* 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);
  
@@ -2599,7 +2363,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        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);
@@ -2620,8 +2384,8 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
 +              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 */
@@ -2643,7 +2407,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        /* 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)
@@ -2652,7 +2416,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
                return(FALSE);
        }
-@@ -596,18 +648,25 @@
+@@ -565,18 +621,25 @@
        distance = 100 + (n_iterations
                          * UT_LIST_GET_LEN(buf_pool->unzip_LRU)) / 5;
  
@@ -2661,7 +2425,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
             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
@@ -2679,8 +2443,8 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
 +              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,
@@ -2706,12 +2470,11 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        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;
@@ -2732,8 +2495,8 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
 +              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;
@@ -2760,7 +2523,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        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);
@@ -2769,7 +2532,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        return(freed);
  }
-@@ -799,7 +878,9 @@
+@@ -737,7 +820,9 @@
  
                buf_pool = buf_pool_from_array(i);
  
@@ -2780,7 +2543,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
                if (!recv_recovery_on
                    && UT_LIST_GET_LEN(buf_pool->free)
-@@ -809,7 +890,9 @@
+@@ -747,7 +832,9 @@
                        ret = TRUE;
                }
  
@@ -2791,7 +2554,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        }
  
        return(ret);
-@@ -827,9 +910,10 @@
+@@ -765,9 +852,10 @@
  {
        buf_block_t*    block;
  
@@ -2804,7 +2567,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        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));
@@ -2815,7 +2578,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
                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);
@@ -2824,7 +2587,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        }
  
        return(block);
-@@ -870,7 +958,7 @@
+@@ -808,7 +900,7 @@
        ibool           mon_value_was   = FALSE;
        ibool           started_monitor = FALSE;
  loop:
@@ -2833,7 +2596,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        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);
@@ -2842,7 +2605,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        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);
@@ -2852,7 +2615,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        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;
  
@@ -2862,7 +2625,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        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));
@@ -2879,7 +2642,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
                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);
@@ -2889,7 +2652,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        ut_a(buf_page_in_file(bpage));
  
-@@ -1240,12 +1332,13 @@
+@@ -1178,12 +1274,13 @@
  
        ut_ad(buf_pool);
        ut_ad(block);
@@ -2905,7 +2668,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        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);
@@ -2915,7 +2678,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        ut_a(buf_page_in_file(bpage));
  
-@@ -1317,7 +1411,8 @@
+@@ -1255,7 +1353,8 @@
  
        ut_ad(buf_pool);
        ut_ad(bpage);
@@ -2925,7 +2688,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        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);
  
@@ -2935,7 +2698,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        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 */
@@ -2957,7 +2720,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        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
  
@@ -2965,28 +2728,17 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
 +      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 */
  
@@ -3008,7 +2760,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
 +              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;
@@ -3026,7 +2778,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        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);
  
@@ -3037,19 +2789,21 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
                        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);
@@ -3059,7 +2813,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
                mutex_exit(block_mutex);
  
                /* Remove possible adaptive hash index on the page.
-@@ -1646,7 +1784,9 @@
+@@ -1580,7 +1720,9 @@
                                : BUF_NO_CHECKSUM_MAGIC);
                }
  
@@ -3070,7 +2824,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
                mutex_enter(block_mutex);
  
                if (b) {
-@@ -1656,13 +1796,17 @@
+@@ -1589,13 +1731,17 @@
                        mutex_exit(&buf_pool->zip_mutex);
                }
  
@@ -3088,8 +2842,8 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
 +              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(
  /*=============================*/
@@ -3106,7 +2860,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        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);
@@ -3132,7 +2886,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        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);
@@ -3145,7 +2899,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        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));
@@ -3156,12 +2910,13 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
                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);
@@ -3172,15 +2927,12 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
 -                      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);
@@ -3197,7 +2949,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
                        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(
  /*===========================*/
@@ -3220,8 +2972,17 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
 +      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) {
@@ -3231,7 +2992,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
                if (ratio != buf_pool->LRU_old_ratio) {
                        buf_pool->LRU_old_ratio = ratio;
-@@ -2000,7 +2156,8 @@
+@@ -1948,7 +2106,8 @@
                        }
                }
  
@@ -3241,7 +3002,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        } else {
                buf_pool->LRU_old_ratio = ratio;
        }
-@@ -2105,7 +2262,8 @@
+@@ -2053,7 +2212,8 @@
        ulint           new_len;
  
        ut_ad(buf_pool);
@@ -3251,7 +3012,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        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);
  
@@ -3276,7 +3037,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
        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));
        }
  
@@ -3286,7 +3047,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  }
  
  /**********************************************************************//**
-@@ -2225,7 +2390,8 @@
+@@ -2173,7 +2340,8 @@
        const buf_page_t*       bpage;
  
        ut_ad(buf_pool);
@@ -3296,7 +3057,7 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  
        bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
  
-@@ -2282,7 +2448,8 @@
+@@ -2230,7 +2398,8 @@
                bpage = UT_LIST_GET_NEXT(LRU, bpage);
        }
  
@@ -3306,10 +3067,9 @@ diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
  }
  
  /**********************************************************************//**
-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);
        }
@@ -3317,7 +3077,7 @@ diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
  
        /* 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;
  
@@ -3325,7 +3085,7 @@ diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
        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 */
@@ -3335,7 +3095,7 @@ diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
                        return(0);
                }
  
-@@ -371,7 +374,8 @@
+@@ -538,7 +541,8 @@
        bpage = buf_page_hash_get(buf_pool, space, offset);
  
        if (bpage == NULL) {
@@ -3345,7 +3105,7 @@ diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
  
                return(0);
        }
-@@ -397,7 +401,8 @@
+@@ -564,7 +568,8 @@
        pred_offset = fil_page_get_prev(frame);
        succ_offset = fil_page_get_next(frame);
  
@@ -3355,10 +3115,9 @@ diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
  
        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},
@@ -3369,7 +3128,7 @@ diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_
        {&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},
@@ -3377,10 +3136,9 @@ diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_
  #  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);
  
@@ -3390,7 +3148,7 @@ diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
  
                for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
                        buf_buddy_stat_t*       buddy_stat;
-@@ -1593,7 +1594,8 @@
+@@ -1613,7 +1614,8 @@
                        }
                }
  
@@ -3400,10 +3158,9 @@ diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
  
                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);
  
@@ -3417,46 +3174,47 @@ diff -ruN a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.
  
                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 @@
@@ -3470,45 +3228,51 @@ diff -ruN a/storage/innobase/include/buf0buddy.ic b/storage/innobase/include/buf
        __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);
@@ -3520,10 +3284,9 @@ diff -ruN a/storage/innobase/include/buf0buddy.ic b/storage/innobase/include/buf
  }
  
  #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 @@
  /*==========================*/
  
  /********************************************************************//**
@@ -3544,7 +3307,7 @@ diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0bu
  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));
  
@@ -3560,7 +3323,7 @@ diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0bu
  /*********************************************************************//**
  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. */
        /* @{ */
  
@@ -3569,7 +3332,7 @@ diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0bu
                                        /*!< 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. */
  
@@ -3580,7 +3343,7 @@ diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0bu
  #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 */
@@ -3594,7 +3357,7 @@ diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0bu
        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 */
@@ -3606,7 +3369,7 @@ diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0bu
        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. */
@@ -3616,10 +3379,9 @@ diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0bu
        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. */
@@ -3628,7 +3390,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
                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);
  
@@ -3646,7 +3408,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
                return(NULL);
        case BUF_BLOCK_ZIP_PAGE:
        case BUF_BLOCK_ZIP_DIRTY:
-@@ -329,6 +336,28 @@
+@@ -347,6 +354,28 @@
        }
  }
  
@@ -3675,7 +3437,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
  /*********************************************************************//**
  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
@@ -3686,7 +3448,25 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
  #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
@@ -3705,7 +3485,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
               && bpage->buf_fix_count == 0);
  }
  
-@@ -477,8 +506,8 @@
+@@ -539,8 +568,8 @@
        const buf_page_t*       bpage)  /*!< in: control block */
  {
  #ifdef UNIV_DEBUG
@@ -3716,7 +3496,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
  #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));
@@ -3726,7 +3506,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
        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
@@ -3739,7 +3519,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
        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 */
  {
@@ -3763,7 +3543,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
  }
  #endif /* !UNIV_HOTBACKUP */
  
-@@ -821,17 +852,17 @@
+@@ -912,17 +943,17 @@
                                        page frame */
  {
        ib_uint64_t     lsn;
@@ -3786,7 +3566,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
  
        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);
  
@@ -3795,7 +3575,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
               && (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);
@@ -3808,7 +3588,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
        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);
  
@@ -3824,7 +3604,7 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
  
        return(bpage != NULL);
  }
-@@ -1196,4 +1233,38 @@
+@@ -1287,4 +1324,38 @@
                buf_pool_mutex_exit(buf_pool);
        }
  }
@@ -3863,10 +3643,9 @@ diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0b
 +      }
 +}
  #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 */
@@ -3877,7 +3656,7 @@ diff -ruN a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lr
        __attribute__((nonnull));
  /******************************************************************//**
  Try to free a replaceable block.
-@@ -159,7 +160,8 @@
+@@ -148,7 +149,8 @@
  void
  buf_LRU_block_free_non_file_page(
  /*=============================*/
@@ -3887,9 +3666,8 @@ diff -ruN a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lr
  /******************************************************************//**
  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 */
@@ -3898,9 +3676,8 @@ diff -ruN a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0r
  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;
@@ -3912,7 +3689,7 @@ diff -ruN a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync
  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
@@ -3920,8 +3697,8 @@ diff -ruN a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync
 +#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. */
@@ -3936,7 +3713,7 @@ diff -ruN a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync
  #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
@@ -3945,10 +3722,9 @@ diff -ruN a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync
                                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);
                                                        }
@@ -3957,7 +3733,7 @@ diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
                                                        n_blocks++;
                                                }
  
-@@ -3184,7 +3184,7 @@
+@@ -3191,7 +3191,7 @@
                                                        found = TRUE;
                                                        break;
                                                }
@@ -3966,9 +3742,8 @@ diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
                                                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
@@ -4002,7 +3777,7 @@ diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.
  }
  
  /******************************************************************//**
-@@ -1234,7 +1244,12 @@
+@@ -1233,7 +1243,12 @@
                        ut_error;
                }
                break;
@@ -4015,7 +3790,7 @@ diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.
        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));
This page took 0.397352 seconds and 4 git commands to generate.