1 # name : innodb_adaptive_hash_index_num.patch
2 # introduced : XtraDB on 5.5 (-13?)
3 # maintainer : Yasufumi
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
11 #ifdef UNIV_SEARCH_PERF_STAT
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
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));
27 /* Store the position of the tree latch we push to mtr so that we
30 if (has_search_latch) {
32 - rw_lock_s_lock(&btr_search_latch);
33 + rw_lock_s_lock(btr_search_get_latch(cursor->index->id));
37 @@ -1977,13 +1977,13 @@
38 btr_search_update_hash_on_delete(cursor);
41 - rw_lock_x_lock(&btr_search_latch);
42 + rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
45 row_upd_rec_in_place(rec, index, offsets, update, page_zip);
48 - rw_lock_x_unlock(&btr_search_latch);
49 + rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
52 if (page_zip && !dict_index_is_clust(index)
53 --- a/storage/innobase/btr/btr0sea.c
54 +++ b/storage/innobase/btr/btr0sea.c
56 Protected by btr_search_latch. */
57 UNIV_INTERN char btr_search_enabled = TRUE;
59 +UNIV_INTERN ulint btr_search_index_num = 1;
62 /* Key to register btr_search_enabled_mutex with performance schema */
63 UNIV_INTERN mysql_pfs_key_t btr_search_enabled_mutex_key;
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;
71 +UNIV_INTERN rw_lock_t** btr_search_latch_part;
73 /** padding to prevent other memory update hotspots from residing on
74 the same memory cache line */
76 will not guarantee success. */
79 -btr_search_check_free_space_in_heap(void)
80 +btr_search_check_free_space_in_heap(
81 /*=====================================*/
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 */
94 - table = btr_search_sys->hash_index;
95 + table = btr_search_get_hash_index(key);
100 if (heap->free_block == NULL) {
101 buf_block_t* block = buf_block_alloc(NULL);
103 - rw_lock_x_lock(&btr_search_latch);
104 + rw_lock_x_lock(btr_search_get_latch(key));
106 if (heap->free_block == NULL) {
107 heap->free_block = block;
109 buf_block_free(block);
112 - rw_lock_x_unlock(&btr_search_latch);
113 + rw_lock_x_unlock(btr_search_get_latch(key));
117 @@ -169,17 +174,28 @@
118 /*==================*/
119 ulint hash_size) /*!< in: hash index hash table size */
122 /* We allocate the search latch from dynamic memory:
123 see above at the global variable definition */
125 - btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
126 + //btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
128 - rw_lock_create(btr_search_latch_key, &btr_search_latch,
130 + //rw_lock_create(btr_search_latch_key, &btr_search_latch,
131 + // SYNC_SEARCH_SYS);
133 btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
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));
142 + rw_lock_create(btr_search_latch_key,
143 + btr_search_latch_part[i], SYNC_SEARCH_SYS);
145 + btr_search_sys->hash_index[i] = ha_create(hash_size, 0, 0);
149 /*****************************************************************//**
150 @@ -189,11 +205,22 @@
151 btr_search_sys_free(void)
152 /*=====================*/
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);
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]);
165 + rw_lock_free(btr_search_latch_part[i]);
167 + mem_free(btr_search_latch_part[i]);
169 + mem_free(btr_search_sys->hash_index);
170 + mem_free(btr_search_latch_part);
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;
179 /*====================*/
184 mutex_enter(&dict_sys->mutex);
185 - rw_lock_x_lock(&btr_search_latch);
186 + btr_search_x_lock_all();
188 btr_search_enabled = FALSE;
190 @@ -232,10 +260,12 @@
191 buf_pool_clear_hash_index();
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);
201 - rw_lock_x_unlock(&btr_search_latch);
202 + btr_search_x_unlock_all();
205 /********************************************************************//**
206 @@ -245,11 +275,11 @@
207 btr_search_enable(void)
208 /*====================*/
210 - rw_lock_x_lock(&btr_search_latch);
211 + btr_search_x_lock_all();
213 btr_search_enabled = TRUE;
215 - rw_lock_x_unlock(&btr_search_latch);
216 + btr_search_x_unlock_all();
219 /*****************************************************************//**
220 @@ -301,20 +331,21 @@
222 btr_search_info_get_ref_count(
223 /*==========================*/
224 - btr_search_t* info) /*!< in: search info. */
225 + btr_search_t* info, /*!< in: search info. */
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 */
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));
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 */
257 index = cursor->index;
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 */
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 @@
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 */
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,
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 */
301 block = btr_cur_get_block(cursor);
304 if (build_index || (cursor->flag == BTR_CUR_HASH_FAIL)) {
306 - btr_search_check_free_space_in_heap();
307 + btr_search_check_free_space_in_heap(cursor->index->id);
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 */
315 - rw_lock_x_lock(&btr_search_latch);
316 + rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
318 btr_search_update_hash_ref(info, block, cursor);
320 - rw_lock_x_unlock(&btr_search_latch);
321 + rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
325 @@ -884,17 +915,17 @@
326 cursor->flag = BTR_CUR_HASH;
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));
332 if (UNIV_UNLIKELY(!btr_search_enabled)) {
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);
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);
345 if (UNIV_UNLIKELY(!rec)) {
351 - rw_lock_s_unlock(&btr_search_latch);
352 + rw_lock_s_unlock(btr_search_get_latch(index_id));
354 buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
356 @@ -1009,7 +1040,7 @@
357 /*-------------------------------------------*/
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));
364 cursor->flag = BTR_CUR_HASH_FAIL;
365 @@ -1053,24 +1084,49 @@
366 const dict_index_t* index;
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 */
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;
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) {
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);
393 + if (UNIV_LIKELY(!block->index)) {
394 + rw_lock_s_unlock(btr_search_latch);
397 + index = block->index;
398 + ut_a(btr_search_latch == btr_search_get_latch(index->id));
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]);
408 + index = block->index;
411 if (UNIV_LIKELY(!index)) {
413 - rw_lock_s_unlock(&btr_search_latch);
414 + rw_lock_s_unlock(btr_search_get_latch(index->id));
419 - ut_a(!dict_index_is_ibuf(index));
420 - table = btr_search_sys->hash_index;
421 + table = btr_search_get_hash_index(index->id);
423 #ifdef UNIV_SYNC_DEBUG
424 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
425 @@ -1080,12 +1136,14 @@
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));
432 /* NOTE: The fields of block must not be accessed after
433 releasing btr_search_latch, as the index page might only
436 - rw_lock_s_unlock(&btr_search_latch);
437 + rw_lock_s_unlock(btr_search_get_latch(index->id));
439 ut_a(n_fields + n_bytes > 0);
441 @@ -1136,7 +1194,7 @@
445 - rw_lock_x_lock(&btr_search_latch);
446 + rw_lock_x_lock(btr_search_get_latch(index->id));
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 */
454 - rw_lock_x_unlock(&btr_search_latch);
455 + rw_lock_x_unlock(btr_search_get_latch(index->id));
459 @@ -1167,6 +1225,7 @@
460 index->search_info->ref_count--;
463 + block->btr_search_latch = NULL;
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));
474 btr_search_validate();
476 - rw_lock_x_unlock(&btr_search_latch);
477 + rw_lock_x_unlock(btr_search_get_latch(index->id));
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 */
485 @@ -1218,9 +1277,9 @@
487 ibool released_search_latch;
489 - rw_lock_s_lock(&btr_search_latch);
490 + rw_lock_s_lock(btr_search_get_latch(index->id));
492 - table = btr_search_sys->hash_index;
493 + table = btr_search_get_hash_index(index->id);
495 for (j = 0; j < srv_buf_pool_instances; j++) {
496 buf_pool_t* buf_pool;
497 @@ -1254,7 +1313,7 @@
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);
506 @@ -1306,7 +1365,7 @@
507 mem_heap_empty(heap);
510 - rw_lock_x_lock(&btr_search_latch);
511 + rw_lock_x_lock(btr_search_get_latch(index->id));
513 if (UNIV_UNLIKELY(!block->index)) {
515 @@ -1316,12 +1375,12 @@
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);
525 - rw_lock_s_lock(&btr_search_latch);
526 + rw_lock_s_lock(btr_search_get_latch(index->id));
530 @@ -1334,6 +1393,7 @@
531 index->search_info->ref_count--;
534 + block->btr_search_latch = NULL;
537 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
538 @@ -1346,18 +1406,18 @@
539 index->name, (ulong) block->n_pointers);
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);
548 - rw_lock_s_lock(&btr_search_latch);
549 + rw_lock_s_lock(btr_search_get_latch(index->id));
552 } while (released_search_latch);
555 - rw_lock_s_unlock(&btr_search_latch);
556 + rw_lock_s_unlock(btr_search_get_latch(index->id));
558 if (UNIV_LIKELY_NULL(heap)) {
560 @@ -1436,31 +1496,26 @@
562 ut_a(!dict_index_is_ibuf(index));
564 + table = btr_search_get_hash_index(index->id);
565 + page = buf_block_get_frame(block);
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 */
574 - rw_lock_s_lock(&btr_search_latch);
576 - if (!btr_search_enabled) {
577 - rw_lock_s_unlock(&btr_search_latch);
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));
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))) {
591 - rw_lock_s_unlock(&btr_search_latch);
592 + rw_lock_s_unlock(btr_search_get_latch(index->id));
594 btr_search_drop_page_hash_index(block);
596 - rw_lock_s_unlock(&btr_search_latch);
597 + rw_lock_s_unlock(btr_search_get_latch(index->id));
600 n_recs = page_get_n_recs(page);
601 @@ -1554,9 +1609,9 @@
605 - btr_search_check_free_space_in_heap();
606 + btr_search_check_free_space_in_heap(index->id);
608 - rw_lock_x_lock(&btr_search_latch);
609 + rw_lock_x_lock(btr_search_get_latch(index->id));
611 if (UNIV_UNLIKELY(!btr_search_enabled)) {
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);
619 for (i = 0; i < n_cached; i++) {
621 @@ -1590,7 +1646,7 @@
625 - rw_lock_x_unlock(&btr_search_latch);
626 + rw_lock_x_unlock(btr_search_get_latch(index->id));
630 @@ -1625,7 +1681,7 @@
631 ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_EX));
632 #endif /* UNIV_SYNC_DEBUG */
634 - rw_lock_s_lock(&btr_search_latch);
635 + rw_lock_s_lock(btr_search_get_latch(index->id));
637 ut_a(!new_block->index || new_block->index == index);
638 ut_a(!block->index || block->index == index);
639 @@ -1634,7 +1690,7 @@
641 if (new_block->index) {
643 - rw_lock_s_unlock(&btr_search_latch);
644 + rw_lock_s_unlock(btr_search_get_latch(index->id));
646 btr_search_drop_page_hash_index(block);
648 @@ -1651,7 +1707,7 @@
649 new_block->n_bytes = block->curr_n_bytes;
650 new_block->left_side = left_side;
652 - rw_lock_s_unlock(&btr_search_latch);
653 + rw_lock_s_unlock(btr_search_get_latch(index->id));
655 ut_a(n_fields + n_bytes > 0);
657 @@ -1663,7 +1719,7 @@
661 - rw_lock_s_unlock(&btr_search_latch);
662 + rw_lock_s_unlock(btr_search_get_latch(index->id));
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));
670 - table = btr_search_sys->hash_index;
671 + table = btr_search_get_hash_index(cursor->index->id);
673 rec = btr_cur_get_rec(cursor);
675 @@ -1713,7 +1769,7 @@
679 - rw_lock_x_lock(&btr_search_latch);
680 + rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
683 ut_a(block->index == index);
684 @@ -1721,7 +1777,7 @@
685 ha_search_and_delete_if_found(table, fold, rec);
688 - rw_lock_x_unlock(&btr_search_latch);
689 + rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
692 /********************************************************************//**
693 @@ -1758,7 +1814,7 @@
694 ut_a(cursor->index == index);
695 ut_a(!dict_index_is_ibuf(index));
697 - rw_lock_x_lock(&btr_search_latch);
698 + rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
702 @@ -1772,15 +1828,15 @@
703 && (cursor->n_bytes == block->curr_n_bytes)
704 && !block->curr_left_side) {
706 - table = btr_search_sys->hash_index;
707 + table = btr_search_get_hash_index(cursor->index->id);
709 ha_search_and_update_if_found(table, cursor->fold, rec,
710 block, page_rec_get_next(rec));
713 - rw_lock_x_unlock(&btr_search_latch);
714 + rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
716 - rw_lock_x_unlock(&btr_search_latch);
717 + rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
719 btr_search_update_hash_on_insert(cursor);
721 @@ -1815,9 +1871,9 @@
722 ulint* offsets = offsets_;
723 rec_offs_init(offsets_);
725 - table = btr_search_sys->hash_index;
726 + table = btr_search_get_hash_index(cursor->index->id);
728 - btr_search_check_free_space_in_heap();
729 + btr_search_check_free_space_in_heap(cursor->index->id);
731 rec = btr_cur_get_rec(cursor);
733 @@ -1862,7 +1918,7 @@
737 - rw_lock_x_lock(&btr_search_latch);
738 + rw_lock_x_lock(btr_search_get_latch(index->id));
742 @@ -1880,7 +1936,7 @@
746 - rw_lock_x_lock(&btr_search_latch);
747 + rw_lock_x_lock(btr_search_get_latch(index->id));
751 @@ -1902,7 +1958,7 @@
755 - rw_lock_x_lock(&btr_search_latch);
756 + rw_lock_x_lock(btr_search_get_latch(index->id));
760 @@ -1921,7 +1977,7 @@
764 - rw_lock_x_lock(&btr_search_latch);
765 + rw_lock_x_lock(btr_search_get_latch(index->id));
769 @@ -1948,7 +2004,7 @@
773 - rw_lock_x_unlock(&btr_search_latch);
774 + rw_lock_x_unlock(btr_search_get_latch(index->id));
778 @@ -1964,7 +2020,7 @@
780 ulint n_page_dumps = 0;
785 mem_heap_t* heap = NULL;
786 ulint offsets_[REC_OFFS_NORMAL_SIZE];
787 @@ -1976,23 +2032,25 @@
789 rec_offs_init(offsets_);
791 - rw_lock_x_lock(&btr_search_latch);
792 + btr_search_x_lock_all();
793 buf_pool_page_hash_x_lock_all();
795 - cell_count = hash_get_n_cells(btr_search_sys->hash_index);
796 + for (j = 0; j < btr_search_index_num; j++) {
798 + cell_count = hash_get_n_cells(btr_search_sys->hash_index[j]);
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();
808 - rw_lock_x_lock(&btr_search_latch);
809 + btr_search_x_lock_all();
810 buf_pool_page_hash_x_lock_all();
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;
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. */
821 buf_pool_page_hash_x_unlock_all();
822 - rw_lock_x_unlock(&btr_search_latch);
823 + btr_search_x_unlock_all();
825 - rw_lock_x_lock(&btr_search_latch);
826 + btr_search_x_lock_all();
827 buf_pool_page_hash_x_lock_all();
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)) {
836 + } /*for (j = 0; j < btr_search_index_num; j++)*/
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)) {
844 --- a/storage/innobase/buf/buf0buf.c
845 +++ b/storage/innobase/buf/buf0buf.c
848 block->check_index_page_at_flush = FALSE;
850 + block->btr_search_latch = NULL;
853 block->page.in_page_hash = FALSE;
854 @@ -1429,7 +1430,11 @@
857 #ifdef UNIV_SYNC_DEBUG
858 - ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
861 + for (j = 0; j < btr_search_index_num; j++) {
862 + ut_ad(rw_lock_own(btr_search_latch_part[j], RW_LOCK_EX));
864 #endif /* UNIV_SYNC_DEBUG */
865 ut_ad(!btr_search_enabled);
867 @@ -2144,6 +2149,7 @@
869 block->check_index_page_at_flush = FALSE;
871 + block->btr_search_latch = NULL;
873 block->n_hash_helps = 0;
875 --- a/storage/innobase/buf/buf0lru.c
876 +++ b/storage/innobase/buf/buf0lru.c
879 mutex_exit(&buf_pool->LRU_list_mutex);
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 @@
890 - rw_lock_s_unlock(&btr_search_latch);
891 + btr_search_s_unlock_all();
893 rw_lock_x_lock(&block->lock);
894 btr_search_drop_page_hash_index(block);
895 rw_lock_x_unlock(&block->lock);
897 - rw_lock_s_lock(&btr_search_latch);
898 + btr_search_s_lock_all();
901 - rw_lock_s_unlock(&btr_search_latch);
902 + btr_search_s_unlock_all();
906 --- a/storage/innobase/dict/dict0dict.c
907 +++ b/storage/innobase/dict/dict0dict.c
908 @@ -1851,7 +1851,7 @@
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) {
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);
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);
928 static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
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
943 btr_search_info_get_ref_count(
944 /*==========================*/
945 - btr_search_t* info); /*!< in: search info. */
946 + btr_search_t* info, /*!< in: search info. */
948 /*********************************************************************//**
949 Updates the search info. */
952 # define btr_search_validate() TRUE
953 #endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
955 +/********************************************************************//**
956 +New functions to control split btr_search_index */
959 +btr_search_get_hash_index(
960 +/*======================*/
965 +btr_search_get_latch(
966 +/*=================*/
971 +btr_search_x_lock_all(void);
972 +/*========================*/
976 +btr_search_x_unlock_all(void);
977 +/*==========================*/
981 +btr_search_s_lock_all(void);
982 +/*========================*/
986 +btr_search_s_unlock_all(void);
987 +/*==========================*/
989 /** The search info struct in an index */
990 struct btr_search_struct{
991 ulint ref_count; /*!< Number of blocks in this index tree
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 */
1001 --- a/storage/innobase/include/btr0sea.ic
1002 +++ b/storage/innobase/include/btr0sea.ic
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 */
1013 info = btr_search_get_info(index);
1016 btr_search_info_update_slow(info, cursor);
1019 +/*********************************************************************//**
1020 +New functions to control split btr_search_index */
1023 +btr_search_get_hash_index(
1024 +/*======================*/
1027 + return(btr_search_sys->hash_index[key % btr_search_index_num]);
1032 +btr_search_get_latch(
1033 +/*=================*/
1036 + return(btr_search_latch_part[key % btr_search_index_num]);
1041 +btr_search_x_lock_all(void)
1042 +/*=======================*/
1046 + for (i = 0; i < btr_search_index_num; i++) {
1047 + rw_lock_x_lock(btr_search_latch_part[i]);
1053 +btr_search_x_unlock_all(void)
1054 +/*==========================*/
1058 + for (i = 0; i < btr_search_index_num; i++) {
1059 + rw_lock_x_unlock(btr_search_latch_part[i]);
1065 +btr_search_s_lock_all(void)
1066 +/*=======================*/
1070 + for (i = 0; i < btr_search_index_num; i++) {
1071 + rw_lock_s_lock(btr_search_latch_part[i]);
1077 +btr_search_s_unlock_all(void)
1078 +/*=========================*/
1082 + for (i = 0; i < btr_search_index_num; i++) {
1083 + rw_lock_s_unlock(btr_search_latch_part[i]);
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);
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);
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);
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 */
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 */
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));
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) {
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. */
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));
1141 found_flag = row_sel_try_search_shortcut(node, plan, &mtr);
1142 @@ -1429,7 +1429,7 @@
1145 if (search_latch_locked) {
1146 - rw_lock_s_unlock(&btr_search_latch);
1147 + rw_lock_s_unlock(btr_search_get_latch(index->id));
1149 search_latch_locked = FALSE;
1151 @@ -2005,7 +2005,7 @@
1154 if (search_latch_locked) {
1155 - rw_lock_s_unlock(&btr_search_latch);
1156 + rw_lock_s_unlock(btr_search_get_latch(index->id));
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
1165 + ulint should_release;
1166 #ifdef UNIV_SEARCH_DEBUG
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 */
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);
1184 + if (should_release) {
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
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));
1201 + if (!trx->has_search_latch) {
1202 trx->search_latch_timeout = BTR_SEA_TIMEOUT;
1206 /* Reset the new record lock info if srv_locks_unsafe_for_binlog
1207 @@ -3667,9 +3684,28 @@
1208 hash index semaphore! */
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));
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]);
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]);
1238 switch (row_sel_try_search_shortcut_for_mysql(
1239 @@ -3730,7 +3766,11 @@
1241 trx->search_latch_timeout--;
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]);
1249 trx->has_search_latch = FALSE;
1252 @@ -3754,7 +3794,12 @@
1253 /* PHASE 3: Open or restore index cursor position */
1255 if (trx->has_search_latch) {
1256 - rw_lock_s_unlock(&btr_search_latch);
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]);
1263 trx->has_search_latch = FALSE;
1266 --- a/storage/innobase/srv/srv0srv.c
1267 +++ b/storage/innobase/srv/srv0srv.c
1268 @@ -2054,7 +2054,9 @@
1269 "-------------------------------------\n", file);
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));
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);
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]);
1295 + btr_search_sys_subtotal *= btr_search_index_num;
1297 lock_sys_subtotal = 0;
1299 @@ -2112,10 +2115,10 @@
1300 " Recovery system %lu \t(%lu + %lu)\n",
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,
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 */
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]);
1328 trx->has_search_latch = FALSE;
1330 --- a/storage/innobase/include/btr0types.h
1331 +++ b/storage/innobase/include/btr0types.h
1334 Bear in mind (3) and (4) when using the hash index.
1336 -extern rw_lock_t* btr_search_latch_temp;
1337 +//extern rw_lock_t* btr_search_latch_temp;
1339 +extern rw_lock_t** btr_search_latch_part;
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)
1345 /** Flag: has the search system been enabled?
1346 Protected by btr_search_latch. */
1347 extern char btr_search_enabled;
1349 +extern ulint btr_search_index_num;
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
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);
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
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 */
1382 if (!btr_search_enabled) {
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);
1392 --- a/storage/innobase/include/ha0ha.ic
1393 +++ b/storage/innobase/include/ha0ha.ic
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);
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);
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;
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:
1431 case SYNC_IBUF_BITMAP_MUTEX:
1432 @@ -1243,6 +1242,7 @@
1436 + case SYNC_SEARCH_SYS:
1437 case SYNC_BUF_LRU_LIST:
1438 case SYNC_BUF_FLUSH_LIST:
1439 case SYNC_BUF_PAGE_HASH: