]> git.pld-linux.org Git - packages/mysql.git/blobdiff - innodb_adaptive_hash_index_partitions.patch
move status action to status function
[packages/mysql.git] / innodb_adaptive_hash_index_partitions.patch
index 943435316587a091a97c8a4c94dd44ad6dd441c2..ed42237e35b50d25c95e2c9e41a073f60a3f81b3 100644 (file)
@@ -5,85 +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/btr0btr.c b/storage/innobase/btr/btr0btr.c
---- a/storage/innobase/btr/btr0btr.c   2010-12-04 15:52:23.355483176 +0900
-+++ b/storage/innobase/btr/btr0btr.c   2010-12-04 16:12:48.639514256 +0900
-@@ -954,7 +954,7 @@
-       }
-       ut_a(block);
--      btr_search_drop_page_hash_index(block);
-+      btr_search_drop_page_hash_index(block, NULL);
-       header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;
- #ifdef UNIV_BTR_DEBUG
-@@ -1023,7 +1023,7 @@
- #ifndef UNIV_HOTBACKUP
-       if (UNIV_LIKELY(!recovery)) {
--              btr_search_drop_page_hash_index(block);
-+              btr_search_drop_page_hash_index(block, index);
-       }
-       block->check_index_page_at_flush = TRUE;
-@@ -1188,7 +1188,7 @@
-       ut_a(!page_zip || page_zip_validate(page_zip, page));
- #endif /* UNIV_ZIP_DEBUG */
--      btr_search_drop_page_hash_index(block);
-+      btr_search_drop_page_hash_index(block, index);
-       /* Recreate the page: note that global data on page (possible
-       segment headers, next page-field, etc.) is preserved intact */
-@@ -2497,7 +2497,7 @@
-               mem_heap_free(heap);
-       }
--      btr_search_drop_page_hash_index(block);
-+      btr_search_drop_page_hash_index(block, index);
-       /* Make the father empty */
-       btr_page_empty(father_block, father_page_zip, index, page_level, mtr);
-@@ -2720,7 +2720,7 @@
-                       goto err_exit;
-               }
--              btr_search_drop_page_hash_index(block);
-+              btr_search_drop_page_hash_index(block, index);
-               /* Remove the page from the level list */
-               btr_level_list_remove(space, zip_size, page, mtr);
-@@ -2761,7 +2761,7 @@
-                       goto err_exit;
-               }
--              btr_search_drop_page_hash_index(block);
-+              btr_search_drop_page_hash_index(block, index);
- #ifdef UNIV_BTR_DEBUG
-               if (UNIV_LIKELY_NULL(merge_page_zip)) {
-@@ -2875,7 +2875,7 @@
-               ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
-               ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
--              btr_search_drop_page_hash_index(block);
-+              btr_search_drop_page_hash_index(block, index);
-               btr_page_get_father(index, block, mtr, &cursor);
-               father = btr_cur_get_block(&cursor);
-@@ -2980,7 +2980,7 @@
-       page = buf_block_get_frame(block);
-       ut_a(page_is_comp(merge_page) == page_is_comp(page));
--      btr_search_drop_page_hash_index(block);
-+      btr_search_drop_page_hash_index(block, index);
-       if (left_page_no == FIL_NULL && !page_is_leaf(page)) {
-diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
---- a/storage/innobase/btr/btr0cur.c   2010-12-04 15:52:23.359513820 +0900
-+++ b/storage/innobase/btr/btr0cur.c   2010-12-04 16:12:48.643551837 +0900
-@@ -486,7 +486,7 @@
+--- a/storage/innobase/btr/btr0cur.c
++++ b/storage/innobase/btr/btr0cur.c
+@@ -500,7 +500,7 @@
  #ifdef UNIV_SEARCH_PERF_STAT
        info->n_searches++;
  #endif
@@ -92,7 +16,7 @@ diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
            && latch_mode <= BTR_MODIFY_LEAF
            && info->last_hash_succ
            && !estimate
-@@ -522,7 +522,7 @@
+@@ -536,7 +536,7 @@
  
        if (has_search_latch) {
                /* Release possible search latch to obey latching order */
@@ -101,7 +25,7 @@ diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
        }
  
        /* Store the position of the tree latch we push to mtr so that we
-@@ -844,7 +844,7 @@
+@@ -847,7 +847,7 @@
  
        if (has_search_latch) {
  
@@ -110,7 +34,7 @@ diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
        }
  }
  
-@@ -2060,7 +2060,7 @@
+@@ -1977,13 +1977,13 @@
                        btr_search_update_hash_on_delete(cursor);
                }
  
@@ -118,63 +42,26 @@ diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
 +              rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
        }
  
-       if (!(flags & BTR_KEEP_SYS_FLAG)) {
-@@ -2074,7 +2074,7 @@
        row_upd_rec_in_place(rec, index, offsets, update, page_zip);
  
-       if (block->is_hashed) {
+       if (is_hashed) {
 -              rw_lock_x_unlock(&btr_search_latch);
 +              rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
        }
  
        if (page_zip && !dict_index_is_clust(index)
-@@ -2852,7 +2852,7 @@
-       }
-       if (block->is_hashed) {
--              rw_lock_x_lock(&btr_search_latch);
-+              rw_lock_x_lock(btr_search_get_latch(index->id));
-       }
-       page_zip = buf_block_get_page_zip(block);
-@@ -2867,7 +2867,7 @@
-       }
-       if (block->is_hashed) {
--              rw_lock_x_unlock(&btr_search_latch);
-+              rw_lock_x_unlock(btr_search_get_latch(index->id));
-       }
-       btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx,
-@@ -2994,13 +2994,13 @@
-             == dict_table_is_comp(cursor->index->table));
-       if (block->is_hashed) {
--              rw_lock_x_lock(&btr_search_latch);
-+              rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
-       }
-       btr_rec_set_deleted_flag(rec, buf_block_get_page_zip(block), val);
-       if (block->is_hashed) {
--              rw_lock_x_unlock(&btr_search_latch);
-+              rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
-       }
-       btr_cur_del_mark_set_sec_rec_log(rec, val, mtr);
-diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
---- a/storage/innobase/btr/btr0sea.c   2010-12-04 15:52:23.387513429 +0900
-+++ b/storage/innobase/btr/btr0sea.c   2010-12-04 16:14:51.721884049 +0900
-@@ -48,6 +48,8 @@
+--- a/storage/innobase/btr/btr0sea.c
++++ b/storage/innobase/btr/btr0sea.c
+@@ -47,6 +47,8 @@
+ Protected by btr_search_latch. */
  UNIV_INTERN char              btr_search_enabled      = TRUE;
- UNIV_INTERN ibool             btr_search_fully_disabled = FALSE;
  
 +UNIV_INTERN ulint             btr_search_index_num    = 1;
 +
- /** Mutex protecting btr_search_enabled */
- static mutex_t                        btr_search_enabled_mutex;
-@@ -79,7 +81,9 @@
+ #ifdef UNIV_PFS_MUTEX
+ /* Key to register btr_search_enabled_mutex with performance schema */
+ UNIV_INTERN mysql_pfs_key_t   btr_search_enabled_mutex_key;
+@@ -75,7 +77,9 @@
  
  /* We will allocate the latch from dynamic memory to get it to the
  same DRAM page as other hotspot semaphores */
@@ -185,7 +72,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
  /** padding to prevent other memory update hotspots from residing on
  the same memory cache line */
-@@ -131,18 +135,19 @@
+@@ -127,18 +131,19 @@
  will not guarantee success. */
  static
  void
@@ -209,16 +96,16 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
        heap = table->heap;
  
-@@ -153,7 +158,7 @@
+@@ -149,7 +154,7 @@
        if (heap->free_block == NULL) {
-               buf_block_t*    block = buf_block_alloc(NULL, 0);
+               buf_block_t*    block = buf_block_alloc(NULL);
  
 -              rw_lock_x_lock(&btr_search_latch);
 +              rw_lock_x_lock(btr_search_get_latch(key));
  
                if (heap->free_block == NULL) {
                        heap->free_block = block;
-@@ -161,7 +166,7 @@
+@@ -157,7 +162,7 @@
                        buf_block_free(block);
                }
  
@@ -227,7 +114,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
        }
  }
  
-@@ -173,19 +178,30 @@
+@@ -169,17 +174,28 @@
  /*==================*/
        ulint   hash_size)      /*!< in: hash index hash table size */
  {
@@ -242,8 +129,6 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
 -                     SYNC_SEARCH_SYS);
 +      //rw_lock_create(btr_search_latch_key, &btr_search_latch,
 +      //             SYNC_SEARCH_SYS);
