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