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