-       mutex_create(btr_search_enabled_mutex_key,
-                    &btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF);
  
        btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
  
@@ -262,7 +147,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  }
  
  /*****************************************************************//**
-@@ -195,11 +211,20 @@
+@@ -189,11 +205,22 @@
  btr_search_sys_free(void)
  /*=====================*/
  {
@@ -281,6 +166,8 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
 +
 +              mem_free(btr_search_latch_part[i]);
 +      }
++      mem_free(btr_search_sys->hash_index);
++      mem_free(btr_search_latch_part);
 +
 +      //rw_lock_free(&btr_search_latch);
 +      //mem_free(btr_search_latch_temp);
@@ -288,40 +175,49 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
        mem_free(btr_search_sys);
        btr_search_sys = NULL;
  }
-@@ -212,7 +237,7 @@
+@@ -206,9 +233,10 @@
  /*====================*/
  {
-       mutex_enter(&btr_search_enabled_mutex);
+       dict_table_t*   table;
++      ulint i;
+       mutex_enter(&dict_sys->mutex);
 -      rw_lock_x_lock(&btr_search_latch);
 +      btr_search_x_lock_all();
  
-       /* Disable access to hash index, also tell ha_insert_for_fold()
-       stop adding new nodes to hash index, but still allow updating
-@@ -230,7 +255,7 @@
-       /* btr_search_enabled_mutex should guarantee this. */
-       ut_ad(!btr_search_enabled);
+       btr_search_enabled = FALSE;
+@@ -232,10 +260,12 @@
+       buf_pool_clear_hash_index();
+       /* Clear the adaptive hash index. */
+-      hash_table_clear(btr_search_sys->hash_index);
+-      mem_heap_empty(btr_search_sys->hash_index->heap);
++      for (i = 0; i < btr_search_index_num; i++) {
++              hash_table_clear(btr_search_sys->hash_index[i]);
++              mem_heap_empty(btr_search_sys->hash_index[i]->heap);
++      }
  
 -      rw_lock_x_unlock(&btr_search_latch);
 +      btr_search_x_unlock_all();
-       mutex_exit(&btr_search_enabled_mutex);
  }
  
-@@ -242,12 +267,12 @@
+ /********************************************************************//**
+@@ -245,11 +275,11 @@
+ btr_search_enable(void)
  /*====================*/
  {
-       mutex_enter(&btr_search_enabled_mutex);
 -      rw_lock_x_lock(&btr_search_latch);
 +      btr_search_x_lock_all();
  
        btr_search_enabled = TRUE;
-       btr_search_fully_disabled = FALSE;
  
 -      rw_lock_x_unlock(&btr_search_latch);
 +      btr_search_x_unlock_all();
-       mutex_exit(&btr_search_enabled_mutex);
  }
  
-@@ -300,20 +325,21 @@
+ /*****************************************************************//**
+@@ -301,20 +331,21 @@
  ulint
  btr_search_info_get_ref_count(
  /*==========================*/
@@ -348,7 +244,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
        return(ret);
  }
-@@ -334,8 +360,8 @@
+@@ -335,8 +366,8 @@
        int             cmp;
  
  #ifdef UNIV_SYNC_DEBUG
@@ -359,7 +255,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  #endif /* UNIV_SYNC_DEBUG */
  
        index = cursor->index;
-@@ -453,8 +479,8 @@
+@@ -454,8 +485,8 @@
                                /*!< in: cursor */
  {
  #ifdef UNIV_SYNC_DEBUG
@@ -370,7 +266,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
        ut_ad(rw_lock_own(&block->lock, RW_LOCK_SHARED)
              || rw_lock_own(&block->lock, RW_LOCK_EX));
  #endif /* UNIV_SYNC_DEBUG */
-@@ -538,7 +564,7 @@
+@@ -539,7 +570,7 @@
  
        ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
  #ifdef UNIV_SYNC_DEBUG
@@ -379,7 +275,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
        ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
              || rw_lock_own(&(block->lock), RW_LOCK_EX));
  #endif /* UNIV_SYNC_DEBUG */
-@@ -578,10 +604,10 @@
+@@ -580,10 +611,10 @@
                        mem_heap_free(heap);
                }
  #ifdef UNIV_SYNC_DEBUG
@@ -392,7 +288,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
                                   block, rec);
        }
  }
-@@ -601,8 +627,8 @@
+@@ -603,8 +634,8 @@
        ulint*          params2;
  
  #ifdef UNIV_SYNC_DEBUG
@@ -403,7 +299,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  #endif /* UNIV_SYNC_DEBUG */
  
        block = btr_cur_get_block(cursor);
-@@ -623,7 +649,7 @@
+@@ -625,7 +656,7 @@
  
        if (build_index || (cursor->flag == BTR_CUR_HASH_FAIL)) {
  
@@ -412,7 +308,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
        }
  
        if (cursor->flag == BTR_CUR_HASH_FAIL) {
-@@ -633,11 +659,11 @@
+@@ -635,11 +666,11 @@
                btr_search_n_hash_fail++;
  #endif /* UNIV_SEARCH_PERF_STAT */
  
@@ -426,7 +322,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
        }
  
        if (build_index) {
-@@ -881,17 +907,17 @@
+@@ -884,17 +915,17 @@
        cursor->flag = BTR_CUR_HASH;
  
        if (UNIV_LIKELY(!has_search_latch)) {
@@ -448,7 +344,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
        if (UNIV_UNLIKELY(!rec)) {
                goto failure_unlock;
-@@ -909,7 +935,7 @@
+@@ -912,7 +943,7 @@
                        goto failure_unlock;
                }
  
@@ -457,7 +353,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
                buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
        }
-@@ -1006,7 +1032,7 @@
+@@ -1009,7 +1040,7 @@
        /*-------------------------------------------*/
  failure_unlock:
        if (UNIV_LIKELY(!has_search_latch)) {
@@ -466,43 +362,25 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
        }
  failure:
        cursor->flag = BTR_CUR_HASH_FAIL;
-@@ -1029,10 +1055,11 @@
- void
- btr_search_drop_page_hash_index(
- /*============================*/
--      buf_block_t*    block)  /*!< in: block containing index page,
-+      buf_block_t*    block,  /*!< in: block containing index page,
-                               s- or x-latched, or an index page
-                               for which we know that
-                               block->buf_fix_count == 0 */
-+      dict_index_t*   index_in)
- {
-       hash_table_t*           table;
-       ulint                   n_fields;
-@@ -1051,22 +1078,60 @@
+@@ -1053,24 +1084,49 @@
+       const dict_index_t*     index;
        ulint*                  offsets;
  
- #ifdef UNIV_SYNC_DEBUG
+-#ifdef UNIV_SYNC_DEBUG
 -      ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
 -      ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
-+      if (index_in) {
-+              ut_ad(!rw_lock_own(btr_search_get_latch(index_in->id), RW_LOCK_SHARED));
-+              ut_ad(!rw_lock_own(btr_search_get_latch(index_in->id), RW_LOCK_EX));
-+      }
- #endif /* UNIV_SYNC_DEBUG */
+-#endif /* UNIV_SYNC_DEBUG */
+-
  retry:
 -      rw_lock_s_lock(&btr_search_latch);
-+      if (index_in) {
-+              index = index_in;
-+              rw_lock_s_lock(btr_search_get_latch(index->id));
-+      } else if (btr_search_index_num > 1) {
+-      index = block->index;
++      if (btr_search_index_num > 1) {
 +              rw_lock_t*      btr_search_latch;
 +
 +              /* FIXME: This may be optimistic implementation still. */
 +              btr_search_latch = (rw_lock_t*)(block->btr_search_latch);
 +              if (UNIV_LIKELY(!btr_search_latch)) {
-+                      if (block->is_hashed) {
++                      if (block->index) {
 +                              goto retry;
 +                      }
 +                      return;
@@ -512,27 +390,25 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
 +                      rw_lock_s_unlock(btr_search_latch);
 +                      goto retry;
 +              }
-+              if (UNIV_LIKELY(!block->is_hashed)) {
++              if (UNIV_LIKELY(!block->index)) {
 +                      rw_lock_s_unlock(btr_search_latch);
-+                      return;
++                      goto retry;
 +              }
 +              index = block->index;
 +              ut_a(btr_search_latch == btr_search_get_latch(index->id));
 +      } else {
 +              /* btr_search_index_num == 1 */
 +              /* btr_search_latch is only one and able to obtain
-+                 before evaluating block->is_hashed. */
++                 before evaluating block->index. */
 +              rw_lock_s_lock(btr_search_latch_part[0]);
-+              if (UNIV_LIKELY(!block->is_hashed)) {
++              if (UNIV_LIKELY(!block->index)) {
 +                      rw_lock_s_unlock(btr_search_latch_part[0]);
 +                      return;
 +              }
 +              index = block->index;
 +      }
-+
-       page = block->frame;
  
-       if (UNIV_LIKELY(!block->is_hashed)) {
+       if (UNIV_LIKELY(!index)) {
  
 -              rw_lock_s_unlock(&btr_search_latch);
 +              rw_lock_s_unlock(btr_search_get_latch(index->id));
@@ -540,18 +416,18 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
                return;
        }
  
+-      ut_a(!dict_index_is_ibuf(index));
 -      table = btr_search_sys->hash_index;
 +      table = btr_search_get_hash_index(index->id);
  
  #ifdef UNIV_SYNC_DEBUG
        ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
-@@ -1076,14 +1141,14 @@
+@@ -1080,12 +1136,14 @@
  
        n_fields = block->curr_n_fields;
        n_bytes = block->curr_n_bytes;
--      index = block->index;
 +      ut_a(index == block->index);
-       ut_a(!dict_index_is_ibuf(index));
++      ut_a(!dict_index_is_ibuf(index));
  
        /* NOTE: The fields of block must not be accessed after
        releasing btr_search_latch, as the index page might only
@@ -562,16 +438,16 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
        ut_a(n_fields + n_bytes > 0);
  
-@@ -1133,7 +1198,7 @@
+@@ -1136,7 +1194,7 @@
                mem_heap_free(heap);
        }
  
 -      rw_lock_x_lock(&btr_search_latch);
 +      rw_lock_x_lock(btr_search_get_latch(index->id));
  
-       if (UNIV_UNLIKELY(!block->is_hashed)) {
+       if (UNIV_UNLIKELY(!block->index)) {
                /* Someone else has meanwhile dropped the hash index */
-@@ -1149,7 +1214,7 @@
+@@ -1152,7 +1210,7 @@
                /* Someone else has meanwhile built a new hash index on the
                page, with different parameters */
  
@@ -580,15 +456,15 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
                mem_free(folds);
                goto retry;
-@@ -1165,6 +1230,7 @@
+@@ -1167,6 +1225,7 @@
+       index->search_info->ref_count--;
  
-       block->is_hashed = FALSE;
        block->index = NULL;
 +      block->btr_search_latch = NULL;
-       
  cleanup:
  #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-@@ -1177,14 +1243,14 @@
+@@ -1179,14 +1238,14 @@
                        "InnoDB: the hash index to a page of %s,"
                        " still %lu hash nodes remain.\n",
                        index->name, (ulong) block->n_pointers);
@@ -606,7 +482,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
  
        mem_free(folds);
-@@ -1216,9 +1282,9 @@
+@@ -1218,9 +1277,9 @@
        ulint*          offsets;
        ibool           released_search_latch;
  
@@ -618,7 +494,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
        for (j = 0; j < srv_buf_pool_instances; j++) {
                buf_pool_t*     buf_pool;
-@@ -1252,7 +1318,7 @@
+@@ -1254,7 +1313,7 @@
  
  
                                        /* keeping latch order */
@@ -627,16 +503,16 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
                                        released_search_latch = TRUE;
                                        rw_lock_x_lock(&block->lock);
  
-@@ -1304,7 +1370,7 @@
+@@ -1306,7 +1365,7 @@
                                                mem_heap_empty(heap);
                                        }
  
 -                                      rw_lock_x_lock(&btr_search_latch);
 +                                      rw_lock_x_lock(btr_search_get_latch(index->id));
  
-                                       if (UNIV_UNLIKELY(!block->is_hashed)) {
+                                       if (UNIV_UNLIKELY(!block->index)) {
                                                goto cleanup;
-@@ -1314,12 +1380,12 @@
+@@ -1316,12 +1375,12 @@
  
                                        if (UNIV_UNLIKELY(block->curr_n_fields != n_fields)
                                            || UNIV_UNLIKELY(block->curr_n_bytes != n_bytes)) {
@@ -651,15 +527,15 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
                                                goto retry;
                                        }
  
-@@ -1333,6 +1399,7 @@
+@@ -1334,6 +1393,7 @@
+                                       index->search_info->ref_count--;
  
-                                       block->is_hashed = FALSE;
                                        block->index = NULL;
 +                                      block->btr_search_latch = NULL;
  
  cleanup:
  #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-@@ -1345,18 +1412,18 @@
+@@ -1346,18 +1406,18 @@
                                                        index->name, (ulong) block->n_pointers);
                                        }
  #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -681,23 +557,13 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
        if (UNIV_LIKELY_NULL(heap)) {
                mem_heap_free(heap);
-@@ -1403,7 +1470,7 @@
-               buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
--              btr_search_drop_page_hash_index(block);
-+              btr_search_drop_page_hash_index(block, NULL);
-       }
-       mtr_commit(&mtr);
-@@ -1445,26 +1512,26 @@
+@@ -1436,31 +1496,26 @@
        ut_ad(index);
        ut_a(!dict_index_is_ibuf(index));
  
--      table = btr_search_sys->hash_index;
 +      table = btr_search_get_hash_index(index->id);
-       page = buf_block_get_frame(block);
++      page = buf_block_get_frame(block);
++
  #ifdef UNIV_SYNC_DEBUG
 -      ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
 +      ut_ad(!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_EX));
@@ -706,24 +572,33 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  #endif /* UNIV_SYNC_DEBUG */
  
 -      rw_lock_s_lock(&btr_search_latch);
+-
+-      if (!btr_search_enabled) {
+-              rw_lock_s_unlock(&btr_search_latch);
+-              return;
+-      }
+-
+-      table = btr_search_sys->hash_index;
+-      page = buf_block_get_frame(block);
 +      rw_lock_s_lock(btr_search_get_latch(index->id));
  
-       if (block->is_hashed && ((block->curr_n_fields != n_fields)
-                                || (block->curr_n_bytes != n_bytes)
-                                || (block->curr_left_side != left_side))) {
+       if (block->index && ((block->curr_n_fields != n_fields)
+-                           || (block->curr_n_bytes != n_bytes)
+-                           || (block->curr_left_side != left_side))) {
++                               || (block->curr_n_bytes != n_bytes)
++                               || (block->curr_left_side != left_side))) {
  
 -              rw_lock_s_unlock(&btr_search_latch);
 +              rw_lock_s_unlock(btr_search_get_latch(index->id));
  
--              btr_search_drop_page_hash_index(block);
-+              btr_search_drop_page_hash_index(block, index);
+               btr_search_drop_page_hash_index(block);
        } else {
 -              rw_lock_s_unlock(&btr_search_latch);
 +              rw_lock_s_unlock(btr_search_get_latch(index->id));
        }
  
        n_recs = page_get_n_recs(page);
-@@ -1558,9 +1625,9 @@
+@@ -1554,9 +1609,9 @@
                fold = next_fold;
        }
  
@@ -733,9 +608,9 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
 -      rw_lock_x_lock(&btr_search_latch);
 +      rw_lock_x_lock(btr_search_get_latch(index->id));
  
-       if (UNIV_UNLIKELY(btr_search_fully_disabled)) {
+       if (UNIV_UNLIKELY(!btr_search_enabled)) {
                goto exit_func;
-@@ -1588,6 +1655,7 @@
+@@ -1583,6 +1638,7 @@
        block->curr_n_bytes = n_bytes;
        block->curr_left_side = left_side;
        block->index = index;
@@ -743,7 +618,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
        for (i = 0; i < n_cached; i++) {
  
-@@ -1595,7 +1663,7 @@
+@@ -1590,7 +1646,7 @@
        }
  
  exit_func:
@@ -752,24 +627,25 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
        mem_free(folds);
        mem_free(recs);
-@@ -1634,13 +1702,13 @@
-       ut_a(!(new_block->is_hashed || block->is_hashed)
-            || !dict_index_is_ibuf(index));
+@@ -1625,7 +1681,7 @@
+       ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_EX));
+ #endif /* UNIV_SYNC_DEBUG */
  
 -      rw_lock_s_lock(&btr_search_latch);
 +      rw_lock_s_lock(btr_search_get_latch(index->id));
  
-       if (new_block->is_hashed) {
+       ut_a(!new_block->index || new_block->index == index);
+       ut_a(!block->index || block->index == index);
+@@ -1634,7 +1690,7 @@
+       if (new_block->index) {
  
 -              rw_lock_s_unlock(&btr_search_latch);
 +              rw_lock_s_unlock(btr_search_get_latch(index->id));
  
--              btr_search_drop_page_hash_index(block);
-+              btr_search_drop_page_hash_index(block, index);
+               btr_search_drop_page_hash_index(block);
  
-               return;
-       }
-@@ -1655,7 +1723,7 @@
+@@ -1651,7 +1707,7 @@
                new_block->n_bytes = block->curr_n_bytes;
                new_block->left_side = left_side;
  
@@ -778,7 +654,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
                ut_a(n_fields + n_bytes > 0);
  
-@@ -1667,7 +1735,7 @@
+@@ -1663,7 +1719,7 @@
                return;
        }
  
@@ -787,38 +663,43 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  }
  
  /********************************************************************//**
-@@ -1706,7 +1774,7 @@
+@@ -1702,7 +1758,7 @@
        ut_a(block->curr_n_fields + block->curr_n_bytes > 0);
-       ut_a(!dict_index_is_ibuf(cursor->index));
+       ut_a(!dict_index_is_ibuf(index));
  
 -      table = btr_search_sys->hash_index;
 +      table = btr_search_get_hash_index(cursor->index->id);
  
-       index_id = cursor->index->id;
-       fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_,
-@@ -1715,11 +1783,11 @@
-       if (UNIV_LIKELY_NULL(heap)) {
+       rec = btr_cur_get_rec(cursor);
+@@ -1713,7 +1769,7 @@
                mem_heap_free(heap);
        }
 -      rw_lock_x_lock(&btr_search_latch);
 +      rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
  
-       ha_search_and_delete_if_found(table, fold, rec);
+       if (block->index) {
+               ut_a(block->index == index);
+@@ -1721,7 +1777,7 @@
+               ha_search_and_delete_if_found(table, fold, rec);
+       }
  
 -      rw_lock_x_unlock(&btr_search_latch);
 +      rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
  }
  
  /********************************************************************//**
-@@ -1753,21 +1821,21 @@
-       ut_a(block->index == cursor->index);
-       ut_a(!dict_index_is_ibuf(cursor->index));
+@@ -1758,7 +1814,7 @@
+       ut_a(cursor->index == index);
+       ut_a(!dict_index_is_ibuf(index));
  
 -      rw_lock_x_lock(&btr_search_latch);
 +      rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
  
-       if ((cursor->flag == BTR_CUR_HASH)
-           && (cursor->n_fields == block->curr_n_fields)
+       if (!block->index) {
+@@ -1772,15 +1828,15 @@
            && (cursor->n_bytes == block->curr_n_bytes)
            && !block->curr_left_side) {
  
@@ -828,6 +709,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
                ha_search_and_update_if_found(table, cursor->fold, rec,
                                              block, page_rec_get_next(rec));
  
+ func_exit:
 -              rw_lock_x_unlock(&btr_search_latch);
 +              rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
        } else {
@@ -836,7 +718,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
                btr_search_update_hash_on_insert(cursor);
        }
-@@ -1802,9 +1870,9 @@
+@@ -1815,9 +1871,9 @@
        ulint*          offsets         = offsets_;
        rec_offs_init(offsets_);
  
@@ -848,52 +730,52 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
        rec = btr_cur_get_rec(cursor);
  
-@@ -1849,7 +1917,7 @@
+@@ -1862,7 +1918,7 @@
        } else {
                if (left_side) {
  
 -                      rw_lock_x_lock(&btr_search_latch);
-+                      rw_lock_x_lock(btr_search_get_latch(index_id));
++                      rw_lock_x_lock(btr_search_get_latch(index->id));
  
                        locked = TRUE;
  
-@@ -1863,7 +1931,7 @@
+@@ -1880,7 +1936,7 @@
  
                if (!locked) {
  
 -                      rw_lock_x_lock(&btr_search_latch);
-+                      rw_lock_x_lock(btr_search_get_latch(index_id));
++                      rw_lock_x_lock(btr_search_get_latch(index->id));
  
                        locked = TRUE;
-               }
-@@ -1881,7 +1949,7 @@
+@@ -1902,7 +1958,7 @@
                if (!left_side) {
  
                        if (!locked) {
 -                              rw_lock_x_lock(&btr_search_latch);
-+                              rw_lock_x_lock(btr_search_get_latch(index_id));
++                              rw_lock_x_lock(btr_search_get_latch(index->id));
  
                                locked = TRUE;
-                       }
-@@ -1896,7 +1964,7 @@
+@@ -1921,7 +1977,7 @@
  
                if (!locked) {
  
 -                      rw_lock_x_lock(&btr_search_latch);
-+                      rw_lock_x_lock(btr_search_get_latch(index_id));
++                      rw_lock_x_lock(btr_search_get_latch(index->id));
  
                        locked = TRUE;
-               }
-@@ -1919,7 +1987,7 @@
+@@ -1948,7 +2004,7 @@
                mem_heap_free(heap);
        }
        if (locked) {
 -              rw_lock_x_unlock(&btr_search_latch);
-+              rw_lock_x_unlock(btr_search_get_latch(index_id));
++              rw_lock_x_unlock(btr_search_get_latch(index->id));
        }
  }
  
-@@ -1935,7 +2003,7 @@
+@@ -1964,7 +2020,7 @@
        ha_node_t*      node;
        ulint           n_page_dumps    = 0;
        ibool           ok              = TRUE;
@@ -902,7 +784,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
        ulint           cell_count;
        mem_heap_t*     heap            = NULL;
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
-@@ -1947,23 +2015,25 @@
+@@ -1976,23 +2032,25 @@
  
        rec_offs_init(offsets_);
  
@@ -933,7 +815,7 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
  
                for (; node != NULL; node = node->next) {
                        const buf_block_t*      block
-@@ -2072,19 +2142,21 @@
+@@ -2099,19 +2157,21 @@
                give other queries a chance to run. */
                if (i != 0) {
                        buf_pool_page_hash_x_unlock_all();
@@ -959,42 +841,18 @@ diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
        if (UNIV_LIKELY_NULL(heap)) {
                mem_heap_free(heap);
        }
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c   2010-12-04 15:55:21.351597052 +0900
-+++ b/storage/innobase/buf/buf0buf.c   2010-12-04 16:12:48.654550708 +0900
-@@ -949,6 +949,7 @@
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
+@@ -960,6 +960,7 @@
  
        block->check_index_page_at_flush = FALSE;
        block->index = NULL;
 +      block->btr_search_latch = NULL;
  
-       block->is_hashed = FALSE;
-@@ -1477,7 +1478,7 @@
-                       /* To follow the latching order, we
-                       have to release btr_search_latch
-                       before acquiring block->latch. */
--                      rw_lock_x_unlock(&btr_search_latch);
-+                      btr_search_x_unlock_all();
-                       /* When we release the search latch,
-                       we must rescan all blocks, because
-                       some may become hashed again. */
-@@ -1508,11 +1509,11 @@
-                       anything.  block->is_hashed can only
-                       be set on uncompressed file pages. */
-                       
--                      btr_search_drop_page_hash_index(block);
-+                      btr_search_drop_page_hash_index(block, NULL);
-                       
-                       rw_lock_x_unlock(&block->lock);
-                       
--                      rw_lock_x_lock(&btr_search_latch);
-+                      btr_search_x_lock_all();
-                       
-                       ut_ad(!btr_search_enabled);
-               }
-@@ -1531,7 +1532,11 @@
-       ibool           released_search_latch;
+ #ifdef UNIV_DEBUG
+       block->page.in_page_hash = FALSE;
+@@ -1429,7 +1430,11 @@
+       ulint   p;
  
  #ifdef UNIV_SYNC_DEBUG
 -      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
@@ -1006,30 +864,48 @@ diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
  #endif /* UNIV_SYNC_DEBUG */
        ut_ad(!btr_search_enabled);
  
-@@ -2635,6 +2640,7 @@
+@@ -2144,6 +2149,7 @@
  {
        block->check_index_page_at_flush = FALSE;
        block->index            = NULL;
 +      block->btr_search_latch = NULL;
  
        block->n_hash_helps     = 0;
-       block->is_hashed        = FALSE;
-diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
---- a/storage/innobase/buf/buf0lru.c   2010-12-04 15:35:29.137347521 +0900
-+++ b/storage/innobase/buf/buf0lru.c   2010-12-04 16:12:48.658550840 +0900
-@@ -1775,7 +1775,7 @@
-               UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
-                              UNIV_PAGE_SIZE);
--              btr_search_drop_page_hash_index((buf_block_t*) bpage);
-+              btr_search_drop_page_hash_index((buf_block_t*) bpage, NULL);
-               UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
-                                UNIV_PAGE_SIZE);
-diff -ruN a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
---- a/storage/innobase/dict/dict0dict.c        2010-12-04 15:52:23.398513916 +0900
-+++ b/storage/innobase/dict/dict0dict.c        2010-12-04 16:12:48.662550715 +0900
-@@ -1806,7 +1806,7 @@
+       block->n_fields         = 1;
+--- a/storage/innobase/buf/buf0lru.c
++++ b/storage/innobase/buf/buf0lru.c
+@@ -576,7 +576,7 @@
+               mutex_exit(&buf_pool->LRU_list_mutex);
+-              rw_lock_s_lock(&btr_search_latch);
++              btr_search_s_lock_all();
+               chunk = buf_pool->chunks;
+               for (j = buf_pool->n_chunks; j--; chunk++) {
+                       buf_block_t*    block   = chunk->blocks;
+@@ -588,16 +588,16 @@
+                                       continue;
+                               }
+-                              rw_lock_s_unlock(&btr_search_latch);
++                              btr_search_s_unlock_all();
+                               rw_lock_x_lock(&block->lock);
+                               btr_search_drop_page_hash_index(block);
+                               rw_lock_x_unlock(&block->lock);
+-                              rw_lock_s_lock(&btr_search_latch);
++                              btr_search_s_lock_all();
+                       }
+               }
+-              rw_lock_s_unlock(&btr_search_latch);
++              btr_search_s_unlock_all();
+       }
+ }
+--- a/storage/innobase/dict/dict0dict.c
++++ b/storage/innobase/dict/dict0dict.c
+@@ -1851,7 +1851,7 @@
        zero. */
  
        for (;;) {
@@ -1038,45 +914,30 @@ diff -ruN a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.
                if (ref_count == 0) {
                        break;
                }
-diff -ruN a/storage/innobase/ha/ha0ha.c b/storage/innobase/ha/ha0ha.c
---- a/storage/innobase/ha/ha0ha.c      2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/ha/ha0ha.c      2010-12-04 16:12:48.665593752 +0900
-@@ -102,7 +102,8 @@
-       ut_ad(table);
-       ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
- #ifdef UNIV_SYNC_DEBUG
--      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
-+      /* cannot identificate which btr_search_latch[i] for now */
-+      //ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
- #endif /* UNIV_SYNC_DEBUG */
- #ifndef UNIV_HOTBACKUP
-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-04 16:12:20.185850734 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc    2010-12-04 16:12:48.674552412 +0900
-@@ -11617,6 +11617,11 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -11832,6 +11832,11 @@
    "Disable with --skip-innodb-adaptive-hash-index.",
    NULL, innodb_adaptive_hash_index_update, TRUE);
  
 +static MYSQL_SYSVAR_ULONG(adaptive_hash_index_partitions, btr_search_index_num,
 +  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 +  "Number of InnoDB adaptive hash index partitions (default 1: disable partitioning)",
-+  NULL, NULL, 1, 1, 32, 0);
++  NULL, NULL, 1, 1, sizeof(ulint) * 8, 0);
 +
  static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
    PLUGIN_VAR_RQCMDARG,
    "Replication thread delay (ms) on the slave server if "
