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