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