-@@ -11964,6 +11969,7 @@
+@@ -12252,6 +12257,7 @@
    MYSQL_SYSVAR(use_sys_stats_table),
    MYSQL_SYSVAR(stats_sample_pages),
    MYSQL_SYSVAR(adaptive_hash_index),
 +  MYSQL_SYSVAR(adaptive_hash_index_partitions),
+   MYSQL_SYSVAR(stats_method),
    MYSQL_SYSVAR(replication_delay),
    MYSQL_SYSVAR(status_file),
-   MYSQL_SYSVAR(strict_mode),
-diff -ruN a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
---- a/storage/innobase/include/btr0sea.h       2010-12-03 15:48:03.070987226 +0900
-+++ b/storage/innobase/include/btr0sea.h       2010-12-04 16:12:48.707551382 +0900
+--- a/storage/innobase/include/btr0sea.h
++++ b/storage/innobase/include/btr0sea.h
 @@ -85,7 +85,8 @@
  ulint
  btr_search_info_get_ref_count(
@@ -1087,20 +948,7 @@ diff -ruN a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0se
  /*********************************************************************//**
  Updates the search info. */
  UNIV_INLINE
-@@ -136,10 +137,11 @@
- void
- btr_search_drop_page_hash_index(
- /*============================*/
--      buf_block_t*    block); /*!< in: block containing index page,
-+      buf_block_t*    block,  /*!< in: block containing index page,
-                               s- or x-latched, or an index page
-                               for which we know that
-                               block->buf_fix_count == 0 */
-+      dict_index_t*   index_in);
- /************************************************************************
- Drops a page hash index based on index */
- UNIV_INTERN
-@@ -199,10 +201,47 @@
+@@ -199,6 +200,40 @@
  # define btr_search_validate()        TRUE
  #endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
  
