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