]> git.pld-linux.org Git - packages/mysql.git/blob - innodb_adaptive_hash_index_partitions.patch
add ignore-builtin-innodb sample and comments
[packages/mysql.git] / innodb_adaptive_hash_index_partitions.patch
1 # name       : innodb_adaptive_hash_index_num.patch
2 # introduced : XtraDB on 5.5 (-13?)
3 # maintainer : Yasufumi
4 #
5 #!!! notice !!!
6 # Any small change to this file in the main branch
7 # should be done or reviewed by the maintainer!
8 --- a/storage/innobase/btr/btr0cur.c
9 +++ b/storage/innobase/btr/btr0cur.c
10 @@ -500,7 +500,7 @@
11  #ifdef UNIV_SEARCH_PERF_STAT
12         info->n_searches++;
13  #endif
14 -       if (rw_lock_get_writer(&btr_search_latch) == RW_LOCK_NOT_LOCKED
15 +       if (rw_lock_get_writer(btr_search_get_latch(cursor->index->id)) == RW_LOCK_NOT_LOCKED
16             && latch_mode <= BTR_MODIFY_LEAF
17             && info->last_hash_succ
18             && !estimate
19 @@ -536,7 +536,7 @@
20  
21         if (has_search_latch) {
22                 /* Release possible search latch to obey latching order */
23 -               rw_lock_s_unlock(&btr_search_latch);
24 +               rw_lock_s_unlock(btr_search_get_latch(cursor->index->id));
25         }
26  
27         /* Store the position of the tree latch we push to mtr so that we
28 @@ -847,7 +847,7 @@
29  
30         if (has_search_latch) {
31  
32 -               rw_lock_s_lock(&btr_search_latch);
33 +               rw_lock_s_lock(btr_search_get_latch(cursor->index->id));
34         }
35  }
36  
37 @@ -1977,13 +1977,13 @@
38                         btr_search_update_hash_on_delete(cursor);
39                 }
40  
41 -               rw_lock_x_lock(&btr_search_latch);
42 +               rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
43         }
44  
45         row_upd_rec_in_place(rec, index, offsets, update, page_zip);
46  
47         if (is_hashed) {
48 -               rw_lock_x_unlock(&btr_search_latch);
49 +               rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
50         }
51  
52         if (page_zip && !dict_index_is_clust(index)
53 --- a/storage/innobase/btr/btr0sea.c
54 +++ b/storage/innobase/btr/btr0sea.c
55 @@ -47,6 +47,8 @@
56  Protected by btr_search_latch. */
57  UNIV_INTERN char               btr_search_enabled      = TRUE;
58  
59 +UNIV_INTERN ulint              btr_search_index_num    = 1;
60 +
61  #ifdef UNIV_PFS_MUTEX
62  /* Key to register btr_search_enabled_mutex with performance schema */
63  UNIV_INTERN mysql_pfs_key_t    btr_search_enabled_mutex_key;
64 @@ -75,7 +77,9 @@
65  
66  /* We will allocate the latch from dynamic memory to get it to the
67  same DRAM page as other hotspot semaphores */
68 -UNIV_INTERN rw_lock_t*         btr_search_latch_temp;
69 +//UNIV_INTERN rw_lock_t*               btr_search_latch_temp;
70 +
71 +UNIV_INTERN rw_lock_t**                btr_search_latch_part;
72  
73  /** padding to prevent other memory update hotspots from residing on
74  the same memory cache line */
75 @@ -127,18 +131,19 @@
76  will not guarantee success. */
77  static
78  void
79 -btr_search_check_free_space_in_heap(void)
80 +btr_search_check_free_space_in_heap(
81  /*=====================================*/
82 +       index_id_t      key)
83  {
84         hash_table_t*   table;
85         mem_heap_t*     heap;
86  
87  #ifdef UNIV_SYNC_DEBUG
88 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
89 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
90 +       ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_SHARED));
91 +       ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_EX));
92  #endif /* UNIV_SYNC_DEBUG */
93  
94 -       table = btr_search_sys->hash_index;
95 +       table = btr_search_get_hash_index(key);
96  
97         heap = table->heap;
98  
99 @@ -149,7 +154,7 @@
100         if (heap->free_block == NULL) {
101                 buf_block_t*    block = buf_block_alloc(NULL);
102  
103 -               rw_lock_x_lock(&btr_search_latch);
104 +               rw_lock_x_lock(btr_search_get_latch(key));
105  
106                 if (heap->free_block == NULL) {
107                         heap->free_block = block;
108 @@ -157,7 +162,7 @@
109                         buf_block_free(block);
110                 }
111  
112 -               rw_lock_x_unlock(&btr_search_latch);
113 +               rw_lock_x_unlock(btr_search_get_latch(key));
114         }
115  }
116  
117 @@ -169,17 +174,28 @@
118  /*==================*/
119         ulint   hash_size)      /*!< in: hash index hash table size */
120  {
121 +       ulint i;
122         /* We allocate the search latch from dynamic memory:
123         see above at the global variable definition */
124  
125 -       btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
126 +       //btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
127  
128 -       rw_lock_create(btr_search_latch_key, &btr_search_latch,
129 -                      SYNC_SEARCH_SYS);
130 +       //rw_lock_create(btr_search_latch_key, &btr_search_latch,
131 +       //             SYNC_SEARCH_SYS);
132  
133         btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
134  
135 -       btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
136 +       /* btr_search_index_num should be <= 32. (bits of trx->has_search_latch) */
137 +       btr_search_latch_part = mem_alloc(sizeof(rw_lock_t*) * btr_search_index_num);
138 +       btr_search_sys->hash_index = mem_alloc(sizeof(hash_table_t*) * btr_search_index_num);
139 +       for (i = 0; i < btr_search_index_num; i++) {
140 +               btr_search_latch_part[i] = mem_alloc(sizeof(rw_lock_t));
141 +
142 +               rw_lock_create(btr_search_latch_key,
143 +                               btr_search_latch_part[i], SYNC_SEARCH_SYS);
144 +
145 +               btr_search_sys->hash_index[i] = ha_create(hash_size, 0, 0);
146 +       }
147  }
148  
149  /*****************************************************************//**
150 @@ -189,11 +205,22 @@
151  btr_search_sys_free(void)
152  /*=====================*/
153  {
154 -       rw_lock_free(&btr_search_latch);
155 -       mem_free(btr_search_latch_temp);
156 -       btr_search_latch_temp = NULL;
157 -       mem_heap_free(btr_search_sys->hash_index->heap);
158 -       hash_table_free(btr_search_sys->hash_index);
159 +       ulint i;
160 +
161 +       for (i = 0; i < btr_search_index_num; i++) {
162 +               mem_heap_free(btr_search_sys->hash_index[i]->heap);
163 +               hash_table_free(btr_search_sys->hash_index[i]);
164 +
165 +               rw_lock_free(btr_search_latch_part[i]);
166 +
167 +               mem_free(btr_search_latch_part[i]);
168 +       }
169 +       mem_free(btr_search_sys->hash_index);
170 +       mem_free(btr_search_latch_part);
171 +
172 +       //rw_lock_free(&btr_search_latch);
173 +       //mem_free(btr_search_latch_temp);
174 +       //btr_search_latch_temp = NULL;
175         mem_free(btr_search_sys);
176         btr_search_sys = NULL;
177  }
178 @@ -206,9 +233,10 @@
179  /*====================*/
180  {
181         dict_table_t*   table;
182 +       ulint i;
183  
184         mutex_enter(&dict_sys->mutex);
185 -       rw_lock_x_lock(&btr_search_latch);
186 +       btr_search_x_lock_all();
187  
188         btr_search_enabled = FALSE;
189  
190 @@ -232,10 +260,12 @@
191         buf_pool_clear_hash_index();
192  
193         /* Clear the adaptive hash index. */
194 -       hash_table_clear(btr_search_sys->hash_index);
195 -       mem_heap_empty(btr_search_sys->hash_index->heap);
196 +       for (i = 0; i < btr_search_index_num; i++) {
197 +               hash_table_clear(btr_search_sys->hash_index[i]);
198 +               mem_heap_empty(btr_search_sys->hash_index[i]->heap);
199 +       }
200  
201 -       rw_lock_x_unlock(&btr_search_latch);
202 +       btr_search_x_unlock_all();
203  }
204  
205  /********************************************************************//**
206 @@ -245,11 +275,11 @@
207  btr_search_enable(void)
208  /*====================*/
209  {
210 -       rw_lock_x_lock(&btr_search_latch);
211 +       btr_search_x_lock_all();
212  
213         btr_search_enabled = TRUE;
214  
215 -       rw_lock_x_unlock(&btr_search_latch);
216 +       btr_search_x_unlock_all();
217  }
218  
219  /*****************************************************************//**
220 @@ -301,20 +331,21 @@
221  ulint
222  btr_search_info_get_ref_count(
223  /*==========================*/
224 -       btr_search_t*   info)   /*!< in: search info. */
225 +       btr_search_t*   info,   /*!< in: search info. */
226 +       index_id_t      key)
227  {
228         ulint ret;
229  
230         ut_ad(info);
231  
232  #ifdef UNIV_SYNC_DEBUG
233 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
234 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
235 +       ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_SHARED));
236 +       ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_EX));
237  #endif /* UNIV_SYNC_DEBUG */
238  
239 -       rw_lock_s_lock(&btr_search_latch);
240 +       rw_lock_s_lock(btr_search_get_latch(key));
241         ret = info->ref_count;
242 -       rw_lock_s_unlock(&btr_search_latch);
243 +       rw_lock_s_unlock(btr_search_get_latch(key));
244  
245         return(ret);
246  }
247 @@ -335,8 +366,8 @@
248         int             cmp;
249  
250  #ifdef UNIV_SYNC_DEBUG
251 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
252 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
253 +       ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));
254 +       ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
255  #endif /* UNIV_SYNC_DEBUG */
256  
257         index = cursor->index;
258 @@ -454,8 +485,8 @@
259                                 /*!< in: cursor */
260  {
261  #ifdef UNIV_SYNC_DEBUG
262 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
263 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
264 +       ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));
265 +       ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
266         ut_ad(rw_lock_own(&block->lock, RW_LOCK_SHARED)
267               || rw_lock_own(&block->lock, RW_LOCK_EX));
268  #endif /* UNIV_SYNC_DEBUG */
269 @@ -539,7 +570,7 @@
270  
271         ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
272  #ifdef UNIV_SYNC_DEBUG
273 -       ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
274 +       ut_ad(rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
275         ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
276               || rw_lock_own(&(block->lock), RW_LOCK_EX));
277  #endif /* UNIV_SYNC_DEBUG */
278 @@ -580,10 +611,10 @@
279                         mem_heap_free(heap);
280                 }
281  #ifdef UNIV_SYNC_DEBUG
282 -               ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
283 +               ut_ad(rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
284  #endif /* UNIV_SYNC_DEBUG */
285  
286 -               ha_insert_for_fold(btr_search_sys->hash_index, fold,
287 +               ha_insert_for_fold(btr_search_get_hash_index(cursor->index->id), fold,
288                                    block, rec);
289         }
290  }
291 @@ -603,8 +634,8 @@
292         ulint*          params2;
293  
294  #ifdef UNIV_SYNC_DEBUG
295 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
296 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
297 +       ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));
298 +       ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
299  #endif /* UNIV_SYNC_DEBUG */
300  
301         block = btr_cur_get_block(cursor);
302 @@ -625,7 +656,7 @@
303  
304         if (build_index || (cursor->flag == BTR_CUR_HASH_FAIL)) {
305  
306 -               btr_search_check_free_space_in_heap();
307 +               btr_search_check_free_space_in_heap(cursor->index->id);
308         }
309  
310         if (cursor->flag == BTR_CUR_HASH_FAIL) {
311 @@ -635,11 +666,11 @@
312                 btr_search_n_hash_fail++;
313  #endif /* UNIV_SEARCH_PERF_STAT */
314  
315 -               rw_lock_x_lock(&btr_search_latch);
316 +               rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
317  
318                 btr_search_update_hash_ref(info, block, cursor);
319  
320 -               rw_lock_x_unlock(&btr_search_latch);
321 +               rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
322         }
323  
324         if (build_index) {
325 @@ -884,17 +915,17 @@
326         cursor->flag = BTR_CUR_HASH;
327  
328         if (UNIV_LIKELY(!has_search_latch)) {
329 -               rw_lock_s_lock(&btr_search_latch);
330 +               rw_lock_s_lock(btr_search_get_latch(index_id));
331  
332                 if (UNIV_UNLIKELY(!btr_search_enabled)) {
333                         goto failure_unlock;
334                 }
335         }
336  
337 -       ut_ad(rw_lock_get_writer(&btr_search_latch) != RW_LOCK_EX);
338 -       ut_ad(rw_lock_get_reader_count(&btr_search_latch) > 0);
339 +       ut_ad(rw_lock_get_writer(btr_search_get_latch(index_id)) != RW_LOCK_EX);
340 +       ut_ad(rw_lock_get_reader_count(btr_search_get_latch(index_id)) > 0);
341  
342 -       rec = ha_search_and_get_data(btr_search_sys->hash_index, fold);
343 +       rec = ha_search_and_get_data(btr_search_get_hash_index(index_id), fold);
344  
345         if (UNIV_UNLIKELY(!rec)) {
346                 goto failure_unlock;
347 @@ -912,7 +943,7 @@
348                         goto failure_unlock;
349                 }
350  
351 -               rw_lock_s_unlock(&btr_search_latch);
352 +               rw_lock_s_unlock(btr_search_get_latch(index_id));
353  
354                 buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
355         }
356 @@ -1009,7 +1040,7 @@
357         /*-------------------------------------------*/
358  failure_unlock:
359         if (UNIV_LIKELY(!has_search_latch)) {
360 -               rw_lock_s_unlock(&btr_search_latch);
361 +               rw_lock_s_unlock(btr_search_get_latch(index_id));
362         }
363  failure:
364         cursor->flag = BTR_CUR_HASH_FAIL;
365 @@ -1053,24 +1084,49 @@
366         const dict_index_t*     index;
367         ulint*                  offsets;
368  
369 -#ifdef UNIV_SYNC_DEBUG
370 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
371 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
372 -#endif /* UNIV_SYNC_DEBUG */
373 -
374  retry:
375 -       rw_lock_s_lock(&btr_search_latch);
376 -       index = block->index;
377 +       if (btr_search_index_num > 1) {
378 +               rw_lock_t*      btr_search_latch;
379 +
380 +               /* FIXME: This may be optimistic implementation still. */
381 +               btr_search_latch = (rw_lock_t*)(block->btr_search_latch);
382 +               if (UNIV_LIKELY(!btr_search_latch)) {
383 +                       if (block->index) {
384 +                               goto retry;
385 +                       }
386 +                       return;
387 +               }
388 +               rw_lock_s_lock(btr_search_latch);
389 +               if (UNIV_LIKELY(btr_search_latch != block->btr_search_latch)) {
390 +                       rw_lock_s_unlock(btr_search_latch);
391 +                       goto retry;
392 +               }
393 +               if (UNIV_LIKELY(!block->index)) {
394 +                       rw_lock_s_unlock(btr_search_latch);
395 +                       goto retry;
396 +               }
397 +               index = block->index;
398 +               ut_a(btr_search_latch == btr_search_get_latch(index->id));
399 +       } else {
400 +               /* btr_search_index_num == 1 */
401 +               /* btr_search_latch is only one and able to obtain
402 +                  before evaluating block->index. */
403 +               rw_lock_s_lock(btr_search_latch_part[0]);
404 +               if (UNIV_LIKELY(!block->index)) {
405 +                       rw_lock_s_unlock(btr_search_latch_part[0]);
406 +                       return;
407 +               }
408 +               index = block->index;
409 +       }
410  
411         if (UNIV_LIKELY(!index)) {
412  
413 -               rw_lock_s_unlock(&btr_search_latch);
414 +               rw_lock_s_unlock(btr_search_get_latch(index->id));
415  
416                 return;
417         }
418  
419 -       ut_a(!dict_index_is_ibuf(index));
420 -       table = btr_search_sys->hash_index;
421 +       table = btr_search_get_hash_index(index->id);
422  
423  #ifdef UNIV_SYNC_DEBUG
424         ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
425 @@ -1080,12 +1136,14 @@
426  
427         n_fields = block->curr_n_fields;
428         n_bytes = block->curr_n_bytes;
429 +       ut_a(index == block->index);
430 +       ut_a(!dict_index_is_ibuf(index));
431  
432         /* NOTE: The fields of block must not be accessed after
433         releasing btr_search_latch, as the index page might only
434         be s-latched! */
435  
436 -       rw_lock_s_unlock(&btr_search_latch);
437 +       rw_lock_s_unlock(btr_search_get_latch(index->id));
438  
439         ut_a(n_fields + n_bytes > 0);
440  
441 @@ -1136,7 +1194,7 @@
442                 mem_heap_free(heap);
443         }
444  
445 -       rw_lock_x_lock(&btr_search_latch);
446 +       rw_lock_x_lock(btr_search_get_latch(index->id));
447  
448         if (UNIV_UNLIKELY(!block->index)) {
449                 /* Someone else has meanwhile dropped the hash index */
450 @@ -1152,7 +1210,7 @@
451                 /* Someone else has meanwhile built a new hash index on the
452                 page, with different parameters */
453  
454 -               rw_lock_x_unlock(&btr_search_latch);
455 +               rw_lock_x_unlock(btr_search_get_latch(index->id));
456  
457                 mem_free(folds);
458                 goto retry;
459 @@ -1167,6 +1225,7 @@
460         index->search_info->ref_count--;
461  
462         block->index = NULL;
463 +       block->btr_search_latch = NULL;
464  
465  cleanup:
466  #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
467 @@ -1179,14 +1238,14 @@
468                         "InnoDB: the hash index to a page of %s,"
469                         " still %lu hash nodes remain.\n",
470                         index->name, (ulong) block->n_pointers);
471 -               rw_lock_x_unlock(&btr_search_latch);
472 +               rw_lock_x_unlock(btr_search_get_latch(index->id));
473  
474                 btr_search_validate();
475         } else {
476 -               rw_lock_x_unlock(&btr_search_latch);
477 +               rw_lock_x_unlock(btr_search_get_latch(index->id));
478         }
479  #else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
480 -       rw_lock_x_unlock(&btr_search_latch);
481 +       rw_lock_x_unlock(btr_search_get_latch(index->id));
482  #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
483  
484         mem_free(folds);
485 @@ -1218,9 +1277,9 @@
486         ulint*          offsets;
487         ibool           released_search_latch;
488  
489 -       rw_lock_s_lock(&btr_search_latch);
490 +       rw_lock_s_lock(btr_search_get_latch(index->id));
491  
492 -       table = btr_search_sys->hash_index;
493 +       table = btr_search_get_hash_index(index->id);
494  
495         for (j = 0; j < srv_buf_pool_instances; j++) {
496                 buf_pool_t*     buf_pool;
497 @@ -1254,7 +1313,7 @@
498  
499  
500                                         /* keeping latch order */
501 -                                       rw_lock_s_unlock(&btr_search_latch);
502 +                                       rw_lock_s_unlock(btr_search_get_latch(index->id));
503                                         released_search_latch = TRUE;
504                                         rw_lock_x_lock(&block->lock);
505  
506 @@ -1306,7 +1365,7 @@
507                                                 mem_heap_empty(heap);
508                                         }
509  
510 -                                       rw_lock_x_lock(&btr_search_latch);
511 +                                       rw_lock_x_lock(btr_search_get_latch(index->id));
512  
513                                         if (UNIV_UNLIKELY(!block->index)) {
514                                                 goto cleanup;
515 @@ -1316,12 +1375,12 @@
516  
517                                         if (UNIV_UNLIKELY(block->curr_n_fields != n_fields)
518                                             || UNIV_UNLIKELY(block->curr_n_bytes != n_bytes)) {
519 -                                               rw_lock_x_unlock(&btr_search_latch);
520 +                                               rw_lock_x_unlock(btr_search_get_latch(index->id));
521                                                 rw_lock_x_unlock(&block->lock);
522  
523                                                 mem_free(folds);
524  
525 -                                               rw_lock_s_lock(&btr_search_latch);
526 +                                               rw_lock_s_lock(btr_search_get_latch(index->id));
527                                                 goto retry;
528                                         }
529  
530 @@ -1334,6 +1393,7 @@
531                                         index->search_info->ref_count--;
532  
533                                         block->index = NULL;
534 +                                       block->btr_search_latch = NULL;
535  
536  cleanup:
537  #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
538 @@ -1346,18 +1406,18 @@
539                                                         index->name, (ulong) block->n_pointers);
540                                         }
541  #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
542 -                                       rw_lock_x_unlock(&btr_search_latch);
543 +                                       rw_lock_x_unlock(btr_search_get_latch(index->id));
544                                         rw_lock_x_unlock(&block->lock);
545  
546                                         mem_free(folds);
547  
548 -                                       rw_lock_s_lock(&btr_search_latch);
549 +                                       rw_lock_s_lock(btr_search_get_latch(index->id));
550                                 }
551                         }
552                 } while (released_search_latch);
553         }
554  
555 -       rw_lock_s_unlock(&btr_search_latch);
556 +       rw_lock_s_unlock(btr_search_get_latch(index->id));
557  
558         if (UNIV_LIKELY_NULL(heap)) {
559                 mem_heap_free(heap);
560 @@ -1436,31 +1496,26 @@
561         ut_ad(index);
562         ut_a(!dict_index_is_ibuf(index));
563  
564 +       table = btr_search_get_hash_index(index->id);
565 +       page = buf_block_get_frame(block);
566 +
567  #ifdef UNIV_SYNC_DEBUG
568 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
569 +       ut_ad(!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_EX));
570         ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
571               || rw_lock_own(&(block->lock), RW_LOCK_EX));
572  #endif /* UNIV_SYNC_DEBUG */
573  
574 -       rw_lock_s_lock(&btr_search_latch);
575 -
576 -       if (!btr_search_enabled) {
577 -               rw_lock_s_unlock(&btr_search_latch);
578 -               return;
579 -       }
580 -
581 -       table = btr_search_sys->hash_index;
582 -       page = buf_block_get_frame(block);
583 +       rw_lock_s_lock(btr_search_get_latch(index->id));
584  
585         if (block->index && ((block->curr_n_fields != n_fields)
586 -                            || (block->curr_n_bytes != n_bytes)
587 -                            || (block->curr_left_side != left_side))) {
588 +                                || (block->curr_n_bytes != n_bytes)
589 +                                || (block->curr_left_side != left_side))) {
590  
591 -               rw_lock_s_unlock(&btr_search_latch);
592 +               rw_lock_s_unlock(btr_search_get_latch(index->id));
593  
594                 btr_search_drop_page_hash_index(block);
595         } else {
596 -               rw_lock_s_unlock(&btr_search_latch);
597 +               rw_lock_s_unlock(btr_search_get_latch(index->id));
598         }
599  
600         n_recs = page_get_n_recs(page);
601 @@ -1554,9 +1609,9 @@
602                 fold = next_fold;
603         }
604  
605 -       btr_search_check_free_space_in_heap();
606 +       btr_search_check_free_space_in_heap(index->id);
607  
608 -       rw_lock_x_lock(&btr_search_latch);
609 +       rw_lock_x_lock(btr_search_get_latch(index->id));
610  
611         if (UNIV_UNLIKELY(!btr_search_enabled)) {
612                 goto exit_func;
613 @@ -1583,6 +1638,7 @@
614         block->curr_n_bytes = n_bytes;
615         block->curr_left_side = left_side;
616         block->index = index;
617 +       block->btr_search_latch = btr_search_get_latch(index->id);
618  
619         for (i = 0; i < n_cached; i++) {
620  
621 @@ -1590,7 +1646,7 @@
622         }
623  
624  exit_func:
625 -       rw_lock_x_unlock(&btr_search_latch);
626 +       rw_lock_x_unlock(btr_search_get_latch(index->id));
627  
628         mem_free(folds);
629         mem_free(recs);
630 @@ -1625,7 +1681,7 @@
631         ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_EX));
632  #endif /* UNIV_SYNC_DEBUG */
633  
634 -       rw_lock_s_lock(&btr_search_latch);
635 +       rw_lock_s_lock(btr_search_get_latch(index->id));
636  
637         ut_a(!new_block->index || new_block->index == index);
638         ut_a(!block->index || block->index == index);
639 @@ -1634,7 +1690,7 @@
640  
641         if (new_block->index) {
642  
643 -               rw_lock_s_unlock(&btr_search_latch);
644 +               rw_lock_s_unlock(btr_search_get_latch(index->id));
645  
646                 btr_search_drop_page_hash_index(block);
647  
648 @@ -1651,7 +1707,7 @@
649                 new_block->n_bytes = block->curr_n_bytes;
650                 new_block->left_side = left_side;
651  
652 -               rw_lock_s_unlock(&btr_search_latch);
653 +               rw_lock_s_unlock(btr_search_get_latch(index->id));
654  
655                 ut_a(n_fields + n_bytes > 0);
656  
657 @@ -1663,7 +1719,7 @@
658                 return;
659         }
660  
661 -       rw_lock_s_unlock(&btr_search_latch);
662 +       rw_lock_s_unlock(btr_search_get_latch(index->id));
663  }
664  
665  /********************************************************************//**
666 @@ -1702,7 +1758,7 @@
667         ut_a(block->curr_n_fields + block->curr_n_bytes > 0);
668         ut_a(!dict_index_is_ibuf(index));
669  
670 -       table = btr_search_sys->hash_index;
671 +       table = btr_search_get_hash_index(cursor->index->id);
672  
673         rec = btr_cur_get_rec(cursor);
674  
675 @@ -1713,7 +1769,7 @@
676                 mem_heap_free(heap);
677         }
678  
679 -       rw_lock_x_lock(&btr_search_latch);
680 +       rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
681  
682         if (block->index) {
683                 ut_a(block->index == index);
684 @@ -1721,7 +1777,7 @@
685                 ha_search_and_delete_if_found(table, fold, rec);
686         }
687  
688 -       rw_lock_x_unlock(&btr_search_latch);
689 +       rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
690  }
691  
692  /********************************************************************//**
693 @@ -1758,7 +1814,7 @@
694         ut_a(cursor->index == index);
695         ut_a(!dict_index_is_ibuf(index));
696  
697 -       rw_lock_x_lock(&btr_search_latch);
698 +       rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
699  
700         if (!block->index) {
701  
702 @@ -1772,15 +1828,15 @@
703             && (cursor->n_bytes == block->curr_n_bytes)
704             && !block->curr_left_side) {
705  
706 -               table = btr_search_sys->hash_index;
707 +               table = btr_search_get_hash_index(cursor->index->id);
708  
709                 ha_search_and_update_if_found(table, cursor->fold, rec,
710                                               block, page_rec_get_next(rec));
711  
712  func_exit:
713 -               rw_lock_x_unlock(&btr_search_latch);
714 +               rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
715         } else {
716 -               rw_lock_x_unlock(&btr_search_latch);
717 +               rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
718  
719                 btr_search_update_hash_on_insert(cursor);
720         }
721 @@ -1815,9 +1871,9 @@
722         ulint*          offsets         = offsets_;
723         rec_offs_init(offsets_);
724  
725 -       table = btr_search_sys->hash_index;
726 +       table = btr_search_get_hash_index(cursor->index->id);
727  
728 -       btr_search_check_free_space_in_heap();
729 +       btr_search_check_free_space_in_heap(cursor->index->id);
730  
731         rec = btr_cur_get_rec(cursor);
732  
733 @@ -1862,7 +1918,7 @@
734         } else {
735                 if (left_side) {
736  
737 -                       rw_lock_x_lock(&btr_search_latch);
738 +                       rw_lock_x_lock(btr_search_get_latch(index->id));
739  
740                         locked = TRUE;
741  
742 @@ -1880,7 +1936,7 @@
743  
744                 if (!locked) {
745  
746 -                       rw_lock_x_lock(&btr_search_latch);
747 +                       rw_lock_x_lock(btr_search_get_latch(index->id));
748  
749                         locked = TRUE;
750  
751 @@ -1902,7 +1958,7 @@
752                 if (!left_side) {
753  
754                         if (!locked) {
755 -                               rw_lock_x_lock(&btr_search_latch);
756 +                               rw_lock_x_lock(btr_search_get_latch(index->id));
757  
758                                 locked = TRUE;
759  
760 @@ -1921,7 +1977,7 @@
761  
762                 if (!locked) {
763  
764 -                       rw_lock_x_lock(&btr_search_latch);
765 +                       rw_lock_x_lock(btr_search_get_latch(index->id));
766  
767                         locked = TRUE;
768  
769 @@ -1948,7 +2004,7 @@
770                 mem_heap_free(heap);
771         }
772         if (locked) {
773 -               rw_lock_x_unlock(&btr_search_latch);
774 +               rw_lock_x_unlock(btr_search_get_latch(index->id));
775         }
776  }
777  
778 @@ -1964,7 +2020,7 @@
779         ha_node_t*      node;
780         ulint           n_page_dumps    = 0;
781         ibool           ok              = TRUE;
782 -       ulint           i;
783 +       ulint           i,j;
784         ulint           cell_count;
785         mem_heap_t*     heap            = NULL;
786         ulint           offsets_[REC_OFFS_NORMAL_SIZE];
787 @@ -1976,23 +2032,25 @@
788  
789         rec_offs_init(offsets_);
790  
791 -       rw_lock_x_lock(&btr_search_latch);
792 +       btr_search_x_lock_all();
793         buf_pool_page_hash_x_lock_all();
794  
795 -       cell_count = hash_get_n_cells(btr_search_sys->hash_index);
796 +       for (j = 0; j < btr_search_index_num; j++) {
797 +
798 +       cell_count = hash_get_n_cells(btr_search_sys->hash_index[j]);
799  
800         for (i = 0; i < cell_count; i++) {
801                 /* We release btr_search_latch every once in a while to
802                 give other queries a chance to run. */
803                 if ((i != 0) && ((i % chunk_size) == 0)) {
804                         buf_pool_page_hash_x_unlock_all();
805 -                       rw_lock_x_unlock(&btr_search_latch);
806 +                       btr_search_x_unlock_all();
807                         os_thread_yield();
808 -                       rw_lock_x_lock(&btr_search_latch);
809 +                       btr_search_x_lock_all();
810                         buf_pool_page_hash_x_lock_all();
811                 }
812  
813 -               node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
814 +               node = hash_get_nth_cell(btr_search_sys->hash_index[j], i)->node;
815  
816                 for (; node != NULL; node = node->next) {
817                         const buf_block_t*      block
818 @@ -2099,19 +2157,21 @@
819                 give other queries a chance to run. */
820                 if (i != 0) {
821                         buf_pool_page_hash_x_unlock_all();
822 -                       rw_lock_x_unlock(&btr_search_latch);
823 +                       btr_search_x_unlock_all();
824                         os_thread_yield();
825 -                       rw_lock_x_lock(&btr_search_latch);
826 +                       btr_search_x_lock_all();
827                         buf_pool_page_hash_x_lock_all();
828                 }
829  
830 -               if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
831 +               if (!ha_validate(btr_search_sys->hash_index[j], i, end_index)) {
832                         ok = FALSE;
833                 }
834         }
835  
836 +       } /*for (j = 0; j < btr_search_index_num; j++)*/
837 +
838         buf_pool_page_hash_x_unlock_all();
839 -       rw_lock_x_unlock(&btr_search_latch);
840 +       btr_search_x_unlock_all();
841         if (UNIV_LIKELY_NULL(heap)) {
842                 mem_heap_free(heap);
843         }
844 --- a/storage/innobase/buf/buf0buf.c
845 +++ b/storage/innobase/buf/buf0buf.c
846 @@ -960,6 +960,7 @@
847  
848         block->check_index_page_at_flush = FALSE;
849         block->index = NULL;
850 +       block->btr_search_latch = NULL;
851  
852  #ifdef UNIV_DEBUG
853         block->page.in_page_hash = FALSE;
854 @@ -1429,7 +1430,11 @@
855         ulint   p;
856  
857  #ifdef UNIV_SYNC_DEBUG
858 -       ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
859 +       ulint   j;
860 +
861 +       for (j = 0; j < btr_search_index_num; j++) {
862 +               ut_ad(rw_lock_own(btr_search_latch_part[j], RW_LOCK_EX));
863 +       }
864  #endif /* UNIV_SYNC_DEBUG */
865         ut_ad(!btr_search_enabled);
866  
867 @@ -2144,6 +2149,7 @@
868  {
869         block->check_index_page_at_flush = FALSE;
870         block->index            = NULL;
871 +       block->btr_search_latch = NULL;
872  
873         block->n_hash_helps     = 0;
874         block->n_fields         = 1;
875 --- a/storage/innobase/buf/buf0lru.c
876 +++ b/storage/innobase/buf/buf0lru.c
877 @@ -576,7 +576,7 @@
878  
879                 mutex_exit(&buf_pool->LRU_list_mutex);
880  
881 -               rw_lock_s_lock(&btr_search_latch);
882 +               btr_search_s_lock_all();
883                 chunk = buf_pool->chunks;
884                 for (j = buf_pool->n_chunks; j--; chunk++) {
885                         buf_block_t*    block   = chunk->blocks;
886 @@ -588,16 +588,16 @@
887                                         continue;
888                                 }
889  
890 -                               rw_lock_s_unlock(&btr_search_latch);
891 +                               btr_search_s_unlock_all();
892  
893                                 rw_lock_x_lock(&block->lock);
894                                 btr_search_drop_page_hash_index(block);
895                                 rw_lock_x_unlock(&block->lock);
896  
897 -                               rw_lock_s_lock(&btr_search_latch);
898 +                               btr_search_s_lock_all();
899                         }
900                 }
901 -               rw_lock_s_unlock(&btr_search_latch);
902 +               btr_search_s_unlock_all();
903         }
904  }
905  
906 --- a/storage/innobase/dict/dict0dict.c
907 +++ b/storage/innobase/dict/dict0dict.c
908 @@ -1851,7 +1851,7 @@
909         zero. */
910  
911         for (;;) {
912 -               ulint ref_count = btr_search_info_get_ref_count(info);
913 +               ulint ref_count = btr_search_info_get_ref_count(info, index->id);
914                 if (ref_count == 0) {
915                         break;
916                 }
917 --- a/storage/innobase/handler/ha_innodb.cc
918 +++ b/storage/innobase/handler/ha_innodb.cc
919 @@ -11832,6 +11832,11 @@
920    "Disable with --skip-innodb-adaptive-hash-index.",
921    NULL, innodb_adaptive_hash_index_update, TRUE);
922  
923 +static MYSQL_SYSVAR_ULONG(adaptive_hash_index_partitions, btr_search_index_num,
924 +  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
925 +  "Number of InnoDB adaptive hash index partitions (default 1: disable partitioning)",
926 +  NULL, NULL, 1, 1, sizeof(ulint) * 8, 0);
927 +
928  static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
929    PLUGIN_VAR_RQCMDARG,
930    "Replication thread delay (ms) on the slave server if "
931 @@ -12252,6 +12257,7 @@
932    MYSQL_SYSVAR(use_sys_stats_table),
933    MYSQL_SYSVAR(stats_sample_pages),
934    MYSQL_SYSVAR(adaptive_hash_index),
935 +  MYSQL_SYSVAR(adaptive_hash_index_partitions),
936    MYSQL_SYSVAR(stats_method),
937    MYSQL_SYSVAR(replication_delay),
938    MYSQL_SYSVAR(status_file),
939 --- a/storage/innobase/include/btr0sea.h
940 +++ b/storage/innobase/include/btr0sea.h
941 @@ -85,7 +85,8 @@
942  ulint
943  btr_search_info_get_ref_count(
944  /*==========================*/
945 -       btr_search_t*   info);  /*!< in: search info. */
946 +       btr_search_t*   info,   /*!< in: search info. */
947 +       index_id_t      key);
948  /*********************************************************************//**
949  Updates the search info. */
950  UNIV_INLINE
951 @@ -199,6 +200,40 @@
952  # define btr_search_validate() TRUE
953  #endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
954  
955 +/********************************************************************//**
956 +New functions to control split btr_search_index */
957 +UNIV_INLINE
958 +hash_table_t*
959 +btr_search_get_hash_index(
960 +/*======================*/
961 +       index_id_t      key);
962 +
963 +UNIV_INLINE
964 +rw_lock_t*
965 +btr_search_get_latch(
966 +/*=================*/
967 +       index_id_t      key);
968 +
969 +UNIV_INLINE
970 +void
971 +btr_search_x_lock_all(void);
972 +/*========================*/
973 +
974 +UNIV_INLINE
975 +void
976 +btr_search_x_unlock_all(void);
977 +/*==========================*/
978 +
979 +UNIV_INLINE
980 +void
981 +btr_search_s_lock_all(void);
982 +/*========================*/
983 +
984 +UNIV_INLINE
985 +void
986 +btr_search_s_unlock_all(void);
987 +/*==========================*/
988 +
989  /** The search info struct in an index */
990  struct btr_search_struct{
991         ulint   ref_count;      /*!< Number of blocks in this index tree
992 @@ -259,7 +294,7 @@
993  
994  /** The hash index system */
995  struct btr_search_sys_struct{
996 -       hash_table_t*   hash_index;     /*!< the adaptive hash index,
997 +       hash_table_t**  hash_index;     /*!< the adaptive hash index,
998                                         mapping dtuple_fold values
999                                         to rec_t pointers on index pages */
1000  };
1001 --- a/storage/innobase/include/btr0sea.ic
1002 +++ b/storage/innobase/include/btr0sea.ic
1003 @@ -62,8 +62,8 @@
1004         btr_search_t*   info;
1005  
1006  #ifdef UNIV_SYNC_DEBUG
1007 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
1008 -       ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1009 +       ut_ad(!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_SHARED));
1010 +       ut_ad(!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_EX));
1011  #endif /* UNIV_SYNC_DEBUG */
1012  
1013         info = btr_search_get_info(index);
1014 @@ -82,3 +82,72 @@
1015  
1016         btr_search_info_update_slow(info, cursor);
1017  }
1018 +
1019 +/*********************************************************************//**
1020 +New functions to control split btr_search_index */
1021 +UNIV_INLINE
1022 +hash_table_t*
1023 +btr_search_get_hash_index(
1024 +/*======================*/
1025 +       index_id_t      key)
1026 +{
1027 +       return(btr_search_sys->hash_index[key % btr_search_index_num]);
1028 +}
1029 +
1030 +UNIV_INLINE
1031 +rw_lock_t*
1032 +btr_search_get_latch(
1033 +/*=================*/
1034 +       index_id_t      key)
1035 +{
1036 +       return(btr_search_latch_part[key % btr_search_index_num]);
1037 +}
1038 +
1039 +UNIV_INLINE
1040 +void
1041 +btr_search_x_lock_all(void)
1042 +/*=======================*/
1043 +{
1044 +       ulint   i;
1045 +
1046 +       for (i = 0; i < btr_search_index_num; i++) {
1047 +               rw_lock_x_lock(btr_search_latch_part[i]);
1048 +       }
1049 +}
1050 +
1051 +UNIV_INLINE
1052 +void
1053 +btr_search_x_unlock_all(void)
1054 +/*==========================*/
1055 +{
1056 +       ulint   i;
1057 +
1058 +       for (i = 0; i < btr_search_index_num; i++) {
1059 +               rw_lock_x_unlock(btr_search_latch_part[i]);
1060 +       }
1061 +}
1062 +
1063 +UNIV_INLINE
1064 +void
1065 +btr_search_s_lock_all(void)
1066 +/*=======================*/
1067 +{
1068 +       ulint   i;
1069 +
1070 +       for (i = 0; i < btr_search_index_num; i++) {
1071 +               rw_lock_s_lock(btr_search_latch_part[i]);
1072 +       }
1073 +}
1074 +
1075 +UNIV_INLINE
1076 +void
1077 +btr_search_s_unlock_all(void)
1078 +/*=========================*/
1079 +{
1080 +       ulint   i;
1081 +
1082 +       for (i = 0; i < btr_search_index_num; i++) {
1083 +               rw_lock_s_unlock(btr_search_latch_part[i]);
1084 +       }
1085 +}
1086 +
1087 --- a/storage/innobase/row/row0mysql.c
1088 +++ b/storage/innobase/row/row0mysql.c
1089 @@ -2594,7 +2594,7 @@
1090                         /* check adaptive hash entries */
1091                         index = dict_table_get_first_index(table);
1092                         while (index) {
1093 -                               ulint ref_count = btr_search_info_get_ref_count(index->search_info);
1094 +                               ulint ref_count = btr_search_info_get_ref_count(index->search_info, index->id);
1095                                 if (ref_count) {
1096                                         fprintf(stderr, "InnoDB: Warning:"
1097                                                 " hash index ref_count (%lu) is not zero"
1098 @@ -2955,7 +2955,7 @@
1099                         table->space = space;
1100                         index = dict_table_get_first_index(table);
1101                         do {
1102 -                               ulint ref_count = btr_search_info_get_ref_count(index->search_info);
1103 +                               ulint ref_count = btr_search_info_get_ref_count(index->search_info, index->id);
1104                                 /* check adaptive hash entries */
1105                                 if (ref_count) {
1106                                         fprintf(stderr, "InnoDB: Warning:"
1107 --- a/storage/innobase/row/row0sel.c
1108 +++ b/storage/innobase/row/row0sel.c
1109 @@ -1222,7 +1222,7 @@
1110         ut_ad(plan->unique_search);
1111         ut_ad(!plan->must_get_clust);
1112  #ifdef UNIV_SYNC_DEBUG
1113 -       ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
1114 +       ut_ad(rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_SHARED));
1115  #endif /* UNIV_SYNC_DEBUG */
1116  
1117         row_sel_open_pcur(plan, TRUE, mtr);
1118 @@ -1393,10 +1393,10 @@
1119             && !plan->must_get_clust
1120             && !plan->table->big_rows) {
1121                 if (!search_latch_locked) {
1122 -                       rw_lock_s_lock(&btr_search_latch);
1123 +                       rw_lock_s_lock(btr_search_get_latch(index->id));
1124  
1125                         search_latch_locked = TRUE;
1126 -               } else if (rw_lock_get_writer(&btr_search_latch) == RW_LOCK_WAIT_EX) {
1127 +               } else if (rw_lock_get_writer(btr_search_get_latch(index->id)) == RW_LOCK_WAIT_EX) {
1128  
1129                         /* There is an x-latch request waiting: release the
1130                         s-latch for a moment; as an s-latch here is often
1131 @@ -1405,8 +1405,8 @@
1132                         from acquiring an s-latch for a long time, lowering
1133                         performance significantly in multiprocessors. */
1134  
1135 -                       rw_lock_s_unlock(&btr_search_latch);
1136 -                       rw_lock_s_lock(&btr_search_latch);
1137 +                       rw_lock_s_unlock(btr_search_get_latch(index->id));
1138 +                       rw_lock_s_lock(btr_search_get_latch(index->id));
1139                 }
1140  
1141                 found_flag = row_sel_try_search_shortcut(node, plan, &mtr);
1142 @@ -1429,7 +1429,7 @@
1143         }
1144  
1145         if (search_latch_locked) {
1146 -               rw_lock_s_unlock(&btr_search_latch);
1147 +               rw_lock_s_unlock(btr_search_get_latch(index->id));
1148  
1149                 search_latch_locked = FALSE;
1150         }
1151 @@ -2005,7 +2005,7 @@
1152  
1153  func_exit:
1154         if (search_latch_locked) {
1155 -               rw_lock_s_unlock(&btr_search_latch);
1156 +               rw_lock_s_unlock(btr_search_get_latch(index->id));
1157         }
1158         if (UNIV_LIKELY_NULL(heap)) {
1159                 mem_heap_free(heap);
1160 @@ -3408,6 +3408,8 @@
1161         /* if the returned record was locked and we did a semi-consistent
1162         read (fetch the newest committed version), then this is set to
1163         TRUE */
1164 +       ulint           i;
1165 +       ulint           should_release;
1166  #ifdef UNIV_SEARCH_DEBUG
1167         ulint           cnt                             = 0;
1168  #endif /* UNIV_SEARCH_DEBUG */
1169 @@ -3505,18 +3507,33 @@
1170         /* PHASE 0: Release a possible s-latch we are holding on the
1171         adaptive hash index latch if there is someone waiting behind */
1172  
1173 -       if (UNIV_UNLIKELY(rw_lock_get_writer(&btr_search_latch) != RW_LOCK_NOT_LOCKED)
1174 -           && trx->has_search_latch) {
1175 +       should_release = 0;
1176 +       for (i = 0; i < btr_search_index_num; i++) {
1177 +               /* we should check all latches (fix Bug#791030) */
1178 +               if (rw_lock_get_writer(btr_search_latch_part[i])
1179 +                   != RW_LOCK_NOT_LOCKED) {
1180 +                       should_release |= ((ulint)1 << i);
1181 +               }
1182 +       }
1183 +
1184 +       if (should_release) {
1185  
1186                 /* There is an x-latch request on the adaptive hash index:
1187                 release the s-latch to reduce starvation and wait for
1188                 BTR_SEA_TIMEOUT rounds before trying to keep it again over
1189                 calls from MySQL */
1190  
1191 -               rw_lock_s_unlock(&btr_search_latch);
1192 -               trx->has_search_latch = FALSE;
1193 +               for (i = 0; i < btr_search_index_num; i++) {
1194 +                       /* we should release all s-latches (fix Bug#791030) */
1195 +                       if (trx->has_search_latch & ((ulint)1 << i)) {
1196 +                               rw_lock_s_unlock(btr_search_latch_part[i]);
1197 +                               trx->has_search_latch &= (~((ulint)1 << i));
1198 +                       }
1199 +               }
1200  
1201 +               if (!trx->has_search_latch) {
1202                 trx->search_latch_timeout = BTR_SEA_TIMEOUT;
1203 +               }
1204         }
1205  
1206         /* Reset the new record lock info if srv_locks_unsafe_for_binlog
1207 @@ -3667,9 +3684,28 @@
1208                         hash index semaphore! */
1209  
1210  #ifndef UNIV_SEARCH_DEBUG
1211 -                       if (!trx->has_search_latch) {
1212 -                               rw_lock_s_lock(&btr_search_latch);
1213 -                               trx->has_search_latch = TRUE;
1214 +                       if (!(trx->has_search_latch
1215 +                             & ((ulint)1 << (index->id % btr_search_index_num)))) {
1216 +                               if (trx->has_search_latch
1217 +                                   < ((ulint)1 << (index->id % btr_search_index_num))) {
1218 +                                       rw_lock_s_lock(btr_search_get_latch(index->id));
1219 +                                       trx->has_search_latch |=
1220 +                                               ((ulint)1 << (index->id % btr_search_index_num));
1221 +                               } else {
1222 +                                       /* should re-lock to obay latch-order */
1223 +                                       for (i = 0; i < btr_search_index_num; i++) {
1224 +                                               if (trx->has_search_latch & ((ulint)1 << i)) {
1225 +                                                       rw_lock_s_unlock(btr_search_latch_part[i]);
1226 +                                               }
1227 +                                       }
1228 +                                       trx->has_search_latch |=
1229 +                                               ((ulint)1 << (index->id % btr_search_index_num));
1230 +                                       for (i = 0; i < btr_search_index_num; i++) {
1231 +                                               if (trx->has_search_latch & ((ulint)1 << i)) {
1232 +                                                       rw_lock_s_lock(btr_search_latch_part[i]);
1233 +                                               }
1234 +                                       }
1235 +                               }
1236                         }
1237  #endif
1238                         switch (row_sel_try_search_shortcut_for_mysql(
1239 @@ -3730,7 +3766,11 @@
1240  
1241                                         trx->search_latch_timeout--;
1242  
1243 -                                       rw_lock_s_unlock(&btr_search_latch);
1244 +                                       for (i = 0; i < btr_search_index_num; i++) {
1245 +                                               if (trx->has_search_latch & ((ulint)1 << i)) {
1246 +                                                       rw_lock_s_unlock(btr_search_latch_part[i]);
1247 +                                               }
1248 +                                       }
1249                                         trx->has_search_latch = FALSE;
1250                                 }
1251  
1252 @@ -3754,7 +3794,12 @@
1253         /* PHASE 3: Open or restore index cursor position */
1254  
1255         if (trx->has_search_latch) {
1256 -               rw_lock_s_unlock(&btr_search_latch);
1257 +
1258 +               for (i = 0; i < btr_search_index_num; i++) {
1259 +                       if (trx->has_search_latch & ((ulint)1 << i)) {
1260 +                               rw_lock_s_unlock(btr_search_latch_part[i]);
1261 +                       }
1262 +               }
1263                 trx->has_search_latch = FALSE;
1264         }
1265  
1266 --- a/storage/innobase/srv/srv0srv.c
1267 +++ b/storage/innobase/srv/srv0srv.c
1268 @@ -2054,7 +2054,9 @@
1269               "-------------------------------------\n", file);
1270         ibuf_print(file);
1271  
1272 -       ha_print_info(file, btr_search_sys->hash_index);
1273 +       for (i = 0; i < btr_search_index_num; i++) {
1274 +               ha_print_info(file, btr_search_get_hash_index((index_id_t)i));
1275 +       }
1276  
1277         fprintf(file,
1278                 "%.2f hash searches/s, %.2f non-hash searches/s\n",
1279 @@ -2079,14 +2081,15 @@
1280                         ut_total_allocated_memory,
1281                         mem_pool_get_reserved(mem_comm_pool));
1282         /* Calcurate reserved memories */
1283 -       if (btr_search_sys && btr_search_sys->hash_index->heap) {
1284 -               btr_search_sys_subtotal = mem_heap_get_size(btr_search_sys->hash_index->heap);
1285 +       if (btr_search_sys && btr_search_sys->hash_index[0]->heap) {
1286 +               btr_search_sys_subtotal = mem_heap_get_size(btr_search_sys->hash_index[0]->heap);
1287         } else {
1288                 btr_search_sys_subtotal = 0;
1289 -               for (i=0; i < btr_search_sys->hash_index->n_mutexes; i++) {
1290 -                       btr_search_sys_subtotal += mem_heap_get_size(btr_search_sys->hash_index->heaps[i]);
1291 +               for (i=0; i < btr_search_sys->hash_index[0]->n_mutexes; i++) {
1292 +                       btr_search_sys_subtotal += mem_heap_get_size(btr_search_sys->hash_index[0]->heaps[i]);
1293                 }
1294         }
1295 +       btr_search_sys_subtotal *= btr_search_index_num;
1296  
1297         lock_sys_subtotal = 0;
1298         if (trx_sys) {
1299 @@ -2112,10 +2115,10 @@
1300                         "    Recovery system     %lu \t(%lu + %lu)\n",
1301  
1302                         (ulong) (btr_search_sys
1303 -                               ? (btr_search_sys->hash_index->n_cells * sizeof(hash_cell_t)) : 0)
1304 +                               ? (btr_search_sys->hash_index[0]->n_cells * btr_search_index_num * sizeof(hash_cell_t)) : 0)
1305                         + btr_search_sys_subtotal,
1306                         (ulong) (btr_search_sys
1307 -                               ? (btr_search_sys->hash_index->n_cells * sizeof(hash_cell_t)) : 0),
1308 +                               ? (btr_search_sys->hash_index[0]->n_cells * btr_search_index_num * sizeof(hash_cell_t)) : 0),
1309                         (ulong) btr_search_sys_subtotal,
1310  
1311                         (ulong) (buf_pool_from_array(0)->page_hash->n_cells * sizeof(hash_cell_t)),
1312 --- a/storage/innobase/trx/trx0trx.c
1313 +++ b/storage/innobase/trx/trx0trx.c
1314 @@ -265,8 +265,14 @@
1315  /*=================================*/
1316         trx_t*     trx) /*!< in: transaction */
1317  {
1318 +       ulint   i;
1319 +
1320         if (trx->has_search_latch) {
1321 -               rw_lock_s_unlock(&btr_search_latch);
1322 +               for (i = 0; i < btr_search_index_num; i++) {
1323 +                       if (trx->has_search_latch & ((ulint)1 << i)) {
1324 +                               rw_lock_s_unlock(btr_search_latch_part[i]);
1325 +                       }
1326 +               }
1327  
1328                 trx->has_search_latch = FALSE;
1329         }
1330 --- a/storage/innobase/include/btr0types.h
1331 +++ b/storage/innobase/include/btr0types.h
1332 @@ -52,15 +52,19 @@
1333  
1334  Bear in mind (3) and (4) when using the hash index.
1335  */
1336 -extern rw_lock_t*      btr_search_latch_temp;
1337 +//extern rw_lock_t*    btr_search_latch_temp;
1338 +
1339 +extern rw_lock_t**     btr_search_latch_part;
1340  
1341  /** The latch protecting the adaptive search system */
1342 -#define btr_search_latch       (*btr_search_latch_temp)
1343 +//#define btr_search_latch     (*btr_search_latch_temp)
1344  
1345  /** Flag: has the search system been enabled?
1346  Protected by btr_search_latch. */
1347  extern char    btr_search_enabled;
1348  
1349 +extern ulint   btr_search_index_num;
1350 +
1351  #ifdef UNIV_BLOB_DEBUG
1352  # include "buf0types.h"
1353  /** An index->blobs entry for keeping track of off-page column references */
1354 --- a/storage/innobase/ha/ha0ha.c
1355 +++ b/storage/innobase/ha/ha0ha.c
1356 @@ -120,7 +120,7 @@
1357         ut_a(block->frame == page_align(data));
1358  #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
1359  #ifdef UNIV_SYNC_DEBUG
1360 -       ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1361 +       ut_ad(rw_lock_own(block->btr_search_latch, RW_LOCK_EX));
1362  #endif /* UNIV_SYNC_DEBUG */
1363         ASSERT_HASH_MUTEX_OWN(table, fold);
1364         ut_ad(btr_search_enabled);
1365 @@ -213,7 +213,7 @@
1366         ut_ad(table);
1367         ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
1368  #ifdef UNIV_SYNC_DEBUG
1369 -       ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1370 +       //      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1371  #endif /* UNIV_SYNC_DEBUG */
1372         ut_ad(btr_search_enabled);
1373  #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
1374 @@ -253,7 +253,7 @@
1375         ut_a(new_block->frame == page_align(new_data));
1376  #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
1377  #ifdef UNIV_SYNC_DEBUG
1378 -       ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1379 +       //      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1380  #endif /* UNIV_SYNC_DEBUG */
1381  
1382         if (!btr_search_enabled) {
1383 @@ -296,7 +296,7 @@
1384         ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
1385         ASSERT_HASH_MUTEX_OWN(table, fold);
1386  #ifdef UNIV_SYNC_DEBUG
1387 -       ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1388 +       //      ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1389  #endif /* UNIV_SYNC_DEBUG */
1390         ut_ad(btr_search_enabled);
1391  
1392 --- a/storage/innobase/include/ha0ha.ic
1393 +++ b/storage/innobase/include/ha0ha.ic
1394 @@ -121,7 +121,7 @@
1395  
1396         ASSERT_HASH_MUTEX_OWN(table, fold);
1397  #ifdef UNIV_SYNC_DEBUG
1398 -       ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
1399 +//     ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
1400  #endif /* UNIV_SYNC_DEBUG */
1401         ut_ad(btr_search_enabled);
1402  
1403 @@ -186,7 +186,7 @@
1404  
1405         ASSERT_HASH_MUTEX_OWN(table, fold);
1406  #ifdef UNIV_SYNC_DEBUG
1407 -       ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1408 +//     ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1409  #endif /* UNIV_SYNC_DEBUG */
1410         ut_ad(btr_search_enabled);
1411  
1412 --- a/storage/innobase/include/buf0buf.h
1413 +++ b/storage/innobase/include/buf0buf.h
1414 @@ -1600,6 +1600,7 @@
1415                                         complete, though: there may
1416                                         have been hash collisions,
1417                                         record deletions, etc. */
1418 +       volatile rw_lock_t*     btr_search_latch;
1419         /* @} */
1420  # ifdef UNIV_SYNC_DEBUG
1421         /** @name Debug fields */
1422 --- a/storage/innobase/sync/sync0sync.c
1423 +++ b/storage/innobase/sync/sync0sync.c
1424 @@ -1222,7 +1222,6 @@
1425         case SYNC_OUTER_ANY_LATCH:
1426         case SYNC_FILE_FORMAT_TAG:
1427         case SYNC_DOUBLEWRITE:
1428 -       case SYNC_SEARCH_SYS:
1429         case SYNC_TRX_LOCK_HEAP:
1430         case SYNC_KERNEL:
1431         case SYNC_IBUF_BITMAP_MUTEX:
1432 @@ -1243,6 +1242,7 @@
1433                         ut_error;
1434                 }
1435                 break;
1436 +       case SYNC_SEARCH_SYS:
1437         case SYNC_BUF_LRU_LIST:
1438         case SYNC_BUF_FLUSH_LIST:
1439         case SYNC_BUF_PAGE_HASH:
This page took 0.136791 seconds and 3 git commands to generate.