@@ -1138,17 +986,10 @@ diff -ruN a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0se
 +btr_search_s_unlock_all(void);
 +/*==========================*/
 +
-+
- /** Flag: has the search system been enabled?
- Protected by btr_search_latch and btr_search_enabled_mutex. */
- extern char   btr_search_enabled;
-+extern ulint  btr_search_index_num;
-+
- /** Flag: whether the search system has completed its disabling process,
- It is set to TRUE right after buf_pool_drop_hash_index() in
- btr_search_disable(), indicating hash index entries are cleaned up.
-@@ -269,7 +308,7 @@
+ /** The search info struct in an index */
+ struct btr_search_struct{
+       ulint   ref_count;      /*!< Number of blocks in this index tree
+@@ -259,7 +294,7 @@
  
  /** The hash index system */
  struct btr_search_sys_struct{
@@ -1157,24 +998,8 @@ diff -ruN a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0se
                                        mapping dtuple_fold values
                                        to rec_t pointers on index pages */
  };
-@@ -290,10 +329,12 @@
- Bear in mind (3) and (4) when using the hash index.
- */
--extern rw_lock_t*     btr_search_latch_temp;
-+//extern rw_lock_t*   btr_search_latch_temp;
-+
-+extern rw_lock_t**    btr_search_latch_part;
- /** The latch protecting the adaptive search system */
--#define btr_search_latch      (*btr_search_latch_temp)
-+//#define btr_search_latch    (*btr_search_latch_temp)
- #ifdef UNIV_SEARCH_PERF_STAT
- /** Number of successful adaptive hash index lookups */
-diff -ruN a/storage/innobase/include/btr0sea.ic b/storage/innobase/include/btr0sea.ic
---- a/storage/innobase/include/btr0sea.ic      2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/btr0sea.ic      2010-12-04 16:12:48.709511202 +0900
+--- a/storage/innobase/include/btr0sea.ic
++++ b/storage/innobase/include/btr0sea.ic
 @@ -62,8 +62,8 @@
        btr_search_t*   info;
  
@@ -1259,75 +1084,29 @@ diff -ruN a/storage/innobase/include/btr0sea.ic b/storage/innobase/include/btr0s
 +      }
 +}
 +
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h       2010-12-15 19:00:07.713604580 +0900
-+++ b/storage/innobase/include/buf0buf.h       2010-12-15 20:58:03.546839883 +0900
-@@ -1544,7 +1544,7 @@
-                                       pointers in the adaptive hash index
-                                       pointing to this frame */
- #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
--      unsigned        is_hashed:1;    /*!< TRUE if hash index has
-+      volatile unsigned       is_hashed:1;    /*!< TRUE if hash index has
-                                       already been built on this
-                                       page; note that it does not
-                                       guarantee that the index is
-@@ -1558,6 +1558,7 @@
-       unsigned        curr_left_side:1;/*!< TRUE or FALSE in hash indexing */
-       dict_index_t*   index;          /*!< Index for which the adaptive
-                                       hash index has been created. */
-+      volatile rw_lock_t*     btr_search_latch;
-       /* @} */
- # ifdef UNIV_SYNC_DEBUG
-       /** @name Debug fields */
-diff -ruN a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic
---- a/storage/innobase/include/row0upd.ic      2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/row0upd.ic      2010-12-04 16:12:48.710551113 +0900
-@@ -158,7 +158,7 @@
-       ut_ad(dict_index_is_clust(index));
-       ut_ad(rec_offs_validate(rec, index, offsets));
- #ifdef UNIV_SYNC_DEBUG
--      if (!rw_lock_own(&btr_search_latch, RW_LOCK_EX)) {
-+      if (!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_EX)) {
-               ut_ad(!buf_block_align(rec)->is_hashed);
-       }
- #endif /* UNIV_SYNC_DEBUG */
-diff -ruN a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c
---- a/storage/innobase/page/page0page.c        2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/page/page0page.c        2010-12-04 16:12:48.712550963 +0900
-@@ -218,7 +218,7 @@
-       const ibool     is_hashed       = block->is_hashed;
-       if (is_hashed) {
--              rw_lock_x_lock(&btr_search_latch);
-+              rw_lock_x_lock(btr_search_get_latch(block->index->id));
-       }
-       ut_ad(!mtr || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
-@@ -244,7 +244,7 @@
- #ifndef UNIV_HOTBACKUP
-       if (is_hashed) {
--              rw_lock_x_unlock(&btr_search_latch);
-+              rw_lock_x_unlock(btr_search_get_latch(block->index->id));
-       }
- #endif /* !UNIV_HOTBACKUP */
- }
-diff -ruN a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c
---- a/storage/innobase/page/page0zip.c 2010-12-04 15:57:13.061494433 +0900
-+++ b/storage/innobase/page/page0zip.c 2010-12-04 16:12:48.716470334 +0900
-@@ -4445,7 +4445,7 @@
- #ifndef UNIV_HOTBACKUP
-       temp_block = buf_block_alloc(buf_pool, 0);
--      btr_search_drop_page_hash_index(block);
-+      btr_search_drop_page_hash_index(block, index);
-       block->check_index_page_at_flush = TRUE;
- #else /* !UNIV_HOTBACKUP */
-       ut_ad(block == back_block1);
-diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
---- a/storage/innobase/row/row0sel.c   2010-12-04 16:09:53.204513572 +0900
-+++ b/storage/innobase/row/row0sel.c   2010-12-04 16:12:48.722551273 +0900
-@@ -1210,7 +1210,7 @@
+--- a/storage/innobase/row/row0mysql.c
++++ b/storage/innobase/row/row0mysql.c
+@@ -2594,7 +2594,7 @@
+                       /* check adaptive hash entries */
+                       index = dict_table_get_first_index(table);
+                       while (index) {
+-                              ulint ref_count = btr_search_info_get_ref_count(index->search_info);
++                              ulint ref_count = btr_search_info_get_ref_count(index->search_info, index->id);
+                               if (ref_count) {
+                                       fprintf(stderr, "InnoDB: Warning:"
+                                               " hash index ref_count (%lu) is not zero"
+@@ -2955,7 +2955,7 @@
+                       table->space = space;
+                       index = dict_table_get_first_index(table);
+                       do {
+-                              ulint ref_count = btr_search_info_get_ref_count(index->search_info);
++                              ulint ref_count = btr_search_info_get_ref_count(index->search_info, index->id);
+                               /* check adaptive hash entries */
+                               if (ref_count) {
+                                       fprintf(stderr, "InnoDB: Warning:"
+--- a/storage/innobase/row/row0sel.c
++++ b/storage/innobase/row/row0sel.c
+@@ -1222,7 +1222,7 @@
        ut_ad(plan->unique_search);
        ut_ad(!plan->must_get_clust);
  #ifdef UNIV_SYNC_DEBUG
@@ -1336,7 +1115,7 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
  #endif /* UNIV_SYNC_DEBUG */
  
        row_sel_open_pcur(plan, TRUE, mtr);
-@@ -1381,10 +1381,10 @@
+@@ -1393,10 +1393,10 @@
            && !plan->must_get_clust
            && !plan->table->big_rows) {
                if (!search_latch_locked) {
@@ -1349,7 +1128,7 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
  
                        /* There is an x-latch request waiting: release the
                        s-latch for a moment; as an s-latch here is often
-@@ -1393,8 +1393,8 @@
+@@ -1405,8 +1405,8 @@
                        from acquiring an s-latch for a long time, lowering
                        performance significantly in multiprocessors. */
  
@@ -1360,7 +1139,7 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
                }
  
                found_flag = row_sel_try_search_shortcut(node, plan, &mtr);
-@@ -1417,7 +1417,7 @@
+@@ -1429,7 +1429,7 @@
        }
  
        if (search_latch_locked) {
@@ -1369,7 +1148,7 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
  
                search_latch_locked = FALSE;
        }
-@@ -1993,7 +1993,7 @@
+@@ -2005,7 +2005,7 @@
  
  func_exit:
        if (search_latch_locked) {
@@ -1378,7 +1157,7 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
        }
        if (UNIV_LIKELY_NULL(heap)) {
                mem_heap_free(heap);
-@@ -3356,6 +3356,8 @@
+@@ -3408,6 +3408,8 @@
        /* if the returned record was locked and we did a semi-consistent
        read (fetch the newest committed version), then this is set to
        TRUE */
@@ -1387,7 +1166,7 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
  #ifdef UNIV_SEARCH_DEBUG
        ulint           cnt                             = 0;
  #endif /* UNIV_SEARCH_DEBUG */
-@@ -3441,18 +3443,32 @@
+@@ -3505,18 +3507,33 @@
        /* PHASE 0: Release a possible s-latch we are holding on the
        adaptive hash index latch if there is someone waiting behind */
  
@@ -1395,9 +1174,9 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
 -          && trx->has_search_latch) {
 +      should_release = 0;
 +      for (i = 0; i < btr_search_index_num; i++) {
-+              if ((trx->has_search_latch & ((ulint)1 << i))
-+                  && rw_lock_get_writer(btr_search_latch_part[i])
-+                              != RW_LOCK_NOT_LOCKED) {
++              /* we should check all latches (fix Bug#791030) */
++              if (rw_lock_get_writer(btr_search_latch_part[i])
++                  != RW_LOCK_NOT_LOCKED) {
 +                      should_release |= ((ulint)1 << i);
 +              }
 +      }
@@ -1412,9 +1191,10 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
 -              rw_lock_s_unlock(&btr_search_latch);
 -              trx->has_search_latch = FALSE;
 +              for (i = 0; i < btr_search_index_num; i++) {
-+                      if (should_release & ((ulint)1 << i)) {
++                      /* we should release all s-latches (fix Bug#791030) */
++                      if (trx->has_search_latch & ((ulint)1 << i)) {
 +                              rw_lock_s_unlock(btr_search_latch_part[i]);
-+                              trx->has_search_latch &= ~((ulint)1 << i);
++                              trx->has_search_latch &= (~((ulint)1 << i));
 +                      }
 +              }
  
@@ -1424,7 +1204,7 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
        }
  
        /* Reset the new record lock info if srv_locks_unsafe_for_binlog
-@@ -3603,9 +3619,11 @@
+@@ -3667,9 +3684,28 @@
                        hash index semaphore! */
  
  #ifndef UNIV_SEARCH_DEBUG
@@ -1433,13 +1213,30 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
 -                              trx->has_search_latch = TRUE;
 +                      if (!(trx->has_search_latch
 +                            & ((ulint)1 << (index->id % btr_search_index_num)))) {
-+                              rw_lock_s_lock(btr_search_get_latch(index->id));
-+                              trx->has_search_latch |=
-+                                      (ulint)1 << (index->id % btr_search_index_num);
++                              if (trx->has_search_latch
++                                  < ((ulint)1 << (index->id % btr_search_index_num))) {
++                                      rw_lock_s_lock(btr_search_get_latch(index->id));
++                                      trx->has_search_latch |=
++                                              ((ulint)1 << (index->id % btr_search_index_num));
++                              } else {
++                                      /* should re-lock to obay latch-order */
++                                      for (i = 0; i < btr_search_index_num; i++) {
++                                              if (trx->has_search_latch & ((ulint)1 << i)) {
++                                                      rw_lock_s_unlock(btr_search_latch_part[i]);
++                                              }
++                                      }
++                                      trx->has_search_latch |=
++                                              ((ulint)1 << (index->id % btr_search_index_num));
++                                      for (i = 0; i < btr_search_index_num; i++) {
++                                              if (trx->has_search_latch & ((ulint)1 << i)) {
++                                                      rw_lock_s_lock(btr_search_latch_part[i]);
++                                              }
++                                      }
++                              }
                        }
  #endif
                        switch (row_sel_try_search_shortcut_for_mysql(
-@@ -3666,7 +3684,11 @@
+@@ -3730,7 +3766,11 @@
  
                                        trx->search_latch_timeout--;
  
@@ -1452,7 +1249,7 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
                                        trx->has_search_latch = FALSE;
                                }
  
-@@ -3690,7 +3712,12 @@
+@@ -3754,7 +3794,12 @@
        /* PHASE 3: Open or restore index cursor position */
  
        if (trx->has_search_latch) {
@@ -1466,10 +1263,9 @@ diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
                trx->has_search_latch = FALSE;
        }
  
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c   2010-12-04 16:12:20.231484679 +0900
-+++ b/storage/innobase/srv/srv0srv.c   2010-12-04 16:12:48.726551018 +0900
-@@ -2042,7 +2042,9 @@
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
+@@ -2054,7 +2054,9 @@
              "-------------------------------------\n", file);
        ibuf_print(file);
  
@@ -1480,7 +1276,7 @@ diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
  
        fprintf(file,
                "%.2f hash searches/s, %.2f non-hash searches/s\n",
-@@ -2067,14 +2069,15 @@
+@@ -2079,14 +2081,15 @@
                        ut_total_allocated_memory,
                        mem_pool_get_reserved(mem_comm_pool));
        /* Calcurate reserved memories */
@@ -1500,8 +1296,8 @@ diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
  
        lock_sys_subtotal = 0;
        if (trx_sys) {
-@@ -2101,10 +2104,10 @@
-                       "    Threads             %lu \t(%lu + %lu)\n",
+@@ -2112,10 +2115,10 @@
+                       "    Recovery system     %lu \t(%lu + %lu)\n",
  
                        (ulong) (btr_search_sys
 -                              ? (btr_search_sys->hash_index->n_cells * sizeof(hash_cell_t)) : 0)
@@ -1513,29 +1309,9 @@ diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
                        (ulong) btr_search_sys_subtotal,
  
                        (ulong) (buf_pool_from_array(0)->page_hash->n_cells * sizeof(hash_cell_t)),
-diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
---- a/storage/innobase/sync/sync0sync.c        2010-12-03 17:36:44.300986571 +0900
-+++ b/storage/innobase/sync/sync0sync.c        2010-12-04 16:12:48.729513564 +0900
-@@ -1183,7 +1183,6 @@
-       case SYNC_ANY_LATCH:
-       case SYNC_FILE_FORMAT_TAG:
-       case SYNC_DOUBLEWRITE:
--      case SYNC_SEARCH_SYS:
-       case SYNC_SEARCH_SYS_CONF:
-       case SYNC_TRX_LOCK_HEAP:
-       case SYNC_KERNEL:
-@@ -1204,6 +1203,7 @@
-                       ut_error;
-               }
-               break;
-+      case SYNC_SEARCH_SYS:
-       case SYNC_BUF_LRU_LIST:
-       case SYNC_BUF_FLUSH_LIST:
-       case SYNC_BUF_PAGE_HASH:
-diff -ruN a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
---- a/storage/innobase/trx/trx0trx.c   2010-12-03 17:49:11.623953784 +0900
-+++ b/storage/innobase/trx/trx0trx.c   2010-12-04 16:12:48.731513275 +0900
-@@ -266,8 +266,14 @@
+--- a/storage/innobase/trx/trx0trx.c
++++ b/storage/innobase/trx/trx0trx.c
+@@ -265,8 +265,14 @@
  /*=================================*/
        trx_t*     trx) /*!< in: transaction */
  {
@@ -1551,3 +1327,113 @@ diff -ruN a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
  
                trx->has_search_latch = FALSE;
        }
+--- a/storage/innobase/include/btr0types.h
++++ b/storage/innobase/include/btr0types.h
+@@ -52,15 +52,19 @@
+ Bear in mind (3) and (4) when using the hash index.
+ */
+-extern rw_lock_t*     btr_search_latch_temp;
++//extern rw_lock_t*   btr_search_latch_temp;
++
++extern rw_lock_t**    btr_search_latch_part;
+ /** The latch protecting the adaptive search system */
+-#define btr_search_latch      (*btr_search_latch_temp)
++//#define btr_search_latch    (*btr_search_latch_temp)
+ /** Flag: has the search system been enabled?
+ Protected by btr_search_latch. */
+ extern char   btr_search_enabled;
++extern ulint  btr_search_index_num;
++
+ #ifdef UNIV_BLOB_DEBUG
+ # include "buf0types.h"
+ /** An index->blobs entry for keeping track of off-page column references */
+--- a/storage/innobase/ha/ha0ha.c
++++ b/storage/innobase/ha/ha0ha.c
+@@ -120,7 +120,7 @@
+       ut_a(block->frame == page_align(data));
+ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+ #ifdef UNIV_SYNC_DEBUG
+-      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
++      ut_ad(rw_lock_own(block->btr_search_latch, RW_LOCK_EX));
+ #endif /* UNIV_SYNC_DEBUG */
+       ASSERT_HASH_MUTEX_OWN(table, fold);
+       ut_ad(btr_search_enabled);
+@@ -213,7 +213,7 @@
+       ut_ad(table);
+       ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
+ #ifdef UNIV_SYNC_DEBUG
+-      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
++      //      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
+ #endif /* UNIV_SYNC_DEBUG */
+       ut_ad(btr_search_enabled);
+ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+@@ -253,7 +253,7 @@
+       ut_a(new_block->frame == page_align(new_data));
+ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+ #ifdef UNIV_SYNC_DEBUG
+-      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
++      //      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
+ #endif /* UNIV_SYNC_DEBUG */
+       if (!btr_search_enabled) {
+@@ -296,7 +296,7 @@
+       ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
+       ASSERT_HASH_MUTEX_OWN(table, fold);
+ #ifdef UNIV_SYNC_DEBUG
+-      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
++      //      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
+ #endif /* UNIV_SYNC_DEBUG */
+       ut_ad(btr_search_enabled);
+--- a/storage/innobase/include/ha0ha.ic
++++ b/storage/innobase/include/ha0ha.ic
+@@ -121,7 +121,7 @@
+       ASSERT_HASH_MUTEX_OWN(table, fold);
+ #ifdef UNIV_SYNC_DEBUG
+-      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
++//    ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
+ #endif /* UNIV_SYNC_DEBUG */
+       ut_ad(btr_search_enabled);
+@@ -186,7 +186,7 @@
+       ASSERT_HASH_MUTEX_OWN(table, fold);
+ #ifdef UNIV_SYNC_DEBUG
+-      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
++//    ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
+ #endif /* UNIV_SYNC_DEBUG */
+       ut_ad(btr_search_enabled);
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -1600,6 +1600,7 @@
+                                       complete, though: there may
+                                       have been hash collisions,
+                                       record deletions, etc. */
++      volatile rw_lock_t*     btr_search_latch;
+       /* @} */
+ # ifdef UNIV_SYNC_DEBUG
+       /** @name Debug fields */
+--- a/storage/innobase/sync/sync0sync.c
++++ b/storage/innobase/sync/sync0sync.c
+@@ -1222,7 +1222,6 @@
+       case SYNC_OUTER_ANY_LATCH:
+       case SYNC_FILE_FORMAT_TAG:
+       case SYNC_DOUBLEWRITE:
+-      case SYNC_SEARCH_SYS:
+       case SYNC_TRX_LOCK_HEAP:
+       case SYNC_KERNEL:
+       case SYNC_IBUF_BITMAP_MUTEX:
+@@ -1243,6 +1242,7 @@
+                       ut_error;
+               }
+               break;
++      case SYNC_SEARCH_SYS:
+       case SYNC_BUF_LRU_LIST:
+       case SYNC_BUF_FLUSH_LIST:
+       case SYNC_BUF_PAGE_HASH:
This page took 0.1172 seconds and 4 git commands to generate.