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