]> git.pld-linux.org Git - packages/mysql.git/blame - innodb_split_buf_pool_mutex.patch
- make mysql.init a bit more lsb-compatible
[packages/mysql.git] / innodb_split_buf_pool_mutex.patch
CommitLineData
b4e1fa2c
AM
1# name : innodb_split_buf_pool_mutex.patch
2# introduced : 11 or before
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
9--- a/storage/innobase/btr/btr0cur.c 2010-11-03 07:01:13.000000000 +0900
10+++ b/storage/innobase/btr/btr0cur.c 2010-12-03 15:48:29.268957148 +0900
11822e22 11@@ -4069,7 +4069,8 @@
b4e1fa2c
AM
12
13 mtr_commit(mtr);
14
15- buf_pool_mutex_enter(buf_pool);
16+ //buf_pool_mutex_enter(buf_pool);
17+ mutex_enter(&buf_pool->LRU_list_mutex);
18 mutex_enter(&block->mutex);
19
20 /* Only free the block if it is still allocated to
11822e22 21@@ -4080,16 +4081,21 @@
b4e1fa2c
AM
22 && buf_block_get_space(block) == space
23 && buf_block_get_page_no(block) == page_no) {
24
df1b5770 25- if (buf_LRU_free_block(&block->page, all) != BUF_LRU_FREED
b4e1fa2c 26- && all && block->page.zip.data) {
df1b5770 27+ if (buf_LRU_free_block(&block->page, all, TRUE) != BUF_LRU_FREED
b4e1fa2c
AM
28+ && all && block->page.zip.data
29+ /* Now, buf_LRU_free_block() may release mutex temporarily */
30+ && buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
31+ && buf_block_get_space(block) == space
32+ && buf_block_get_page_no(block) == page_no) {
33 /* Attempt to deallocate the uncompressed page
34 if the whole block cannot be deallocted. */
35
df1b5770
AM
36- buf_LRU_free_block(&block->page, FALSE);
37+ buf_LRU_free_block(&block->page, FALSE, TRUE);
b4e1fa2c
AM
38 }
39 }
40
41- buf_pool_mutex_exit(buf_pool);
42+ //buf_pool_mutex_exit(buf_pool);
43+ mutex_exit(&buf_pool->LRU_list_mutex);
44 mutex_exit(&block->mutex);
45 }
46
47diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
48--- a/storage/innobase/btr/btr0sea.c 2010-12-03 15:48:03.033037049 +0900
49+++ b/storage/innobase/btr/btr0sea.c 2010-12-03 15:48:29.271024260 +0900
d8778560 50@@ -1943,7 +1943,7 @@
b4e1fa2c
AM
51 rec_offs_init(offsets_);
52
53 rw_lock_x_lock(&btr_search_latch);
54- buf_pool_mutex_enter_all();
55+ buf_pool_page_hash_x_lock_all();
56
57 cell_count = hash_get_n_cells(btr_search_sys->hash_index);
58
d8778560 59@@ -1951,11 +1951,11 @@
b4e1fa2c
AM
60 /* We release btr_search_latch every once in a while to
61 give other queries a chance to run. */
62 if ((i != 0) && ((i % chunk_size) == 0)) {
63- buf_pool_mutex_exit_all();
64+ buf_pool_page_hash_x_unlock_all();
65 rw_lock_x_unlock(&btr_search_latch);
66 os_thread_yield();
67 rw_lock_x_lock(&btr_search_latch);
68- buf_pool_mutex_enter_all();
69+ buf_pool_page_hash_x_lock_all();
70 }
71
72 node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
d8778560 73@@ -2066,11 +2066,11 @@
b4e1fa2c
AM
74 /* We release btr_search_latch every once in a while to
75 give other queries a chance to run. */
76 if (i != 0) {
77- buf_pool_mutex_exit_all();
78+ buf_pool_page_hash_x_unlock_all();
79 rw_lock_x_unlock(&btr_search_latch);
80 os_thread_yield();
81 rw_lock_x_lock(&btr_search_latch);
82- buf_pool_mutex_enter_all();
83+ buf_pool_page_hash_x_lock_all();
84 }
85
86 if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
d8778560 87@@ -2078,7 +2078,7 @@
b4e1fa2c
AM
88 }
89 }
90
91- buf_pool_mutex_exit_all();
92+ buf_pool_page_hash_x_unlock_all();
93 rw_lock_x_unlock(&btr_search_latch);
94 if (UNIV_LIKELY_NULL(heap)) {
95 mem_heap_free(heap);
96diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
97--- a/storage/innobase/buf/buf0buddy.c 2010-12-03 15:22:36.307986907 +0900
98+++ b/storage/innobase/buf/buf0buddy.c 2010-12-03 15:48:29.275025723 +0900
99@@ -73,10 +73,11 @@
100 if (b) UNIV_MEM_VALID(b, BUF_BUDDY_LOW << i);
101 #endif /* UNIV_DEBUG_VALGRIND */
102
103- ut_ad(buf_pool_mutex_own(buf_pool));
104+ //ut_ad(buf_pool_mutex_own(buf_pool));
105+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
106 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
107 ut_ad(buf_pool->zip_free[i].start != bpage);
108- UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], bpage);
109+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_free[i], bpage);
110
111 #ifdef UNIV_DEBUG_VALGRIND
112 if (b) UNIV_MEM_FREE(b, BUF_BUDDY_LOW << i);
113@@ -96,8 +97,8 @@
114 buf_pool->zip_free[] */
115 {
116 #ifdef UNIV_DEBUG_VALGRIND
117- buf_page_t* prev = UT_LIST_GET_PREV(list, bpage);
118- buf_page_t* next = UT_LIST_GET_NEXT(list, bpage);
119+ buf_page_t* prev = UT_LIST_GET_PREV(zip_list, bpage);
120+ buf_page_t* next = UT_LIST_GET_NEXT(zip_list, bpage);
121
122 if (prev) UNIV_MEM_VALID(prev, BUF_BUDDY_LOW << i);
123 if (next) UNIV_MEM_VALID(next, BUF_BUDDY_LOW << i);
124@@ -106,9 +107,10 @@
125 ut_ad(!next || buf_page_get_state(next) == BUF_BLOCK_ZIP_FREE);
126 #endif /* UNIV_DEBUG_VALGRIND */
127
128- ut_ad(buf_pool_mutex_own(buf_pool));
129+ //ut_ad(buf_pool_mutex_own(buf_pool));
130+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
131 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
132- UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
133+ UT_LIST_REMOVE(zip_list, buf_pool->zip_free[i], bpage);
134
135 #ifdef UNIV_DEBUG_VALGRIND
136 if (prev) UNIV_MEM_FREE(prev, BUF_BUDDY_LOW << i);
137@@ -128,12 +130,13 @@
138 {
139 buf_page_t* bpage;
140
141- ut_ad(buf_pool_mutex_own(buf_pool));
142+ //ut_ad(buf_pool_mutex_own(buf_pool));
143+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
144 ut_a(i < BUF_BUDDY_SIZES);
145
146 #ifndef UNIV_DEBUG_VALGRIND
147 /* Valgrind would complain about accessing free memory. */
148- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
149+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
150 ut_ad(buf_page_get_state(ut_list_node_313)
151 == BUF_BLOCK_ZIP_FREE)));
152 #endif /* !UNIV_DEBUG_VALGRIND */
153@@ -177,16 +180,19 @@
154 buf_buddy_block_free(
155 /*=================*/
156 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
157- void* buf) /*!< in: buffer frame to deallocate */
158+ void* buf, /*!< in: buffer frame to deallocate */
159+ ibool have_page_hash_mutex)
160 {
161 const ulint fold = BUF_POOL_ZIP_FOLD_PTR(buf);
162 buf_page_t* bpage;
163 buf_block_t* block;
164
165- ut_ad(buf_pool_mutex_own(buf_pool));
166+ //ut_ad(buf_pool_mutex_own(buf_pool));
167 ut_ad(!mutex_own(&buf_pool->zip_mutex));
168 ut_a(!ut_align_offset(buf, UNIV_PAGE_SIZE));
169
170+ mutex_enter(&buf_pool->zip_hash_mutex);
171+
172 HASH_SEARCH(hash, buf_pool->zip_hash, fold, buf_page_t*, bpage,
173 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_MEMORY
174 && bpage->in_zip_hash && !bpage->in_page_hash),
175@@ -198,12 +204,14 @@
176 ut_d(bpage->in_zip_hash = FALSE);
177 HASH_DELETE(buf_page_t, hash, buf_pool->zip_hash, fold, bpage);
178
179+ mutex_exit(&buf_pool->zip_hash_mutex);
180+
181 ut_d(memset(buf, 0, UNIV_PAGE_SIZE));
182 UNIV_MEM_INVALID(buf, UNIV_PAGE_SIZE);
183
184 block = (buf_block_t*) bpage;
185 mutex_enter(&block->mutex);
186- buf_LRU_block_free_non_file_page(block);
187+ buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
188 mutex_exit(&block->mutex);
189
190 ut_ad(buf_pool->buddy_n_frames > 0);
191@@ -220,7 +228,7 @@
192 {
193 buf_pool_t* buf_pool = buf_pool_from_block(block);
194 const ulint fold = BUF_POOL_ZIP_FOLD(block);
195- ut_ad(buf_pool_mutex_own(buf_pool));
196+ //ut_ad(buf_pool_mutex_own(buf_pool));
197 ut_ad(!mutex_own(&buf_pool->zip_mutex));
198 ut_ad(buf_block_get_state(block) == BUF_BLOCK_READY_FOR_USE);
199
200@@ -232,7 +240,10 @@
201 ut_ad(!block->page.in_page_hash);
202 ut_ad(!block->page.in_zip_hash);
203 ut_d(block->page.in_zip_hash = TRUE);
204+
205+ mutex_enter(&buf_pool->zip_hash_mutex);
206 HASH_INSERT(buf_page_t, hash, buf_pool->zip_hash, fold, &block->page);
207+ mutex_exit(&buf_pool->zip_hash_mutex);
208
209 ut_d(buf_pool->buddy_n_frames++);
210 }
211@@ -268,7 +279,7 @@
212 bpage->state = BUF_BLOCK_ZIP_FREE;
213 #ifndef UNIV_DEBUG_VALGRIND
214 /* Valgrind would complain about accessing free memory. */
215- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
216+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
217 ut_ad(buf_page_get_state(
218 ut_list_node_313)
219 == BUF_BLOCK_ZIP_FREE)));
220@@ -291,25 +302,29 @@
221 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
222 ulint i, /*!< in: index of buf_pool->zip_free[],
223 or BUF_BUDDY_SIZES */
224- ibool* lru) /*!< in: pointer to a variable that
225+ ibool* lru, /*!< in: pointer to a variable that
226 will be assigned TRUE if storage was
227 allocated from the LRU list and
228 buf_pool->mutex was temporarily
229 released, or NULL if the LRU list
230 should not be used */
231+ ibool have_page_hash_mutex)
232 {
233 buf_block_t* block;
234
235- ut_ad(buf_pool_mutex_own(buf_pool));
236+ //ut_ad(buf_pool_mutex_own(buf_pool));
237+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
238 ut_ad(!mutex_own(&buf_pool->zip_mutex));
239
240 if (i < BUF_BUDDY_SIZES) {
241 /* Try to allocate from the buddy system. */
242+ mutex_enter(&buf_pool->zip_free_mutex);
243 block = buf_buddy_alloc_zip(buf_pool, i);
244
245 if (block) {
246 goto func_exit;
247 }
248+ mutex_exit(&buf_pool->zip_free_mutex);
249 }
250
251 /* Try allocating from the buf_pool->free list. */
252@@ -326,19 +341,30 @@
253 }
254
255 /* Try replacing an uncompressed page in the buffer pool. */
256- buf_pool_mutex_exit(buf_pool);
257+ //buf_pool_mutex_exit(buf_pool);
258+ mutex_exit(&buf_pool->LRU_list_mutex);
259+ if (have_page_hash_mutex) {
260+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
261+ }
df1b5770 262 block = buf_LRU_get_free_block(buf_pool);
b4e1fa2c
AM
263 *lru = TRUE;
264- buf_pool_mutex_enter(buf_pool);
265+ //buf_pool_mutex_enter(buf_pool);
266+ mutex_enter(&buf_pool->LRU_list_mutex);
267+ if (have_page_hash_mutex) {
268+ rw_lock_x_lock(&buf_pool->page_hash_latch);
269+ }
270
271 alloc_big:
272 buf_buddy_block_register(block);
273
274+ mutex_enter(&buf_pool->zip_free_mutex);
275 block = buf_buddy_alloc_from(
276 buf_pool, block->frame, i, BUF_BUDDY_SIZES);
277
278 func_exit:
279 buf_pool->buddy_stat[i].used++;
280+ mutex_exit(&buf_pool->zip_free_mutex);
281+
282 return(block);
283 }
284
285@@ -355,7 +381,10 @@
286 buf_page_t* b;
287 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
288
289- ut_ad(buf_pool_mutex_own(buf_pool));
290+ //ut_ad(buf_pool_mutex_own(buf_pool));
291+#ifdef UNIV_SYNC_DEBUG
292+ ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX));
293+#endif
294
295 switch (buf_page_get_state(bpage)) {
296 case BUF_BLOCK_ZIP_FREE:
297@@ -364,7 +393,7 @@
298 case BUF_BLOCK_FILE_PAGE:
299 case BUF_BLOCK_MEMORY:
300 case BUF_BLOCK_REMOVE_HASH:
301- ut_error;
302+ /* ut_error; */ /* optimistic */
303 case BUF_BLOCK_ZIP_DIRTY:
304 /* Cannot relocate dirty pages. */
305 return(FALSE);
306@@ -374,9 +403,18 @@
307 }
308
309 mutex_enter(&buf_pool->zip_mutex);
310+ mutex_enter(&buf_pool->zip_free_mutex);
311
312 if (!buf_page_can_relocate(bpage)) {
313 mutex_exit(&buf_pool->zip_mutex);
314+ mutex_exit(&buf_pool->zip_free_mutex);
315+ return(FALSE);
316+ }
317+
318+ if (bpage != buf_page_hash_get(buf_pool,
319+ bpage->space, bpage->offset)) {
320+ mutex_exit(&buf_pool->zip_mutex);
321+ mutex_exit(&buf_pool->zip_free_mutex);
322 return(FALSE);
323 }
324
325@@ -384,18 +422,19 @@
326 ut_d(bpage->state = BUF_BLOCK_ZIP_FREE);
327
328 /* relocate buf_pool->zip_clean */
329- b = UT_LIST_GET_PREV(list, dpage);
330- UT_LIST_REMOVE(list, buf_pool->zip_clean, dpage);
331+ b = UT_LIST_GET_PREV(zip_list, dpage);
332+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, dpage);
333
334 if (b) {
335- UT_LIST_INSERT_AFTER(list, buf_pool->zip_clean, b, dpage);
336+ UT_LIST_INSERT_AFTER(zip_list, buf_pool->zip_clean, b, dpage);
337 } else {
338- UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, dpage);
339+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_clean, dpage);
340 }
341
342 UNIV_MEM_INVALID(bpage, sizeof *bpage);
343
344 mutex_exit(&buf_pool->zip_mutex);
345+ mutex_exit(&buf_pool->zip_free_mutex);
346 return(TRUE);
347 }
348
349@@ -409,14 +448,16 @@
350 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
351 void* src, /*!< in: block to relocate */
352 void* dst, /*!< in: free block to relocate to */
353- ulint i) /*!< in: index of
354+ ulint i, /*!< in: index of
355 buf_pool->zip_free[] */
356+ ibool have_page_hash_mutex)
357 {
358 buf_page_t* bpage;
359 const ulint size = BUF_BUDDY_LOW << i;
360 ullint usec = ut_time_us(NULL);
361
362- ut_ad(buf_pool_mutex_own(buf_pool));
363+ //ut_ad(buf_pool_mutex_own(buf_pool));
364+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
365 ut_ad(!mutex_own(&buf_pool->zip_mutex));
366 ut_ad(!ut_align_offset(src, size));
367 ut_ad(!ut_align_offset(dst, size));
d8778560
AM
368@@ -437,6 +478,13 @@
369 if (size >= PAGE_ZIP_MIN_SIZE) {
b4e1fa2c
AM
370 /* This is a compressed page. */
371 mutex_t* mutex;
d8778560
AM
372+ ulint space, page_no;
373+
b4e1fa2c
AM
374+ if (!have_page_hash_mutex) {
375+ mutex_exit(&buf_pool->zip_free_mutex);
376+ mutex_enter(&buf_pool->LRU_list_mutex);
377+ rw_lock_x_lock(&buf_pool->page_hash_latch);
378+ }
d8778560 379
b4e1fa2c
AM
380 /* The src block may be split into smaller blocks,
381 some of which may be free. Thus, the
d8778560
AM
382@@ -446,9 +494,9 @@
383 pool), so there is nothing wrong about this. The
384 mach_read_from_4() calls here will only trigger bogus
385 Valgrind memcheck warnings in UNIV_DEBUG_VALGRIND builds. */
386- ulint space = mach_read_from_4(
387+ space = mach_read_from_4(
388 (const byte*) src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
389- ulint page_no = mach_read_from_4(
390+ page_no = mach_read_from_4(
391 (const byte*) src + FIL_PAGE_OFFSET);
392 /* Suppress Valgrind warnings about conditional jump
393 on uninitialized value. */
394@@ -462,6 +510,11 @@
b4e1fa2c
AM
395 added to buf_pool->page_hash yet. Obviously,
396 it cannot be relocated. */
397
398+ if (!have_page_hash_mutex) {
399+ mutex_enter(&buf_pool->zip_free_mutex);
400+ mutex_exit(&buf_pool->LRU_list_mutex);
401+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
402+ }
403 return(FALSE);
404 }
405
d8778560 406@@ -473,18 +526,27 @@
b4e1fa2c
AM
407 For the sake of simplicity, give up. */
408 ut_ad(page_zip_get_size(&bpage->zip) < size);
409
410+ if (!have_page_hash_mutex) {
411+ mutex_enter(&buf_pool->zip_free_mutex);
412+ mutex_exit(&buf_pool->LRU_list_mutex);
413+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
414+ }
415 return(FALSE);
416 }
417
418+ /* To keep latch order */
419+ if (have_page_hash_mutex)
420+ mutex_exit(&buf_pool->zip_free_mutex);
421+
422 /* The block must have been allocated, but it may
423 contain uninitialized data. */
424 UNIV_MEM_ASSERT_W(src, size);
425
426- mutex = buf_page_get_mutex(bpage);
427+ mutex = buf_page_get_mutex_enter(bpage);
428
429- mutex_enter(mutex);
430+ mutex_enter(&buf_pool->zip_free_mutex);
431
432- if (buf_page_can_relocate(bpage)) {
433+ if (mutex && buf_page_can_relocate(bpage)) {
434 /* Relocate the compressed page. */
435 ut_a(bpage->zip.data == src);
436 memcpy(dst, src, size);
d8778560 437@@ -499,10 +561,22 @@
b4e1fa2c
AM
438 buddy_stat->relocated_usec
439 += ut_time_us(NULL) - usec;
440 }
441+
442+ if (!have_page_hash_mutex) {
443+ mutex_exit(&buf_pool->LRU_list_mutex);
444+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
445+ }
446 return(TRUE);
447 }
448
449- mutex_exit(mutex);
450+ if (!have_page_hash_mutex) {
451+ mutex_exit(&buf_pool->LRU_list_mutex);
452+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
453+ }
454+
455+ if (mutex) {
456+ mutex_exit(mutex);
457+ }
458 } else if (i == buf_buddy_get_slot(sizeof(buf_page_t))) {
459 /* This must be a buf_page_t object. */
460 #if UNIV_WORD_SIZE == 4
d8778560 461@@ -511,10 +585,31 @@
b4e1fa2c
AM
462 about uninitialized pad bytes. */
463 UNIV_MEM_ASSERT_RW(src, size);
464 #endif
465+
466+ mutex_exit(&buf_pool->zip_free_mutex);
467+
468+ if (!have_page_hash_mutex) {
469+ mutex_enter(&buf_pool->LRU_list_mutex);
470+ rw_lock_x_lock(&buf_pool->page_hash_latch);
471+ }
472+
473 if (buf_buddy_relocate_block(src, dst)) {
474+ mutex_enter(&buf_pool->zip_free_mutex);
475+
476+ if (!have_page_hash_mutex) {
477+ mutex_exit(&buf_pool->LRU_list_mutex);
478+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
479+ }
480
481 goto success;
482 }
483+
484+ mutex_enter(&buf_pool->zip_free_mutex);
485+
486+ if (!have_page_hash_mutex) {
487+ mutex_exit(&buf_pool->LRU_list_mutex);
488+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
489+ }
490 }
491
492 return(FALSE);
d8778560 493@@ -529,13 +624,15 @@
b4e1fa2c
AM
494 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
495 void* buf, /*!< in: block to be freed, must not be
496 pointed to by the buffer pool */
497- ulint i) /*!< in: index of buf_pool->zip_free[],
498+ ulint i, /*!< in: index of buf_pool->zip_free[],
499 or BUF_BUDDY_SIZES */
500+ ibool have_page_hash_mutex)
501 {
502 buf_page_t* bpage;
503 buf_page_t* buddy;
504
505- ut_ad(buf_pool_mutex_own(buf_pool));
506+ //ut_ad(buf_pool_mutex_own(buf_pool));
507+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
508 ut_ad(!mutex_own(&buf_pool->zip_mutex));
509 ut_ad(i <= BUF_BUDDY_SIZES);
510 ut_ad(buf_pool->buddy_stat[i].used > 0);
d8778560 511@@ -546,7 +643,9 @@
b4e1fa2c
AM
512 ut_d(((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE);
513
514 if (i == BUF_BUDDY_SIZES) {
515- buf_buddy_block_free(buf_pool, buf);
516+ mutex_exit(&buf_pool->zip_free_mutex);
517+ buf_buddy_block_free(buf_pool, buf, have_page_hash_mutex);
518+ mutex_enter(&buf_pool->zip_free_mutex);
519 return;
520 }
521
d8778560 522@@ -591,7 +690,7 @@
b4e1fa2c
AM
523 ut_a(bpage != buf);
524
525 {
526- buf_page_t* next = UT_LIST_GET_NEXT(list, bpage);
527+ buf_page_t* next = UT_LIST_GET_NEXT(zip_list, bpage);
528 UNIV_MEM_ASSERT_AND_FREE(bpage, BUF_BUDDY_LOW << i);
529 bpage = next;
530 }
d8778560 531@@ -600,13 +699,13 @@
b4e1fa2c
AM
532 #ifndef UNIV_DEBUG_VALGRIND
533 buddy_nonfree:
534 /* Valgrind would complain about accessing free memory. */
535- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
536+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
537 ut_ad(buf_page_get_state(ut_list_node_313)
538 == BUF_BLOCK_ZIP_FREE)));
539 #endif /* UNIV_DEBUG_VALGRIND */
540
541 /* The buddy is not free. Is there a free block of this size? */
542- bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
543+ bpage = UT_LIST_GET_LAST(buf_pool->zip_free[i]);
544
545 if (bpage) {
546 /* Remove the block from the free list, because a successful
d8778560 547@@ -616,7 +715,7 @@
b4e1fa2c
AM
548 buf_buddy_remove_from_free(buf_pool, bpage, i);
549
550 /* Try to relocate the buddy of buf to the free block. */
551- if (buf_buddy_relocate(buf_pool, buddy, bpage, i)) {
552+ if (buf_buddy_relocate(buf_pool, buddy, bpage, i, have_page_hash_mutex)) {
553
554 ut_d(buddy->state = BUF_BLOCK_ZIP_FREE);
555 goto buddy_free2;
d8778560 556@@ -636,14 +735,14 @@
b4e1fa2c
AM
557
558 (Parts of the buddy can be free in
559 buf_pool->zip_free[j] with j < i.) */
560- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
561+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
562 ut_ad(buf_page_get_state(
563 ut_list_node_313)
564 == BUF_BLOCK_ZIP_FREE
565 && ut_list_node_313 != buddy)));
566 #endif /* !UNIV_DEBUG_VALGRIND */
567
568- if (buf_buddy_relocate(buf_pool, buddy, buf, i)) {
569+ if (buf_buddy_relocate(buf_pool, buddy, buf, i, have_page_hash_mutex)) {
570
571 buf = bpage;
572 UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
573diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
574--- a/storage/innobase/buf/buf0buf.c 2010-12-03 15:22:36.314943336 +0900
575+++ b/storage/innobase/buf/buf0buf.c 2010-12-03 15:48:29.282947357 +0900
576@@ -263,6 +263,7 @@
577 #ifdef UNIV_PFS_RWLOCK
578 /* Keys to register buffer block related rwlocks and mutexes with
579 performance schema */
580+UNIV_INTERN mysql_pfs_key_t buf_pool_page_hash_key;
581 UNIV_INTERN mysql_pfs_key_t buf_block_lock_key;
582 # ifdef UNIV_SYNC_DEBUG
583 UNIV_INTERN mysql_pfs_key_t buf_block_debug_latch_key;
584@@ -273,6 +274,10 @@
585 UNIV_INTERN mysql_pfs_key_t buffer_block_mutex_key;
586 UNIV_INTERN mysql_pfs_key_t buf_pool_mutex_key;
587 UNIV_INTERN mysql_pfs_key_t buf_pool_zip_mutex_key;
588+UNIV_INTERN mysql_pfs_key_t buf_pool_LRU_list_mutex_key;
589+UNIV_INTERN mysql_pfs_key_t buf_pool_free_list_mutex_key;
590+UNIV_INTERN mysql_pfs_key_t buf_pool_zip_free_mutex_key;
591+UNIV_INTERN mysql_pfs_key_t buf_pool_zip_hash_mutex_key;
592 UNIV_INTERN mysql_pfs_key_t flush_list_mutex_key;
593 #endif /* UNIV_PFS_MUTEX */
594
adf0fb13 595@@ -881,9 +886,13 @@
b4e1fa2c
AM
596 block->page.in_zip_hash = FALSE;
597 block->page.in_flush_list = FALSE;
598 block->page.in_free_list = FALSE;
599- block->in_unzip_LRU_list = FALSE;
600 #endif /* UNIV_DEBUG */
adf0fb13
AM
601+ block->page.flush_list.prev = NULL;
602+ block->page.flush_list.next = NULL;
603+ block->page.zip_list.prev = NULL;
604+ block->page.zip_list.next = NULL;
b4e1fa2c
AM
605 block->page.in_LRU_list = FALSE;
606+ block->in_unzip_LRU_list = FALSE;
607 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
608 block->n_pointers = 0;
609 #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
adf0fb13 610@@ -981,9 +990,11 @@
b4e1fa2c
AM
611 memset(block->frame, '\0', UNIV_PAGE_SIZE);
612 #endif
613 /* Add the block to the free list */
614- UT_LIST_ADD_LAST(list, buf_pool->free, (&block->page));
615+ mutex_enter(&buf_pool->free_list_mutex);
616+ UT_LIST_ADD_LAST(free, buf_pool->free, (&block->page));
617
618 ut_d(block->page.in_free_list = TRUE);
619+ mutex_exit(&buf_pool->free_list_mutex);
620 ut_ad(buf_pool_from_block(block) == buf_pool);
621
622 block++;
adf0fb13 623@@ -1038,7 +1049,8 @@
b4e1fa2c
AM
624 buf_chunk_t* chunk = buf_pool->chunks;
625
626 ut_ad(buf_pool);
627- ut_ad(buf_pool_mutex_own(buf_pool));
628+ //ut_ad(buf_pool_mutex_own(buf_pool));
629+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
630 for (n = buf_pool->n_chunks; n--; chunk++) {
631
632 buf_block_t* block = buf_chunk_contains_zip(chunk, data);
adf0fb13 633@@ -1138,7 +1150,7 @@
b4e1fa2c
AM
634 buf_block_t* block;
635 const buf_block_t* block_end;
636
637- ut_ad(buf_pool_mutex_own(buf_pool));
638+ //ut_ad(buf_pool_mutex_own(buf_pool)); /* but we need all mutex here */
639
640 block_end = chunk->blocks + chunk->size;
641
adf0fb13 642@@ -1150,8 +1162,10 @@
b4e1fa2c
AM
643 ut_ad(!block->in_unzip_LRU_list);
644 ut_ad(!block->page.in_flush_list);
645 /* Remove the block from the free list. */
646+ mutex_enter(&buf_pool->free_list_mutex);
647 ut_ad(block->page.in_free_list);
648- UT_LIST_REMOVE(list, buf_pool->free, (&block->page));
649+ UT_LIST_REMOVE(free, buf_pool->free, (&block->page));
650+ mutex_exit(&buf_pool->free_list_mutex);
651
652 /* Free the latches. */
653 mutex_free(&block->mutex);
adf0fb13 654@@ -1208,9 +1222,21 @@
b4e1fa2c
AM
655 ------------------------------- */
656 mutex_create(buf_pool_mutex_key,
657 &buf_pool->mutex, SYNC_BUF_POOL);
658+ mutex_create(buf_pool_LRU_list_mutex_key,
659+ &buf_pool->LRU_list_mutex, SYNC_BUF_LRU_LIST);
660+ rw_lock_create(buf_pool_page_hash_key,
661+ &buf_pool->page_hash_latch, SYNC_BUF_PAGE_HASH);
662+ mutex_create(buf_pool_free_list_mutex_key,
663+ &buf_pool->free_list_mutex, SYNC_BUF_FREE_LIST);
664+ mutex_create(buf_pool_zip_free_mutex_key,
665+ &buf_pool->zip_free_mutex, SYNC_BUF_ZIP_FREE);
666+ mutex_create(buf_pool_zip_hash_mutex_key,
667+ &buf_pool->zip_hash_mutex, SYNC_BUF_ZIP_HASH);
668 mutex_create(buf_pool_zip_mutex_key,
669 &buf_pool->zip_mutex, SYNC_BUF_BLOCK);
670
671+ mutex_enter(&buf_pool->LRU_list_mutex);
672+ rw_lock_x_lock(&buf_pool->page_hash_latch);
673 buf_pool_mutex_enter(buf_pool);
674
675 if (buf_pool_size > 0) {
adf0fb13 676@@ -1223,6 +1249,8 @@
b4e1fa2c
AM
677 mem_free(chunk);
678 mem_free(buf_pool);
679
680+ mutex_exit(&buf_pool->LRU_list_mutex);
681+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
682 buf_pool_mutex_exit(buf_pool);
683
684 return(DB_ERROR);
adf0fb13 685@@ -1253,6 +1281,8 @@
b4e1fa2c
AM
686
687 /* All fields are initialized by mem_zalloc(). */
688
689+ mutex_exit(&buf_pool->LRU_list_mutex);
690+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
691 buf_pool_mutex_exit(buf_pool);
692
693 return(DB_SUCCESS);
adf0fb13 694@@ -1467,7 +1497,11 @@
b4e1fa2c
AM
695 ulint fold;
696 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
697
698- ut_ad(buf_pool_mutex_own(buf_pool));
699+ //ut_ad(buf_pool_mutex_own(buf_pool));
700+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
701+#ifdef UNIV_SYNC_DEBUG
702+ ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX));
703+#endif
704 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
705 ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
706 ut_a(bpage->buf_fix_count == 0);
adf0fb13 707@@ -1554,7 +1588,8 @@
b4e1fa2c
AM
708
709 try_again:
710 btr_search_disable(); /* Empty the adaptive hash index again */
711- buf_pool_mutex_enter(buf_pool);
712+ //buf_pool_mutex_enter(buf_pool);
713+ mutex_enter(&buf_pool->LRU_list_mutex);
714
715 shrink_again:
716 if (buf_pool->n_chunks <= 1) {
adf0fb13 717@@ -1625,7 +1660,7 @@
b4e1fa2c
AM
718
719 buf_LRU_make_block_old(&block->page);
720 dirty++;
df1b5770
AM
721- } else if (buf_LRU_free_block(&block->page, TRUE)
722+ } else if (buf_LRU_free_block(&block->page, TRUE, TRUE)
b4e1fa2c
AM
723 != BUF_LRU_FREED) {
724 nonfree++;
725 }
adf0fb13 726@@ -1633,7 +1668,8 @@
b4e1fa2c
AM
727 mutex_exit(&block->mutex);
728 }
729
730- buf_pool_mutex_exit(buf_pool);
731+ //buf_pool_mutex_exit(buf_pool);
732+ mutex_exit(&buf_pool->LRU_list_mutex);
733
734 /* Request for a flush of the chunk if it helps.
735 Do not flush if there are non-free blocks, since
adf0fb13 736@@ -1683,7 +1719,8 @@
b4e1fa2c
AM
737 func_done:
738 buf_pool->old_pool_size = buf_pool->curr_pool_size;
739 func_exit:
740- buf_pool_mutex_exit(buf_pool);
741+ //buf_pool_mutex_exit(buf_pool);
742+ mutex_exit(&buf_pool->LRU_list_mutex);
743 btr_search_enable();
744 }
745
adf0fb13 746@@ -1724,7 +1761,9 @@
b4e1fa2c
AM
747 hash_table_t* zip_hash;
748 hash_table_t* page_hash;
749
750- buf_pool_mutex_enter(buf_pool);
751+ //buf_pool_mutex_enter(buf_pool);
752+ mutex_enter(&buf_pool->LRU_list_mutex);
753+ rw_lock_x_lock(&buf_pool->page_hash_latch);
754
755 /* Free, create, and populate the hash table. */
756 hash_table_free(buf_pool->page_hash);
adf0fb13 757@@ -1765,8 +1804,9 @@
b4e1fa2c
AM
758 All such blocks are either in buf_pool->zip_clean or
759 in buf_pool->flush_list. */
760
761+ mutex_enter(&buf_pool->zip_mutex);
762 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
763- b = UT_LIST_GET_NEXT(list, b)) {
764+ b = UT_LIST_GET_NEXT(zip_list, b)) {
765 ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
766 ut_ad(!b->in_flush_list);
767 ut_ad(b->in_LRU_list);
adf0fb13 768@@ -1776,10 +1816,11 @@
b4e1fa2c
AM
769 HASH_INSERT(buf_page_t, hash, page_hash,
770 buf_page_address_fold(b->space, b->offset), b);
771 }
772+ mutex_exit(&buf_pool->zip_mutex);
773
774 buf_flush_list_mutex_enter(buf_pool);
775 for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
776- b = UT_LIST_GET_NEXT(list, b)) {
777+ b = UT_LIST_GET_NEXT(flush_list, b)) {
778 ut_ad(b->in_flush_list);
779 ut_ad(b->in_LRU_list);
780 ut_ad(b->in_page_hash);
adf0fb13 781@@ -1806,7 +1847,9 @@
b4e1fa2c
AM
782 }
783
784 buf_flush_list_mutex_exit(buf_pool);
785- buf_pool_mutex_exit(buf_pool);
786+ //buf_pool_mutex_exit(buf_pool);
787+ mutex_exit(&buf_pool->LRU_list_mutex);
788+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
789 }
790
791 /********************************************************************
adf0fb13 792@@ -1853,21 +1896,32 @@
b4e1fa2c
AM
793 buf_page_t* bpage;
794 ulint i;
795 buf_pool_t* buf_pool = buf_pool_get(space, offset);
796+ mutex_t* block_mutex;
797
798- ut_ad(buf_pool_mutex_own(buf_pool));
799+ //ut_ad(buf_pool_mutex_own(buf_pool));
800
801+ rw_lock_x_lock(&buf_pool->page_hash_latch);
802 bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
803+ if (bpage) {
804+ block_mutex = buf_page_get_mutex_enter(bpage);
805+ ut_a(block_mutex);
806+ }
807
808 if (UNIV_LIKELY_NULL(bpage)) {
809 if (!buf_pool_watch_is_sentinel(buf_pool, bpage)) {
810 /* The page was loaded meanwhile. */
811+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
812 return(bpage);
813 }
814 /* Add to an existing watch. */
815 bpage->buf_fix_count++;
816+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
817+ mutex_exit(block_mutex);
818 return(NULL);
819 }
820
821+ /* buf_pool->watch is protected by zip_mutex for now */
822+ mutex_enter(&buf_pool->zip_mutex);
823 for (i = 0; i < BUF_POOL_WATCH_SIZE; i++) {
824 bpage = &buf_pool->watch[i];
825
adf0fb13 826@@ -1891,10 +1945,12 @@
b4e1fa2c
AM
827 bpage->space = space;
828 bpage->offset = offset;
829 bpage->buf_fix_count = 1;
830-
831+ bpage->buf_pool_index = buf_pool_index(buf_pool);
832 ut_d(bpage->in_page_hash = TRUE);
833 HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
834 fold, bpage);
835+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
836+ mutex_exit(&buf_pool->zip_mutex);
837 return(NULL);
838 case BUF_BLOCK_ZIP_PAGE:
839 ut_ad(bpage->in_page_hash);
adf0fb13 840@@ -1912,6 +1968,8 @@
b4e1fa2c
AM
841 ut_error;
842
843 /* Fix compiler warning */
844+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
845+ mutex_exit(&buf_pool->zip_mutex);
846 return(NULL);
847 }
848
adf0fb13 849@@ -1941,6 +1999,8 @@
b4e1fa2c
AM
850 buf_chunk_t* chunks;
851 buf_chunk_t* chunk;
852
853+ mutex_enter(&buf_pool->LRU_list_mutex);
854+ rw_lock_x_lock(&buf_pool->page_hash_latch);
855 buf_pool_mutex_enter(buf_pool);
856 chunks = mem_alloc((buf_pool->n_chunks + 1) * sizeof *chunks);
857
adf0fb13 858@@ -1959,6 +2019,8 @@
b4e1fa2c
AM
859 buf_pool->n_chunks++;
860 }
861
862+ mutex_exit(&buf_pool->LRU_list_mutex);
863+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
864 buf_pool_mutex_exit(buf_pool);
865 }
866
adf0fb13 867@@ -2046,7 +2108,11 @@
b4e1fa2c
AM
868 space, offset) */
869 buf_page_t* watch) /*!< in/out: sentinel for watch */
870 {
871- ut_ad(buf_pool_mutex_own(buf_pool));
872+ //ut_ad(buf_pool_mutex_own(buf_pool));
873+#ifdef UNIV_SYNC_DEBUG
874+ ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX));
875+#endif
876+ ut_ad(mutex_own(&buf_pool->zip_mutex)); /* for now */
877
878 HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, watch);
879 ut_d(watch->in_page_hash = FALSE);
adf0fb13 880@@ -2068,28 +2134,31 @@
b4e1fa2c
AM
881 buf_pool_t* buf_pool = buf_pool_get(space, offset);
882 ulint fold = buf_page_address_fold(space, offset);
883
884- buf_pool_mutex_enter(buf_pool);
885+ //buf_pool_mutex_enter(buf_pool);
886+ rw_lock_x_lock(&buf_pool->page_hash_latch);
887 bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
888 /* The page must exist because buf_pool_watch_set()
889 increments buf_fix_count. */
890 ut_a(bpage);
891
892 if (UNIV_UNLIKELY(!buf_pool_watch_is_sentinel(buf_pool, bpage))) {
893- mutex_t* mutex = buf_page_get_mutex(bpage);
894+ mutex_t* mutex = buf_page_get_mutex_enter(bpage);
895
896- mutex_enter(mutex);
897 ut_a(bpage->buf_fix_count > 0);
898 bpage->buf_fix_count--;
899 mutex_exit(mutex);
900 } else {
901+ mutex_enter(&buf_pool->zip_mutex);
902 ut_a(bpage->buf_fix_count > 0);
903
904 if (UNIV_LIKELY(!--bpage->buf_fix_count)) {
905 buf_pool_watch_remove(buf_pool, fold, bpage);
906 }
907+ mutex_exit(&buf_pool->zip_mutex);
908 }
909
910- buf_pool_mutex_exit(buf_pool);
911+ //buf_pool_mutex_exit(buf_pool);
912+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
913 }
914
915 /****************************************************************//**
adf0fb13 916@@ -2109,14 +2178,16 @@
b4e1fa2c
AM
917 buf_pool_t* buf_pool = buf_pool_get(space, offset);
918 ulint fold = buf_page_address_fold(space, offset);
919
920- buf_pool_mutex_enter(buf_pool);
921+ //buf_pool_mutex_enter(buf_pool);
922+ rw_lock_s_lock(&buf_pool->page_hash_latch);
923
924 bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
925 /* The page must exist because buf_pool_watch_set()
926 increments buf_fix_count. */
927 ut_a(bpage);
928 ret = !buf_pool_watch_is_sentinel(buf_pool, bpage);
929- buf_pool_mutex_exit(buf_pool);
930+ //buf_pool_mutex_exit(buf_pool);
931+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
932
933 return(ret);
934 }
adf0fb13 935@@ -2133,13 +2204,15 @@
b4e1fa2c
AM
936 {
937 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
938
939- buf_pool_mutex_enter(buf_pool);
940+ //buf_pool_mutex_enter(buf_pool);
941+ mutex_enter(&buf_pool->LRU_list_mutex);
942
943 ut_a(buf_page_in_file(bpage));
944
945 buf_LRU_make_block_young(bpage);
946
947- buf_pool_mutex_exit(buf_pool);
948+ //buf_pool_mutex_exit(buf_pool);
949+ mutex_exit(&buf_pool->LRU_list_mutex);
950 }
951
952 /********************************************************************//**
adf0fb13 953@@ -2163,14 +2236,20 @@
b4e1fa2c
AM
954 ut_a(buf_page_in_file(bpage));
955
956 if (buf_page_peek_if_too_old(bpage)) {
957- buf_pool_mutex_enter(buf_pool);
958+ //buf_pool_mutex_enter(buf_pool);
959+ mutex_enter(&buf_pool->LRU_list_mutex);
960 buf_LRU_make_block_young(bpage);
961- buf_pool_mutex_exit(buf_pool);
962+ //buf_pool_mutex_exit(buf_pool);
963+ mutex_exit(&buf_pool->LRU_list_mutex);
964 } else if (!access_time) {
965 ulint time_ms = ut_time_ms();
966- buf_pool_mutex_enter(buf_pool);
967+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
968+ //buf_pool_mutex_enter(buf_pool);
969+ if (block_mutex) {
970 buf_page_set_accessed(bpage, time_ms);
971- buf_pool_mutex_exit(buf_pool);
972+ mutex_exit(block_mutex);
973+ }
974+ //buf_pool_mutex_exit(buf_pool);
975 }
976 }
977
adf0fb13 978@@ -2187,7 +2266,8 @@
b4e1fa2c
AM
979 buf_block_t* block;
980 buf_pool_t* buf_pool = buf_pool_get(space, offset);
981
982- buf_pool_mutex_enter(buf_pool);
983+ //buf_pool_mutex_enter(buf_pool);
984+ rw_lock_s_lock(&buf_pool->page_hash_latch);
985
986 block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset);
987
adf0fb13 988@@ -2196,7 +2276,8 @@
b4e1fa2c
AM
989 block->check_index_page_at_flush = FALSE;
990 }
991
992- buf_pool_mutex_exit(buf_pool);
993+ //buf_pool_mutex_exit(buf_pool);
994+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
995 }
996
997 /********************************************************************//**
adf0fb13 998@@ -2215,7 +2296,8 @@
b4e1fa2c
AM
999 ibool is_hashed;
1000 buf_pool_t* buf_pool = buf_pool_get(space, offset);
1001
1002- buf_pool_mutex_enter(buf_pool);
1003+ //buf_pool_mutex_enter(buf_pool);
1004+ rw_lock_s_lock(&buf_pool->page_hash_latch);
1005
1006 block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset);
1007
adf0fb13 1008@@ -2226,7 +2308,8 @@
b4e1fa2c
AM
1009 is_hashed = block->is_hashed;
1010 }
1011
1012- buf_pool_mutex_exit(buf_pool);
1013+ //buf_pool_mutex_exit(buf_pool);
1014+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
1015
1016 return(is_hashed);
1017 }
adf0fb13 1018@@ -2248,7 +2331,8 @@
b4e1fa2c
AM
1019 buf_page_t* bpage;
1020 buf_pool_t* buf_pool = buf_pool_get(space, offset);
1021
1022- buf_pool_mutex_enter(buf_pool);
1023+ //buf_pool_mutex_enter(buf_pool);
1024+ rw_lock_s_lock(&buf_pool->page_hash_latch);
1025
1026 bpage = buf_page_hash_get(buf_pool, space, offset);
1027
adf0fb13 1028@@ -2259,7 +2343,8 @@
b4e1fa2c
AM
1029 bpage->file_page_was_freed = TRUE;
1030 }
1031
1032- buf_pool_mutex_exit(buf_pool);
1033+ //buf_pool_mutex_exit(buf_pool);
1034+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
1035
1036 return(bpage);
1037 }
adf0fb13 1038@@ -2280,7 +2365,8 @@
b4e1fa2c
AM
1039 buf_page_t* bpage;
1040 buf_pool_t* buf_pool = buf_pool_get(space, offset);
1041
1042- buf_pool_mutex_enter(buf_pool);
1043+ //buf_pool_mutex_enter(buf_pool);
1044+ rw_lock_s_lock(&buf_pool->page_hash_latch);
1045
1046 bpage = buf_page_hash_get(buf_pool, space, offset);
1047
adf0fb13 1048@@ -2289,7 +2375,8 @@
b4e1fa2c
AM
1049 bpage->file_page_was_freed = FALSE;
1050 }
1051
1052- buf_pool_mutex_exit(buf_pool);
1053+ //buf_pool_mutex_exit(buf_pool);
1054+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
1055
1056 return(bpage);
1057 }
adf0fb13 1058@@ -2321,8 +2408,9 @@
b4e1fa2c
AM
1059 buf_pool->stat.n_page_gets++;
1060
1061 for (;;) {
1062- buf_pool_mutex_enter(buf_pool);
1063+ //buf_pool_mutex_enter(buf_pool);
1064 lookup:
1065+ rw_lock_s_lock(&buf_pool->page_hash_latch);
1066 bpage = buf_page_hash_get(buf_pool, space, offset);
1067 if (bpage) {
1068 ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
adf0fb13 1069@@ -2331,7 +2419,8 @@
b4e1fa2c
AM
1070
1071 /* Page not in buf_pool: needs to be read from file */
1072
1073- buf_pool_mutex_exit(buf_pool);
1074+ //buf_pool_mutex_exit(buf_pool);
1075+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
1076
1077 buf_read_page(space, zip_size, offset);
1078
adf0fb13 1079@@ -2343,10 +2432,15 @@
b4e1fa2c
AM
1080 if (UNIV_UNLIKELY(!bpage->zip.data)) {
1081 /* There is no compressed page. */
1082 err_exit:
1083- buf_pool_mutex_exit(buf_pool);
1084+ //buf_pool_mutex_exit(buf_pool);
1085+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
1086 return(NULL);
1087 }
1088
1089+ block_mutex = buf_page_get_mutex_enter(bpage);
1090+
1091+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
1092+
1093 ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
1094
1095 switch (buf_page_get_state(bpage)) {
f7ab7acd 1096@@ -2355,24 +2449,43 @@
b4e1fa2c
AM
1097 case BUF_BLOCK_MEMORY:
1098 case BUF_BLOCK_REMOVE_HASH:
1099 case BUF_BLOCK_ZIP_FREE:
1100+ if (block_mutex)
1101+ mutex_exit(block_mutex);
1102 break;
1103 case BUF_BLOCK_ZIP_PAGE:
1104 case BUF_BLOCK_ZIP_DIRTY:
1105- block_mutex = &buf_pool->zip_mutex;
1106- mutex_enter(block_mutex);
1107+ ut_a(block_mutex == &buf_pool->zip_mutex);
1108 bpage->buf_fix_count++;
1109 goto got_block;
1110 case BUF_BLOCK_FILE_PAGE:
1111- block_mutex = &((buf_block_t*) bpage)->mutex;
b4e1fa2c 1112+ ut_a(block_mutex == &((buf_block_t*) bpage)->mutex);
f7ab7acd
AM
1113+
1114+ /* release mutex to obey to latch-order */
1115+ mutex_exit(block_mutex);
1116+
1117+ /* get LRU_list_mutex for buf_LRU_free_block() */
1118+ mutex_enter(&buf_pool->LRU_list_mutex);
1119 mutex_enter(block_mutex);
b4e1fa2c 1120
f7ab7acd 1121- /* Discard the uncompressed page frame if possible. */
df1b5770 1122- if (buf_LRU_free_block(bpage, FALSE) == BUF_LRU_FREED) {
f7ab7acd
AM
1123+ if (UNIV_UNLIKELY(bpage->space != space
1124+ || bpage->offset != offset
1125+ || !bpage->in_LRU_list
1126+ || !bpage->zip.data)) {
1127+ /* someone should interrupt, retry */
1128+ mutex_exit(&buf_pool->LRU_list_mutex);
1129+ mutex_exit(block_mutex);
1130+ goto lookup;
1131+ }
b4e1fa2c 1132
f7ab7acd
AM
1133+ /* Discard the uncompressed page frame if possible. */
1134+ if (buf_LRU_free_block(bpage, FALSE, TRUE) == BUF_LRU_FREED) {
1135+ mutex_exit(&buf_pool->LRU_list_mutex);
b4e1fa2c 1136 mutex_exit(block_mutex);
df1b5770 1137 goto lookup;
f7ab7acd
AM
1138 }
1139
1140+ mutex_exit(&buf_pool->LRU_list_mutex);
1141+
1142 buf_block_buf_fix_inc((buf_block_t*) bpage,
1143 __FILE__, __LINE__);
1144 goto got_block;
1145@@ -2385,7 +2498,7 @@
b4e1fa2c
AM
1146 must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
1147 access_time = buf_page_is_accessed(bpage);
1148
1149- buf_pool_mutex_exit(buf_pool);
1150+ //buf_pool_mutex_exit(buf_pool);
1151
1152 mutex_exit(block_mutex);
1153
f7ab7acd 1154@@ -2697,7 +2810,7 @@
b4e1fa2c
AM
1155 const buf_block_t* block) /*!< in: pointer to block,
1156 not dereferenced */
1157 {
1158- ut_ad(buf_pool_mutex_own(buf_pool));
1159+ //ut_ad(buf_pool_mutex_own(buf_pool));
1160
1161 if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
1162 /* The pointer should be aligned. */
f7ab7acd 1163@@ -2733,6 +2846,7 @@
b4e1fa2c
AM
1164 ulint fix_type;
1165 ibool must_read;
1166 ulint retries = 0;
1167+ mutex_t* block_mutex = NULL;
1168 buf_pool_t* buf_pool = buf_pool_get(space, offset);
1169
1170 ut_ad(mtr);
f7ab7acd 1171@@ -2765,9 +2879,11 @@
b4e1fa2c
AM
1172 fold = buf_page_address_fold(space, offset);
1173 loop:
1174 block = guess;
1175- buf_pool_mutex_enter(buf_pool);
1176+ //buf_pool_mutex_enter(buf_pool);
1177
1178 if (block) {
1179+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
1180+
1181 /* If the guess is a compressed page descriptor that
1182 has been allocated by buf_buddy_alloc(), it may have
1183 been invalidated by buf_buddy_relocate(). In that
f7ab7acd 1184@@ -2776,11 +2892,15 @@
b4e1fa2c
AM
1185 the guess may be pointing to a buffer pool chunk that
1186 has been released when resizing the buffer pool. */
1187
1188- if (!buf_block_is_uncompressed(buf_pool, block)
1189+ if (!block_mutex) {
1190+ block = guess = NULL;
1191+ } else if (!buf_block_is_uncompressed(buf_pool, block)
1192 || offset != block->page.offset
1193 || space != block->page.space
1194 || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
1195
1196+ mutex_exit(block_mutex);
1197+
1198 block = guess = NULL;
1199 } else {
1200 ut_ad(!block->page.in_zip_hash);
f7ab7acd 1201@@ -2789,12 +2909,19 @@
b4e1fa2c
AM
1202 }
1203
1204 if (block == NULL) {
1205+ rw_lock_s_lock(&buf_pool->page_hash_latch);
1206 block = (buf_block_t*) buf_page_hash_get_low(
1207 buf_pool, space, offset, fold);
1208+ if (block) {
1209+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
1210+ ut_a(block_mutex);
1211+ }
1212+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
1213 }
1214
1215 loop2:
1216 if (block && buf_pool_watch_is_sentinel(buf_pool, &block->page)) {
1217+ mutex_exit(block_mutex);
1218 block = NULL;
1219 }
1220
f7ab7acd 1221@@ -2806,12 +2933,14 @@
b4e1fa2c
AM
1222 space, offset, fold);
1223
1224 if (UNIV_LIKELY_NULL(block)) {
1225-
1226+ block_mutex = buf_page_get_mutex((buf_page_t*)block);
1227+ ut_a(block_mutex);
1228+ ut_ad(mutex_own(block_mutex));
1229 goto got_block;
1230 }
1231 }
1232
1233- buf_pool_mutex_exit(buf_pool);
1234+ //buf_pool_mutex_exit(buf_pool);
1235
1236 if (mode == BUF_GET_IF_IN_POOL
adf0fb13 1237 || mode == BUF_PEEK_IF_IN_POOL
f7ab7acd 1238@@ -2861,7 +2990,8 @@
b4e1fa2c
AM
1239 /* The page is being read to buffer pool,
1240 but we cannot wait around for the read to
1241 complete. */
1242- buf_pool_mutex_exit(buf_pool);
1243+ //buf_pool_mutex_exit(buf_pool);
1244+ mutex_exit(block_mutex);
1245
1246 return(NULL);
1247 }
f7ab7acd 1248@@ -2871,38 +3001,49 @@
b4e1fa2c
AM
1249 ibool success;
1250
1251 case BUF_BLOCK_FILE_PAGE:
1252+ if (block_mutex == &buf_pool->zip_mutex) {
1253+ /* it is wrong mutex... */
1254+ mutex_exit(block_mutex);
1255+ goto loop;
1256+ }
1257 break;
1258
1259 case BUF_BLOCK_ZIP_PAGE:
1260 case BUF_BLOCK_ZIP_DIRTY:
1261+ ut_ad(block_mutex == &buf_pool->zip_mutex);
1262 bpage = &block->page;
1263 /* Protect bpage->buf_fix_count. */
1264- mutex_enter(&buf_pool->zip_mutex);
1265+ //mutex_enter(&buf_pool->zip_mutex);
1266
1267 if (bpage->buf_fix_count
1268 || buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
1269 /* This condition often occurs when the buffer
1270 is not buffer-fixed, but I/O-fixed by
1271 buf_page_init_for_read(). */
1272- mutex_exit(&buf_pool->zip_mutex);
1273+ //mutex_exit(&buf_pool->zip_mutex);
1274 wait_until_unfixed:
1275 /* The block is buffer-fixed or I/O-fixed.
1276 Try again later. */
1277- buf_pool_mutex_exit(buf_pool);
1278+ //buf_pool_mutex_exit(buf_pool);
1279+ mutex_exit(block_mutex);
1280 os_thread_sleep(WAIT_FOR_READ);
adf0fb13 1281
b4e1fa2c
AM
1282 goto loop;
1283 }
1284
1285 /* Allocate an uncompressed page. */
1286- buf_pool_mutex_exit(buf_pool);
1287- mutex_exit(&buf_pool->zip_mutex);
1288+ //buf_pool_mutex_exit(buf_pool);
1289+ //mutex_exit(&buf_pool->zip_mutex);
1290+ mutex_exit(block_mutex);
1291
df1b5770 1292 block = buf_LRU_get_free_block(buf_pool);
b4e1fa2c
AM
1293 ut_a(block);
1294+ block_mutex = &block->mutex;
1295
1296- buf_pool_mutex_enter(buf_pool);
1297- mutex_enter(&block->mutex);
1298+ //buf_pool_mutex_enter(buf_pool);
1299+ mutex_enter(&buf_pool->LRU_list_mutex);
1300+ rw_lock_x_lock(&buf_pool->page_hash_latch);
1301+ mutex_enter(block_mutex);
1302
1303 {
1304 buf_page_t* hash_bpage;
f7ab7acd 1305@@ -2915,35 +3056,47 @@
b4e1fa2c
AM
1306 while buf_pool->mutex was released.
1307 Free the block that was allocated. */
1308
1309- buf_LRU_block_free_non_file_page(block);
1310- mutex_exit(&block->mutex);
1311+ buf_LRU_block_free_non_file_page(block, TRUE);
1312+ mutex_exit(block_mutex);
1313
1314 block = (buf_block_t*) hash_bpage;
1315+ if (block) {
1316+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
1317+ ut_a(block_mutex);
1318+ }
1319+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1320+ mutex_exit(&buf_pool->LRU_list_mutex);
1321 goto loop2;
1322 }
1323 }
1324
1325+ mutex_enter(&buf_pool->zip_mutex);
1326+
1327 if (UNIV_UNLIKELY
1328 (bpage->buf_fix_count
1329 || buf_page_get_io_fix(bpage) != BUF_IO_NONE)) {
1330
1331+ mutex_exit(&buf_pool->zip_mutex);
1332 /* The block was buffer-fixed or I/O-fixed
1333 while buf_pool->mutex was not held by this thread.
1334 Free the block that was allocated and try again.
1335 This should be extremely unlikely. */
1336
1337- buf_LRU_block_free_non_file_page(block);
1338- mutex_exit(&block->mutex);
1339+ buf_LRU_block_free_non_file_page(block, TRUE);
1340+ //mutex_exit(&block->mutex);
1341
1342+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1343+ mutex_exit(&buf_pool->LRU_list_mutex);
1344 goto wait_until_unfixed;
1345 }
1346
1347 /* Move the compressed page from bpage to block,
1348 and uncompress it. */
1349
1350- mutex_enter(&buf_pool->zip_mutex);
1351-
1352 buf_relocate(bpage, &block->page);
1353+
1354+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1355+
1356 buf_block_init_low(block);
1357 block->lock_hash_val = lock_rec_hash(space, offset);
1358
f7ab7acd 1359@@ -2952,7 +3105,7 @@
b4e1fa2c
AM
1360
1361 if (buf_page_get_state(&block->page)
1362 == BUF_BLOCK_ZIP_PAGE) {
1363- UT_LIST_REMOVE(list, buf_pool->zip_clean,
1364+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean,
1365 &block->page);
1366 ut_ad(!block->page.in_flush_list);
1367 } else {
f7ab7acd 1368@@ -2969,20 +3122,25 @@
b4e1fa2c
AM
1369 /* Insert at the front of unzip_LRU list */
1370 buf_unzip_LRU_add_block(block, FALSE);
1371
1372+ mutex_exit(&buf_pool->LRU_list_mutex);
1373+
1374 block->page.buf_fix_count = 1;
1375 buf_block_set_io_fix(block, BUF_IO_READ);
1376 rw_lock_x_lock_func(&block->lock, 0, file, line);
1377
1378 UNIV_MEM_INVALID(bpage, sizeof *bpage);
1379
1380- mutex_exit(&block->mutex);
1381+ mutex_exit(block_mutex);
1382 mutex_exit(&buf_pool->zip_mutex);
1383+
1384+ buf_pool_mutex_enter(buf_pool);
1385 buf_pool->n_pend_unzip++;
1386+ buf_pool_mutex_exit(buf_pool);
1387
adf0fb13 1388 bpage->state = BUF_BLOCK_ZIP_FREE;
b4e1fa2c
AM
1389- buf_buddy_free(buf_pool, bpage, sizeof *bpage);
1390+ buf_buddy_free(buf_pool, bpage, sizeof *bpage, FALSE);
1391
1392- buf_pool_mutex_exit(buf_pool);
1393+ //buf_pool_mutex_exit(buf_pool);
1394
1395 /* Decompress the page and apply buffered operations
1396 while not holding buf_pool->mutex or block->mutex. */
f7ab7acd 1397@@ -2995,12 +3153,15 @@
b4e1fa2c
AM
1398 }
1399
1400 /* Unfix and unlatch the block. */
1401- buf_pool_mutex_enter(buf_pool);
1402- mutex_enter(&block->mutex);
1403+ //buf_pool_mutex_enter(buf_pool);
1404+ block_mutex = &block->mutex;
1405+ mutex_enter(block_mutex);
1406 block->page.buf_fix_count--;
1407 buf_block_set_io_fix(block, BUF_IO_NONE);
1408- mutex_exit(&block->mutex);
1409+
1410+ buf_pool_mutex_enter(buf_pool);
1411 buf_pool->n_pend_unzip--;
1412+ buf_pool_mutex_exit(buf_pool);
1413 rw_lock_x_unlock(&block->lock);
1414
1415 break;
f7ab7acd 1416@@ -3016,7 +3177,7 @@
b4e1fa2c
AM
1417
1418 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1419
1420- mutex_enter(&block->mutex);
1421+ //mutex_enter(&block->mutex);
1422 #if UNIV_WORD_SIZE == 4
1423 /* On 32-bit systems, there is no padding in buf_page_t. On
1424 other systems, Valgrind could complain about uninitialized pad
f7ab7acd 1425@@ -3029,8 +3190,8 @@
b4e1fa2c
AM
1426 /* Try to evict the block from the buffer pool, to use the
1427 insert buffer (change buffer) as much as possible. */
1428
df1b5770 1429- if (buf_LRU_free_block(&block->page, TRUE) == BUF_LRU_FREED) {
11822e22 1430- mutex_exit(&block->mutex);
df1b5770 1431+ if (buf_LRU_free_block(&block->page, TRUE, FALSE) == BUF_LRU_FREED) {
11822e22 1432+ mutex_exit(block_mutex);
b4e1fa2c 1433 if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
df1b5770 1434 /* Set the watch, as it would have
11822e22 1435 been set if the page were not in the
f7ab7acd 1436@@ -3039,6 +3200,9 @@
11822e22
AM
1437 space, offset, fold);
1438
1439 if (UNIV_LIKELY_NULL(block)) {
1440+ block_mutex = buf_page_get_mutex((buf_page_t*)block);
1441+ ut_a(block_mutex);
1442+ ut_ad(mutex_own(block_mutex));
1443
1444 /* The page entered the buffer
1445 pool for some reason. Try to
f7ab7acd 1446@@ -3046,7 +3210,7 @@
11822e22
AM
1447 goto got_block;
1448 }
1449 }
1450- buf_pool_mutex_exit(buf_pool);
1451+ //buf_pool_mutex_exit(buf_pool);
1452 fprintf(stderr,
1453 "innodb_change_buffering_debug evict %u %u\n",
1454 (unsigned) space, (unsigned) offset);
f7ab7acd 1455@@ -3065,13 +3229,14 @@
b4e1fa2c
AM
1456
1457 buf_block_buf_fix_inc(block, file, line);
1458
1459- mutex_exit(&block->mutex);
1460+ //mutex_exit(&block->mutex);
1461
1462 /* Check if this is the first access to the page */
1463
1464 access_time = buf_page_is_accessed(&block->page);
1465
1466- buf_pool_mutex_exit(buf_pool);
1467+ //buf_pool_mutex_exit(buf_pool);
1468+ mutex_exit(block_mutex);
1469
adf0fb13
AM
1470 if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
1471 buf_page_set_accessed_make_young(&block->page, access_time);
f7ab7acd 1472@@ -3308,9 +3473,11 @@
b4e1fa2c
AM
1473 buf_pool = buf_pool_from_block(block);
1474
1475 if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
1476- buf_pool_mutex_enter(buf_pool);
1477+ //buf_pool_mutex_enter(buf_pool);
1478+ mutex_enter(&buf_pool->LRU_list_mutex);
1479 buf_LRU_make_block_young(&block->page);
1480- buf_pool_mutex_exit(buf_pool);
1481+ //buf_pool_mutex_exit(buf_pool);
1482+ mutex_exit(&buf_pool->LRU_list_mutex);
1483 } else if (!buf_page_is_accessed(&block->page)) {
1484 /* Above, we do a dirty read on purpose, to avoid
1485 mutex contention. The field buf_page_t::access_time
f7ab7acd 1486@@ -3318,9 +3485,11 @@
b4e1fa2c
AM
1487 field must be protected by mutex, however. */
1488 ulint time_ms = ut_time_ms();
1489
1490- buf_pool_mutex_enter(buf_pool);
1491+ //buf_pool_mutex_enter(buf_pool);
1492+ mutex_enter(&block->mutex);
1493 buf_page_set_accessed(&block->page, time_ms);
1494- buf_pool_mutex_exit(buf_pool);
1495+ //buf_pool_mutex_exit(buf_pool);
1496+ mutex_exit(&block->mutex);
1497 }
1498
adf0fb13 1499 ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
f7ab7acd 1500@@ -3387,18 +3556,21 @@
b4e1fa2c
AM
1501 ut_ad(mtr);
1502 ut_ad(mtr->state == MTR_ACTIVE);
1503
1504- buf_pool_mutex_enter(buf_pool);
1505+ //buf_pool_mutex_enter(buf_pool);
1506+ rw_lock_s_lock(&buf_pool->page_hash_latch);
1507 block = buf_block_hash_get(buf_pool, space_id, page_no);
1508
1509 if (!block || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
1510- buf_pool_mutex_exit(buf_pool);
1511+ //buf_pool_mutex_exit(buf_pool);
1512+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
1513 return(NULL);
1514 }
1515
1516 ut_ad(!buf_pool_watch_is_sentinel(buf_pool, &block->page));
1517
1518 mutex_enter(&block->mutex);
1519- buf_pool_mutex_exit(buf_pool);
1520+ //buf_pool_mutex_exit(buf_pool);
1521+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
1522
1523 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1524 ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
f7ab7acd 1525@@ -3487,7 +3659,10 @@
b4e1fa2c
AM
1526 buf_page_t* hash_page;
1527 buf_pool_t* buf_pool = buf_pool_get(space, offset);
1528
1529- ut_ad(buf_pool_mutex_own(buf_pool));
1530+ //ut_ad(buf_pool_mutex_own(buf_pool));
1531+#ifdef UNIV_SYNC_DEBUG
1532+ ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX));
1533+#endif
1534 ut_ad(mutex_own(&(block->mutex)));
1535 ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
1536
f7ab7acd 1537@@ -3516,11 +3691,14 @@
b4e1fa2c
AM
1538 if (UNIV_LIKELY(!hash_page)) {
1539 } else if (buf_pool_watch_is_sentinel(buf_pool, hash_page)) {
1540 /* Preserve the reference count. */
1541- ulint buf_fix_count = hash_page->buf_fix_count;
1542+ ulint buf_fix_count;
1543
1544+ mutex_enter(&buf_pool->zip_mutex);
1545+ buf_fix_count = hash_page->buf_fix_count;
1546 ut_a(buf_fix_count > 0);
1547 block->page.buf_fix_count += buf_fix_count;
1548 buf_pool_watch_remove(buf_pool, fold, hash_page);
1549+ mutex_exit(&buf_pool->zip_mutex);
1550 } else {
1551 fprintf(stderr,
1552 "InnoDB: Error: page %lu %lu already found"
f7ab7acd 1553@@ -3530,7 +3708,8 @@
b4e1fa2c
AM
1554 (const void*) hash_page, (const void*) block);
1555 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1556 mutex_exit(&block->mutex);
1557- buf_pool_mutex_exit(buf_pool);
1558+ //buf_pool_mutex_exit(buf_pool);
1559+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1560 buf_print();
1561 buf_LRU_print();
1562 buf_validate();
f7ab7acd 1563@@ -3613,7 +3792,9 @@
b4e1fa2c
AM
1564
1565 fold = buf_page_address_fold(space, offset);
1566
1567- buf_pool_mutex_enter(buf_pool);
1568+ //buf_pool_mutex_enter(buf_pool);
1569+ mutex_enter(&buf_pool->LRU_list_mutex);
1570+ rw_lock_x_lock(&buf_pool->page_hash_latch);
1571
1572 watch_page = buf_page_hash_get_low(buf_pool, space, offset, fold);
1573 if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) {
f7ab7acd 1574@@ -3622,9 +3803,15 @@
b4e1fa2c
AM
1575 err_exit:
1576 if (block) {
1577 mutex_enter(&block->mutex);
1578- buf_LRU_block_free_non_file_page(block);
1579+ mutex_exit(&buf_pool->LRU_list_mutex);
1580+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1581+ buf_LRU_block_free_non_file_page(block, FALSE);
1582 mutex_exit(&block->mutex);
1583 }
1584+ else {
1585+ mutex_exit(&buf_pool->LRU_list_mutex);
1586+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1587+ }
1588
1589 bpage = NULL;
1590 goto func_exit;
f7ab7acd 1591@@ -3647,6 +3834,8 @@
b4e1fa2c
AM
1592
1593 buf_page_init(space, offset, fold, block);
1594
1595+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1596+
1597 /* The block must be put to the LRU list, to the old blocks */
1598 buf_LRU_add_block(bpage, TRUE/* to old blocks */);
1599
f7ab7acd 1600@@ -3674,7 +3863,7 @@
b4e1fa2c
AM
1601 been added to buf_pool->LRU and
1602 buf_pool->page_hash. */
1603 mutex_exit(&block->mutex);
1604- data = buf_buddy_alloc(buf_pool, zip_size, &lru);
1605+ data = buf_buddy_alloc(buf_pool, zip_size, &lru, FALSE);
1606 mutex_enter(&block->mutex);
1607 block->page.zip.data = data;
1608
f7ab7acd 1609@@ -3687,6 +3876,7 @@
b4e1fa2c
AM
1610 buf_unzip_LRU_add_block(block, TRUE);
1611 }
1612
1613+ mutex_exit(&buf_pool->LRU_list_mutex);
1614 mutex_exit(&block->mutex);
1615 } else {
1616 /* Defer buf_buddy_alloc() until after the block has
f7ab7acd 1617@@ -3698,8 +3888,8 @@
b4e1fa2c
AM
1618 control block (bpage), in order to avoid the
1619 invocation of buf_buddy_relocate_block() on
1620 uninitialized data. */
1621- data = buf_buddy_alloc(buf_pool, zip_size, &lru);
1622- bpage = buf_buddy_alloc(buf_pool, sizeof *bpage, &lru);
1623+ data = buf_buddy_alloc(buf_pool, zip_size, &lru, TRUE);
1624+ bpage = buf_buddy_alloc(buf_pool, sizeof *bpage, &lru, TRUE);
1625
1626 /* Initialize the buf_pool pointer. */
1627 bpage->buf_pool_index = buf_pool_index(buf_pool);
f7ab7acd 1628@@ -3719,8 +3909,11 @@
b4e1fa2c
AM
1629 /* The block was added by some other thread. */
1630 watch_page = NULL;
adf0fb13 1631 bpage->state = BUF_BLOCK_ZIP_FREE;
b4e1fa2c
AM
1632- buf_buddy_free(buf_pool, bpage, sizeof *bpage);
1633- buf_buddy_free(buf_pool, data, zip_size);
1634+ buf_buddy_free(buf_pool, bpage, sizeof *bpage, TRUE);
1635+ buf_buddy_free(buf_pool, data, zip_size, TRUE);
1636+
1637+ mutex_exit(&buf_pool->LRU_list_mutex);
1638+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1639
1640 bpage = NULL;
1641 goto func_exit;
f7ab7acd 1642@@ -3764,18 +3957,24 @@
b4e1fa2c
AM
1643 HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold,
1644 bpage);
1645
1646+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1647+
1648 /* The block must be put to the LRU list, to the old blocks */
1649 buf_LRU_add_block(bpage, TRUE/* to old blocks */);
1650 buf_LRU_insert_zip_clean(bpage);
1651
1652+ mutex_exit(&buf_pool->LRU_list_mutex);
1653+
1654 buf_page_set_io_fix(bpage, BUF_IO_READ);
1655
1656 mutex_exit(&buf_pool->zip_mutex);
1657 }
1658
1659+ buf_pool_mutex_enter(buf_pool);
1660 buf_pool->n_pend_reads++;
1661-func_exit:
1662 buf_pool_mutex_exit(buf_pool);
1663+func_exit:
1664+ //buf_pool_mutex_exit(buf_pool);
1665
1666 if (mode == BUF_READ_IBUF_PAGES_ONLY) {
1667
f7ab7acd 1668@@ -3817,7 +4016,9 @@
b4e1fa2c
AM
1669
1670 fold = buf_page_address_fold(space, offset);
1671
1672- buf_pool_mutex_enter(buf_pool);
1673+ //buf_pool_mutex_enter(buf_pool);
1674+ mutex_enter(&buf_pool->LRU_list_mutex);
1675+ rw_lock_x_lock(&buf_pool->page_hash_latch);
1676
1677 block = (buf_block_t*) buf_page_hash_get_low(
1678 buf_pool, space, offset, fold);
f7ab7acd 1679@@ -3833,7 +4034,9 @@
df1b5770 1680 #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
b4e1fa2c
AM
1681
1682 /* Page can be found in buf_pool */
1683- buf_pool_mutex_exit(buf_pool);
1684+ //buf_pool_mutex_exit(buf_pool);
1685+ mutex_exit(&buf_pool->LRU_list_mutex);
1686+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1687
1688 buf_block_free(free_block);
1689
f7ab7acd 1690@@ -3855,6 +4058,7 @@
b4e1fa2c
AM
1691 mutex_enter(&block->mutex);
1692
1693 buf_page_init(space, offset, fold, block);
1694+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1695
1696 /* The block must be put to the LRU list */
1697 buf_LRU_add_block(&block->page, FALSE);
f7ab7acd 1698@@ -3881,7 +4085,7 @@
b4e1fa2c
AM
1699 the reacquisition of buf_pool->mutex. We also must
1700 defer this operation until after the block descriptor
1701 has been added to buf_pool->LRU and buf_pool->page_hash. */
1702- data = buf_buddy_alloc(buf_pool, zip_size, &lru);
1703+ data = buf_buddy_alloc(buf_pool, zip_size, &lru, FALSE);
1704 mutex_enter(&block->mutex);
1705 block->page.zip.data = data;
1706
f7ab7acd 1707@@ -3899,7 +4103,8 @@
b4e1fa2c
AM
1708
1709 buf_page_set_accessed(&block->page, time_ms);
1710
1711- buf_pool_mutex_exit(buf_pool);
1712+ //buf_pool_mutex_exit(buf_pool);
1713+ mutex_exit(&buf_pool->LRU_list_mutex);
1714
1715 mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
1716
f7ab7acd 1717@@ -3950,6 +4155,8 @@
b4e1fa2c
AM
1718 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1719 const ibool uncompressed = (buf_page_get_state(bpage)
1720 == BUF_BLOCK_FILE_PAGE);
1721+ ibool have_LRU_mutex = FALSE;
1722+ mutex_t* block_mutex;
1723
1724 ut_a(buf_page_in_file(bpage));
1725
f7ab7acd 1726@@ -4083,8 +4290,26 @@
b4e1fa2c
AM
1727 }
1728 }
1729
1730+ if (io_type == BUF_IO_WRITE
1731+ && (buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY
1732+ || buf_page_get_flush_type(bpage) == BUF_FLUSH_LRU)) {
1733+ /* to keep consistency at buf_LRU_insert_zip_clean() */
1734+ have_LRU_mutex = TRUE; /* optimistic */
1735+ }
1736+retry_mutex:
1737+ if (have_LRU_mutex)
1738+ mutex_enter(&buf_pool->LRU_list_mutex);
1739+ block_mutex = buf_page_get_mutex_enter(bpage);
1740+ ut_a(block_mutex);
1741+ if (io_type == BUF_IO_WRITE
1742+ && (buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY
1743+ || buf_page_get_flush_type(bpage) == BUF_FLUSH_LRU)
1744+ && !have_LRU_mutex) {
1745+ mutex_exit(block_mutex);
1746+ have_LRU_mutex = TRUE;
1747+ goto retry_mutex;
1748+ }
1749 buf_pool_mutex_enter(buf_pool);
1750- mutex_enter(buf_page_get_mutex(bpage));
1751
1752 #ifdef UNIV_IBUF_COUNT_DEBUG
1753 if (io_type == BUF_IO_WRITE || uncompressed) {
f7ab7acd 1754@@ -4107,6 +4332,7 @@
b4e1fa2c
AM
1755 the x-latch to this OS thread: do not let this confuse you in
1756 debugging! */
1757
1758+ ut_a(!have_LRU_mutex);
1759 ut_ad(buf_pool->n_pend_reads > 0);
1760 buf_pool->n_pend_reads--;
1761 buf_pool->stat.n_pages_read++;
f7ab7acd 1762@@ -4124,6 +4350,9 @@
b4e1fa2c
AM
1763
1764 buf_flush_write_complete(bpage);
1765
1766+ if (have_LRU_mutex)
1767+ mutex_exit(&buf_pool->LRU_list_mutex);
1768+
1769 if (uncompressed) {
1770 rw_lock_s_unlock_gen(&((buf_block_t*) bpage)->lock,
1771 BUF_IO_WRITE);
f7ab7acd 1772@@ -4146,8 +4375,8 @@
b4e1fa2c
AM
1773 }
1774 #endif /* UNIV_DEBUG */
1775
1776- mutex_exit(buf_page_get_mutex(bpage));
1777 buf_pool_mutex_exit(buf_pool);
1778+ mutex_exit(block_mutex);
1779 }
1780
1781 /*********************************************************************//**
f7ab7acd 1782@@ -4164,7 +4393,9 @@
b4e1fa2c
AM
1783
1784 ut_ad(buf_pool);
1785
1786- buf_pool_mutex_enter(buf_pool);
1787+ //buf_pool_mutex_enter(buf_pool);
1788+ mutex_enter(&buf_pool->LRU_list_mutex);
1789+ rw_lock_x_lock(&buf_pool->page_hash_latch);
1790
1791 chunk = buf_pool->chunks;
1792
f7ab7acd 1793@@ -4181,7 +4412,9 @@
b4e1fa2c
AM
1794 }
1795 }
1796
1797- buf_pool_mutex_exit(buf_pool);
1798+ //buf_pool_mutex_exit(buf_pool);
1799+ mutex_exit(&buf_pool->LRU_list_mutex);
1800+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1801
1802 return(TRUE);
1803 }
f7ab7acd 1804@@ -4229,7 +4462,8 @@
b4e1fa2c
AM
1805 freed = buf_LRU_search_and_free_block(buf_pool, 100);
1806 }
1807
1808- buf_pool_mutex_enter(buf_pool);
1809+ //buf_pool_mutex_enter(buf_pool);
1810+ mutex_enter(&buf_pool->LRU_list_mutex);
1811
1812 ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
1813 ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
f7ab7acd 1814@@ -4242,7 +4476,8 @@
b4e1fa2c
AM
1815 memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
1816 buf_refresh_io_stats(buf_pool);
1817
1818- buf_pool_mutex_exit(buf_pool);
1819+ //buf_pool_mutex_exit(buf_pool);
1820+ mutex_exit(&buf_pool->LRU_list_mutex);
1821 }
1822
1823 /*********************************************************************//**
f7ab7acd 1824@@ -4284,7 +4519,10 @@
b4e1fa2c
AM
1825
1826 ut_ad(buf_pool);
1827
1828- buf_pool_mutex_enter(buf_pool);
1829+ //buf_pool_mutex_enter(buf_pool);
1830+ mutex_enter(&buf_pool->LRU_list_mutex);
1831+ rw_lock_x_lock(&buf_pool->page_hash_latch);
1832+ /* for keep the new latch order, it cannot validate correctly... */
1833
1834 chunk = buf_pool->chunks;
1835
f7ab7acd 1836@@ -4379,7 +4617,7 @@
b4e1fa2c
AM
1837 /* Check clean compressed-only blocks. */
1838
1839 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
1840- b = UT_LIST_GET_NEXT(list, b)) {
1841+ b = UT_LIST_GET_NEXT(zip_list, b)) {
1842 ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
1843 switch (buf_page_get_io_fix(b)) {
1844 case BUF_IO_NONE:
f7ab7acd 1845@@ -4410,7 +4648,7 @@
b4e1fa2c
AM
1846
1847 buf_flush_list_mutex_enter(buf_pool);
1848 for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
1849- b = UT_LIST_GET_NEXT(list, b)) {
1850+ b = UT_LIST_GET_NEXT(flush_list, b)) {
1851 ut_ad(b->in_flush_list);
1852 ut_a(b->oldest_modification);
1853 n_flush++;
f7ab7acd 1854@@ -4469,6 +4707,8 @@
b4e1fa2c
AM
1855 }
1856
1857 ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru);
1858+ /* because of latching order with block->mutex, we cannot get needed mutexes before that */
1859+/*
1860 if (UT_LIST_GET_LEN(buf_pool->free) != n_free) {
1861 fprintf(stderr, "Free list len %lu, free blocks %lu\n",
1862 (ulong) UT_LIST_GET_LEN(buf_pool->free),
f7ab7acd 1863@@ -4479,8 +4719,11 @@
b4e1fa2c
AM
1864 ut_a(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE] == n_single_flush);
1865 ut_a(buf_pool->n_flush[BUF_FLUSH_LIST] == n_list_flush);
1866 ut_a(buf_pool->n_flush[BUF_FLUSH_LRU] == n_lru_flush);
1867+*/
1868
1869- buf_pool_mutex_exit(buf_pool);
1870+ //buf_pool_mutex_exit(buf_pool);
1871+ mutex_exit(&buf_pool->LRU_list_mutex);
1872+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
1873
1874 ut_a(buf_LRU_validate());
1875 ut_a(buf_flush_validate(buf_pool));
f7ab7acd 1876@@ -4536,7 +4779,9 @@
b4e1fa2c
AM
1877 index_ids = mem_alloc(size * sizeof *index_ids);
1878 counts = mem_alloc(sizeof(ulint) * size);
1879
1880- buf_pool_mutex_enter(buf_pool);
1881+ //buf_pool_mutex_enter(buf_pool);
1882+ mutex_enter(&buf_pool->LRU_list_mutex);
1883+ mutex_enter(&buf_pool->free_list_mutex);
1884 buf_flush_list_mutex_enter(buf_pool);
1885
1886 fprintf(stderr,
f7ab7acd 1887@@ -4605,7 +4850,9 @@
b4e1fa2c
AM
1888 }
1889 }
1890
1891- buf_pool_mutex_exit(buf_pool);
1892+ //buf_pool_mutex_exit(buf_pool);
1893+ mutex_exit(&buf_pool->LRU_list_mutex);
1894+ mutex_exit(&buf_pool->free_list_mutex);
1895
1896 for (i = 0; i < n_found; i++) {
1897 index = dict_index_get_if_in_cache(index_ids[i]);
f7ab7acd 1898@@ -4662,7 +4909,7 @@
b4e1fa2c
AM
1899 buf_chunk_t* chunk;
1900 ulint fixed_pages_number = 0;
1901
1902- buf_pool_mutex_enter(buf_pool);
1903+ //buf_pool_mutex_enter(buf_pool);
1904
1905 chunk = buf_pool->chunks;
1906
f7ab7acd 1907@@ -4696,7 +4943,7 @@
b4e1fa2c
AM
1908 /* Traverse the lists of clean and dirty compressed-only blocks. */
1909
1910 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
1911- b = UT_LIST_GET_NEXT(list, b)) {
1912+ b = UT_LIST_GET_NEXT(zip_list, b)) {
1913 ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
1914 ut_a(buf_page_get_io_fix(b) != BUF_IO_WRITE);
1915
f7ab7acd 1916@@ -4708,7 +4955,7 @@
b4e1fa2c
AM
1917
1918 buf_flush_list_mutex_enter(buf_pool);
1919 for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
1920- b = UT_LIST_GET_NEXT(list, b)) {
1921+ b = UT_LIST_GET_NEXT(flush_list, b)) {
1922 ut_ad(b->in_flush_list);
1923
1924 switch (buf_page_get_state(b)) {
f7ab7acd 1925@@ -4734,7 +4981,7 @@
b4e1fa2c
AM
1926
1927 buf_flush_list_mutex_exit(buf_pool);
1928 mutex_exit(&buf_pool->zip_mutex);
1929- buf_pool_mutex_exit(buf_pool);
1930+ //buf_pool_mutex_exit(buf_pool);
1931
1932 return(fixed_pages_number);
1933 }
f7ab7acd 1934@@ -4890,6 +5137,8 @@
d8778560
AM
1935 /* Find appropriate pool_info to store stats for this buffer pool */
1936 pool_info = &all_pool_info[pool_id];
b4e1fa2c
AM
1937
1938+ mutex_enter(&buf_pool->LRU_list_mutex);
1939+ mutex_enter(&buf_pool->free_list_mutex);
1940 buf_pool_mutex_enter(buf_pool);
1941 buf_flush_list_mutex_enter(buf_pool);
1942
f7ab7acd 1943@@ -5000,6 +5249,8 @@
d8778560 1944 pool_info->unzip_cur = buf_LRU_stat_cur.unzip;
b4e1fa2c
AM
1945
1946 buf_refresh_io_stats(buf_pool);
1947+ mutex_exit(&buf_pool->LRU_list_mutex);
1948+ mutex_exit(&buf_pool->free_list_mutex);
1949 buf_pool_mutex_exit(buf_pool);
1950 }
1951
f7ab7acd 1952@@ -5241,11 +5492,13 @@
b4e1fa2c
AM
1953 {
1954 ulint len;
1955
1956- buf_pool_mutex_enter(buf_pool);
1957+ //buf_pool_mutex_enter(buf_pool);
1958+ mutex_enter(&buf_pool->free_list_mutex);
1959
1960 len = UT_LIST_GET_LEN(buf_pool->free);
1961
1962- buf_pool_mutex_exit(buf_pool);
1963+ //buf_pool_mutex_exit(buf_pool);
1964+ mutex_exit(&buf_pool->free_list_mutex);
1965
1966 return(len);
1967 }
1968diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
1969--- a/storage/innobase/buf/buf0flu.c 2010-12-03 15:22:36.318955693 +0900
1970+++ b/storage/innobase/buf/buf0flu.c 2010-12-03 15:48:29.289024083 +0900
d8778560 1971@@ -307,7 +307,7 @@
b4e1fa2c
AM
1972
1973 ut_d(block->page.in_flush_list = TRUE);
1974 block->page.oldest_modification = lsn;
1975- UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page);
1976+ UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, &block->page);
1977
1978 #ifdef UNIV_DEBUG_VALGRIND
1979 {
d8778560 1980@@ -401,14 +401,14 @@
b4e1fa2c
AM
1981 > block->page.oldest_modification) {
1982 ut_ad(b->in_flush_list);
1983 prev_b = b;
1984- b = UT_LIST_GET_NEXT(list, b);
1985+ b = UT_LIST_GET_NEXT(flush_list, b);
1986 }
1987 }
1988
1989 if (prev_b == NULL) {
1990- UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page);
1991+ UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, &block->page);
1992 } else {
1993- UT_LIST_INSERT_AFTER(list, buf_pool->flush_list,
1994+ UT_LIST_INSERT_AFTER(flush_list, buf_pool->flush_list,
1995 prev_b, &block->page);
1996 }
1997
d8778560 1998@@ -434,7 +434,7 @@
b4e1fa2c
AM
1999 //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2000 //ut_ad(buf_pool_mutex_own(buf_pool));
2001 #endif
2002- //ut_ad(mutex_own(buf_page_get_mutex(bpage)));
2003+ ut_ad(mutex_own(buf_page_get_mutex(bpage)));
2004 //ut_ad(bpage->in_LRU_list);
2005
2006 if (UNIV_LIKELY(bpage->in_LRU_list && buf_page_in_file(bpage))) {
d8778560 2007@@ -470,14 +470,14 @@
b4e1fa2c
AM
2008 enum buf_flush flush_type)/*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
2009 {
2010 #ifdef UNIV_DEBUG
2011- buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2012- ut_ad(buf_pool_mutex_own(buf_pool));
2013+ //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2014+ //ut_ad(buf_pool_mutex_own(buf_pool));
2015 #endif
2016- ut_a(buf_page_in_file(bpage));
2017+ //ut_a(buf_page_in_file(bpage));
2018 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
2019 ut_ad(flush_type == BUF_FLUSH_LRU || BUF_FLUSH_LIST);
2020
2021- if (bpage->oldest_modification != 0
2022+ if (buf_page_in_file(bpage) && bpage->oldest_modification != 0
2023 && buf_page_get_io_fix(bpage) == BUF_IO_NONE) {
2024 ut_ad(bpage->in_flush_list);
2025
d8778560 2026@@ -508,7 +508,7 @@
b4e1fa2c
AM
2027 {
2028 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2029
2030- ut_ad(buf_pool_mutex_own(buf_pool));
2031+ //ut_ad(buf_pool_mutex_own(buf_pool));
2032 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
2033 ut_ad(bpage->in_flush_list);
2034
d8778560 2035@@ -526,11 +526,11 @@
b4e1fa2c
AM
2036 return;
2037 case BUF_BLOCK_ZIP_DIRTY:
2038 buf_page_set_state(bpage, BUF_BLOCK_ZIP_PAGE);
2039- UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
2040+ UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
2041 buf_LRU_insert_zip_clean(bpage);
2042 break;
2043 case BUF_BLOCK_FILE_PAGE:
2044- UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
2045+ UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
2046 break;
2047 }
2048
d8778560 2049@@ -574,7 +574,7 @@
b4e1fa2c
AM
2050 buf_page_t* prev_b = NULL;
2051 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2052
2053- ut_ad(buf_pool_mutex_own(buf_pool));
2054+ //ut_ad(buf_pool_mutex_own(buf_pool));
2055 /* Must reside in the same buffer pool. */
2056 ut_ad(buf_pool == buf_pool_from_bpage(dpage));
2057
d8778560 2058@@ -603,18 +603,18 @@
b4e1fa2c
AM
2059 because we assert on in_flush_list in comparison function. */
2060 ut_d(bpage->in_flush_list = FALSE);
2061
2062- prev = UT_LIST_GET_PREV(list, bpage);
2063- UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
2064+ prev = UT_LIST_GET_PREV(flush_list, bpage);
2065+ UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
2066
2067 if (prev) {
2068 ut_ad(prev->in_flush_list);
2069 UT_LIST_INSERT_AFTER(
2070- list,
2071+ flush_list,
2072 buf_pool->flush_list,
2073 prev, dpage);
2074 } else {
2075 UT_LIST_ADD_FIRST(
2076- list,
2077+ flush_list,
2078 buf_pool->flush_list,
2079 dpage);
2080 }
d8778560 2081@@ -1083,7 +1083,7 @@
b4e1fa2c
AM
2082
2083 #ifdef UNIV_DEBUG
2084 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2085- ut_ad(!buf_pool_mutex_own(buf_pool));
2086+ //ut_ad(!buf_pool_mutex_own(buf_pool));
2087 #endif
2088
2089 #ifdef UNIV_LOG_DEBUG
d8778560 2090@@ -1097,7 +1097,8 @@
b4e1fa2c
AM
2091 io_fixed and oldest_modification != 0. Thus, it cannot be
2092 relocated in the buffer pool or removed from flush_list or
2093 LRU_list. */
2094- ut_ad(!buf_pool_mutex_own(buf_pool));
2095+ //ut_ad(!buf_pool_mutex_own(buf_pool));
2096+ ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));
2097 ut_ad(!buf_flush_list_mutex_own(buf_pool));
2098 ut_ad(!mutex_own(buf_page_get_mutex(bpage)));
2099 ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_WRITE);
11822e22
AM
2100@@ -1177,7 +1178,7 @@
2101 buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
2102 buf_block_t* block) /*!< in/out: buffer control block */
2103 {
2104- ut_ad(buf_pool_mutex_own(buf_pool));
2105+ //ut_ad(buf_pool_mutex_own(buf_pool));
2106 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
2107 ut_ad(mutex_own(&block->mutex));
2108
2109@@ -1185,8 +1186,11 @@
2110 return(FALSE);
2111 }
2112
2113+ buf_pool_mutex_enter(buf_pool);
2114+
2115 if (buf_pool->n_flush[BUF_FLUSH_LRU] > 0
2116 || buf_pool->init_flush[BUF_FLUSH_LRU]) {
2117+ buf_pool_mutex_exit(buf_pool);
2118 /* There is already a flush batch of the same type running */
2119 return(FALSE);
2120 }
2121@@ -1260,12 +1264,18 @@
b4e1fa2c
AM
2122 ibool is_uncompressed;
2123
2124 ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
2125- ut_ad(buf_pool_mutex_own(buf_pool));
2126+ //ut_ad(buf_pool_mutex_own(buf_pool));
2127+#ifdef UNIV_SYNC_DEBUG
2128+ ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_SHARED));
2129+#endif
2130 ut_ad(buf_page_in_file(bpage));
2131
2132 block_mutex = buf_page_get_mutex(bpage);
2133 ut_ad(mutex_own(block_mutex));
2134
2135+ buf_pool_mutex_enter(buf_pool);
2136+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
2137+
2138 ut_ad(buf_flush_ready_for_flush(bpage, flush_type));
2139
2140 buf_page_set_io_fix(bpage, BUF_IO_WRITE);
11822e22 2141@@ -1427,14 +1437,16 @@
b4e1fa2c
AM
2142
2143 buf_pool = buf_pool_get(space, i);
2144
2145- buf_pool_mutex_enter(buf_pool);
2146+ //buf_pool_mutex_enter(buf_pool);
2147+ rw_lock_s_lock(&buf_pool->page_hash_latch);
2148
2149 /* We only want to flush pages from this buffer pool. */
2150 bpage = buf_page_hash_get(buf_pool, space, i);
2151
2152 if (!bpage) {
2153
2154- buf_pool_mutex_exit(buf_pool);
2155+ //buf_pool_mutex_exit(buf_pool);
2156+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
2157 continue;
2158 }
2159
11822e22 2160@@ -1446,11 +1458,9 @@
b4e1fa2c
AM
2161 if (flush_type != BUF_FLUSH_LRU
2162 || i == offset
2163 || buf_page_is_old(bpage)) {
2164- mutex_t* block_mutex = buf_page_get_mutex(bpage);
b4e1fa2c
AM
2165+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
2166
11822e22
AM
2167- mutex_enter(block_mutex);
2168-
b4e1fa2c
AM
2169- if (buf_flush_ready_for_flush(bpage, flush_type)
2170+ if (block_mutex && buf_flush_ready_for_flush(bpage, flush_type)
2171 && (i == offset || !bpage->buf_fix_count)) {
2172 /* We only try to flush those
2173 neighbors != offset where the buf fix
11822e22 2174@@ -1466,11 +1476,12 @@
b4e1fa2c
AM
2175 ut_ad(!buf_pool_mutex_own(buf_pool));
2176 count++;
2177 continue;
2178- } else {
2179+ } else if (block_mutex) {
2180 mutex_exit(block_mutex);
2181 }
2182 }
2183- buf_pool_mutex_exit(buf_pool);
2184+ //buf_pool_mutex_exit(buf_pool);
2185+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
2186 }
2187
2188 return(count);
11822e22 2189@@ -1503,21 +1514,25 @@
b4e1fa2c
AM
2190 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2191 #endif /* UNIV_DEBUG */
2192
2193- ut_ad(buf_pool_mutex_own(buf_pool));
2194+ //ut_ad(buf_pool_mutex_own(buf_pool));
2195+ ut_ad(flush_type != BUF_FLUSH_LRU
2196+ || mutex_own(&buf_pool->LRU_list_mutex));
2197
2198- block_mutex = buf_page_get_mutex(bpage);
2199- mutex_enter(block_mutex);
2200+ block_mutex = buf_page_get_mutex_enter(bpage);
2201
2202- ut_a(buf_page_in_file(bpage));
2203+ //ut_a(buf_page_in_file(bpage));
2204
2205- if (buf_flush_ready_for_flush(bpage, flush_type)) {
2206+ if (block_mutex && buf_flush_ready_for_flush(bpage, flush_type)) {
2207 ulint space;
2208 ulint offset;
2209 buf_pool_t* buf_pool;
2210
2211 buf_pool = buf_pool_from_bpage(bpage);
2212
2213- buf_pool_mutex_exit(buf_pool);
2214+ //buf_pool_mutex_exit(buf_pool);
2215+ if (flush_type == BUF_FLUSH_LRU) {
2216+ mutex_exit(&buf_pool->LRU_list_mutex);
2217+ }
2218
2219 /* These fields are protected by both the
2220 buffer pool mutex and block mutex. */
11822e22 2221@@ -1533,13 +1548,18 @@
b4e1fa2c
AM
2222 *count,
2223 n_to_flush);
2224
2225- buf_pool_mutex_enter(buf_pool);
2226+ //buf_pool_mutex_enter(buf_pool);
2227+ if (flush_type == BUF_FLUSH_LRU) {
2228+ mutex_enter(&buf_pool->LRU_list_mutex);
2229+ }
2230 flushed = TRUE;
2231- } else {
2232+ } else if (block_mutex) {
2233 mutex_exit(block_mutex);
2234 }
2235
2236- ut_ad(buf_pool_mutex_own(buf_pool));
2237+ //ut_ad(buf_pool_mutex_own(buf_pool));
2238+ ut_ad(flush_type != BUF_FLUSH_LRU
2239+ || mutex_own(&buf_pool->LRU_list_mutex));
2240
2241 return(flushed);
2242 }
11822e22 2243@@ -1560,7 +1580,8 @@
b4e1fa2c
AM
2244 buf_page_t* bpage;
2245 ulint count = 0;
2246
2247- ut_ad(buf_pool_mutex_own(buf_pool));
2248+ //ut_ad(buf_pool_mutex_own(buf_pool));
2249+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2250
2251 do {
2252 /* Start from the end of the list looking for a
11822e22 2253@@ -1582,7 +1603,8 @@
b4e1fa2c
AM
2254 should be flushed, we factor in this value. */
2255 buf_lru_flush_page_count += count;
2256
2257- ut_ad(buf_pool_mutex_own(buf_pool));
2258+ //ut_ad(buf_pool_mutex_own(buf_pool));
2259+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2260
2261 return(count);
2262 }
11822e22 2263@@ -1610,9 +1632,10 @@
b4e1fa2c
AM
2264 {
2265 ulint len;
2266 buf_page_t* bpage;
2267+ buf_page_t* prev_bpage = NULL;
2268 ulint count = 0;
2269
2270- ut_ad(buf_pool_mutex_own(buf_pool));
2271+ //ut_ad(buf_pool_mutex_own(buf_pool));
2272
2273 /* If we have flushed enough, leave the loop */
2274 do {
11822e22 2275@@ -1631,6 +1654,7 @@
b4e1fa2c
AM
2276
2277 if (bpage) {
2278 ut_a(bpage->oldest_modification > 0);
2279+ prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
2280 }
2281
2282 if (!bpage || bpage->oldest_modification >= lsn_limit) {
11822e22 2283@@ -1672,9 +1696,17 @@
b4e1fa2c
AM
2284 break;
2285 }
2286
2287- bpage = UT_LIST_GET_PREV(list, bpage);
2288+ bpage = UT_LIST_GET_PREV(flush_list, bpage);
2289
2290- ut_ad(!bpage || bpage->in_flush_list);
2291+ //ut_ad(!bpage || bpage->in_flush_list);
2292+ if (bpage != prev_bpage) {
2293+ /* the search might warp.. retrying */
2294+ buf_flush_list_mutex_exit(buf_pool);
2295+ break;
2296+ }
2297+ if (bpage) {
2298+ prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
2299+ }
2300
2301 buf_flush_list_mutex_exit(buf_pool);
2302
11822e22 2303@@ -1683,7 +1715,7 @@
b4e1fa2c
AM
2304
2305 } while (count < min_n && bpage != NULL && len > 0);
2306
2307- ut_ad(buf_pool_mutex_own(buf_pool));
2308+ //ut_ad(buf_pool_mutex_own(buf_pool));
2309
2310 return(count);
2311 }
11822e22 2312@@ -1722,13 +1754,15 @@
adf0fb13 2313 || sync_thread_levels_empty_except_dict());
b4e1fa2c
AM
2314 #endif /* UNIV_SYNC_DEBUG */
2315
2316- buf_pool_mutex_enter(buf_pool);
2317+ //buf_pool_mutex_enter(buf_pool);
2318
2319 /* Note: The buffer pool mutex is released and reacquired within
2320 the flush functions. */
2321 switch(flush_type) {
2322 case BUF_FLUSH_LRU:
2323+ mutex_enter(&buf_pool->LRU_list_mutex);
2324 count = buf_flush_LRU_list_batch(buf_pool, min_n);
2325+ mutex_exit(&buf_pool->LRU_list_mutex);
2326 break;
2327 case BUF_FLUSH_LIST:
2328 count = buf_flush_flush_list_batch(buf_pool, min_n, lsn_limit);
11822e22 2329@@ -1737,7 +1771,7 @@
b4e1fa2c
AM
2330 ut_error;
2331 }
2332
2333- buf_pool_mutex_exit(buf_pool);
2334+ //buf_pool_mutex_exit(buf_pool);
2335
2336 buf_flush_buffered_writes();
2337
11822e22 2338@@ -1993,7 +2027,7 @@
b4e1fa2c
AM
2339 retry:
2340 //buf_pool_mutex_enter(buf_pool);
2341 if (have_LRU_mutex)
2342- buf_pool_mutex_enter(buf_pool);
2343+ mutex_enter(&buf_pool->LRU_list_mutex);
2344
2345 n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
2346
11822e22 2347@@ -2010,15 +2044,15 @@
b4e1fa2c
AM
2348 bpage = UT_LIST_GET_LAST(buf_pool->LRU);
2349 continue;
2350 }
2351- block_mutex = buf_page_get_mutex(bpage);
2352-
2353- mutex_enter(block_mutex);
2354+ block_mutex = buf_page_get_mutex_enter(bpage);
2355
2356- if (buf_flush_ready_for_replace(bpage)) {
2357+ if (block_mutex && buf_flush_ready_for_replace(bpage)) {
2358 n_replaceable++;
2359 }
2360
2361- mutex_exit(block_mutex);
2362+ if (block_mutex) {
2363+ mutex_exit(block_mutex);
2364+ }
2365
2366 distance++;
2367
11822e22 2368@@ -2027,7 +2061,7 @@
b4e1fa2c
AM
2369
2370 //buf_pool_mutex_exit(buf_pool);
2371 if (have_LRU_mutex)
2372- buf_pool_mutex_exit(buf_pool);
2373+ mutex_exit(&buf_pool->LRU_list_mutex);
2374
2375 if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN(buf_pool)) {
2376
11822e22 2377@@ -2226,7 +2260,7 @@
b4e1fa2c
AM
2378
2379 ut_ad(buf_flush_list_mutex_own(buf_pool));
2380
2381- UT_LIST_VALIDATE(list, buf_page_t, buf_pool->flush_list,
2382+ UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
2383 ut_ad(ut_list_node_313->in_flush_list));
2384
2385 bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
11822e22 2386@@ -2266,7 +2300,7 @@
b4e1fa2c
AM
2387 rnode = rbt_next(buf_pool->flush_rbt, rnode);
2388 }
2389
2390- bpage = UT_LIST_GET_NEXT(list, bpage);
2391+ bpage = UT_LIST_GET_NEXT(flush_list, bpage);
2392
2393 ut_a(!bpage || om >= bpage->oldest_modification);
2394 }
2395diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
2396--- a/storage/innobase/buf/buf0lru.c 2010-12-03 15:22:36.321987250 +0900
2397+++ b/storage/innobase/buf/buf0lru.c 2010-12-03 15:48:29.293023197 +0900
2398@@ -143,8 +143,9 @@
2399 void
2400 buf_LRU_block_free_hashed_page(
2401 /*===========================*/
2402- buf_block_t* block); /*!< in: block, must contain a file page and
2403+ buf_block_t* block, /*!< in: block, must contain a file page and
2404 be in a state where it can be freed */
2405+ ibool have_page_hash_mutex);
2406
2407 /******************************************************************//**
2408 Determines if the unzip_LRU list should be used for evicting a victim
2409@@ -154,15 +155,20 @@
2410 ibool
2411 buf_LRU_evict_from_unzip_LRU(
2412 /*=========================*/
2413- buf_pool_t* buf_pool)
2414+ buf_pool_t* buf_pool,
2415+ ibool have_LRU_mutex)
2416 {
2417 ulint io_avg;
2418 ulint unzip_avg;
2419
2420- ut_ad(buf_pool_mutex_own(buf_pool));
2421+ //ut_ad(buf_pool_mutex_own(buf_pool));
2422
2423+ if (!have_LRU_mutex)
2424+ mutex_enter(&buf_pool->LRU_list_mutex);
2425 /* If the unzip_LRU list is empty, we can only use the LRU. */
2426 if (UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0) {
2427+ if (!have_LRU_mutex)
2428+ mutex_exit(&buf_pool->LRU_list_mutex);
2429 return(FALSE);
2430 }
2431
2432@@ -171,14 +177,20 @@
2433 decompressed pages in the buffer pool. */
2434 if (UT_LIST_GET_LEN(buf_pool->unzip_LRU)
2435 <= UT_LIST_GET_LEN(buf_pool->LRU) / 10) {
2436+ if (!have_LRU_mutex)
2437+ mutex_exit(&buf_pool->LRU_list_mutex);
2438 return(FALSE);
2439 }
2440
2441 /* If eviction hasn't started yet, we assume by default
2442 that a workload is disk bound. */
2443 if (buf_pool->freed_page_clock == 0) {
2444+ if (!have_LRU_mutex)
2445+ mutex_exit(&buf_pool->LRU_list_mutex);
2446 return(TRUE);
2447 }
2448+ if (!have_LRU_mutex)
2449+ mutex_exit(&buf_pool->LRU_list_mutex);
2450
2451 /* Calculate the average over past intervals, and add the values
2452 of the current interval. */
adf0fb13 2453@@ -246,18 +258,25 @@
b4e1fa2c
AM
2454 page_arr = ut_malloc(
2455 sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE);
2456
2457- buf_pool_mutex_enter(buf_pool);
2458+ //buf_pool_mutex_enter(buf_pool);
2459+ mutex_enter(&buf_pool->LRU_list_mutex);
adf0fb13 2460 num_entries = 0;
b4e1fa2c
AM
2461
2462 scan_again:
b4e1fa2c
AM
2463 bpage = UT_LIST_GET_LAST(buf_pool->LRU);
2464
2465 while (bpage != NULL) {
adf0fb13 2466+ /* bpage->state,space,io_fix,buf_fix_count are protected by block_mutex at XtraDB */
b4e1fa2c
AM
2467+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
2468 buf_page_t* prev_bpage;
adf0fb13 2469 ibool is_fixed;
b4e1fa2c 2470
b4e1fa2c
AM
2471 prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
2472
adf0fb13 2473+ if (UNIV_UNLIKELY(!block_mutex)) {
b4e1fa2c
AM
2474+ goto next_page;
2475+ }
2476+
2477 ut_a(buf_page_in_file(bpage));
2478
2479 if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
adf0fb13
AM
2480@@ -266,23 +285,27 @@
2481 /* Compressed pages are never hashed.
2482 Skip blocks of other tablespaces.
2483 Skip I/O-fixed blocks (to be dealt with later). */
2484+ mutex_exit(block_mutex);
2485 next_page:
2486 bpage = prev_bpage;
2487 continue;
2488 }
b4e1fa2c 2489
adf0fb13
AM
2490- mutex_enter(&((buf_block_t*) bpage)->mutex);
2491+ //mutex_enter(&((buf_block_t*) bpage)->mutex);
2492 is_fixed = bpage->buf_fix_count > 0
2493 || !((buf_block_t*) bpage)->is_hashed;
2494- mutex_exit(&((buf_block_t*) bpage)->mutex);
2495+ //mutex_exit(&((buf_block_t*) bpage)->mutex);
b4e1fa2c 2496
adf0fb13
AM
2497 if (is_fixed) {
2498+ mutex_exit(block_mutex);
2499 goto next_page;
2500 }
b4e1fa2c 2501
adf0fb13
AM
2502 /* Store the page number so that we can drop the hash
2503 index in a batch later. */
2504 page_arr[num_entries] = bpage->offset;
2505+ mutex_exit(block_mutex);
2506+
2507 ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
2508 ++num_entries;
b4e1fa2c 2509
adf0fb13
AM
2510@@ -292,14 +315,16 @@
2511
2512 /* Array full. We release the buf_pool->mutex to obey
2513 the latching order. */
2514- buf_pool_mutex_exit(buf_pool);
2515+ //buf_pool_mutex_exit(buf_pool);
2516+ mutex_exit(&buf_pool->LRU_list_mutex);
2517
2518 buf_LRU_drop_page_hash_batch(
2519 id, zip_size, page_arr, num_entries);
2520
2521 num_entries = 0;
2522
2523- buf_pool_mutex_enter(buf_pool);
2524+ //buf_pool_mutex_enter(buf_pool);
2525+ mutex_enter(&buf_pool->LRU_list_mutex);
2526
2527 /* Note that we released the buf_pool mutex above
2528 after reading the prev_bpage during processing of a
2529@@ -317,13 +342,23 @@
2530 /* If, however, bpage has been removed from LRU list
2531 to the free list then we should restart the scan.
2532 bpage->state is protected by buf_pool mutex. */
2533+
2534+ /* obtain block_mutex again to avoid race condition of bpage->state */
2535+ block_mutex = buf_page_get_mutex_enter(bpage);
2536+ if (!block_mutex) {
2537+ goto scan_again;
2538+ }
2539+
2540 if (bpage
2541 && buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
2542+ mutex_exit(block_mutex);
2543 goto scan_again;
b4e1fa2c 2544 }
adf0fb13 2545+ mutex_exit(block_mutex);
b4e1fa2c
AM
2546 }
2547
2548- buf_pool_mutex_exit(buf_pool);
2549+ //buf_pool_mutex_exit(buf_pool);
2550+ mutex_exit(&buf_pool->LRU_list_mutex);
2551
2552 /* Drop any remaining batch of search hashed pages. */
2553 buf_LRU_drop_page_hash_batch(id, zip_size, page_arr, num_entries);
adf0fb13 2554@@ -345,7 +380,9 @@
b4e1fa2c
AM
2555 ibool all_freed;
2556
2557 scan_again:
2558- buf_pool_mutex_enter(buf_pool);
2559+ //buf_pool_mutex_enter(buf_pool);
2560+ mutex_enter(&buf_pool->LRU_list_mutex);
2561+ rw_lock_x_lock(&buf_pool->page_hash_latch);
2562
2563 all_freed = TRUE;
2564
adf0fb13 2565@@ -373,8 +410,16 @@
b4e1fa2c
AM
2566
2567 all_freed = FALSE;
2568 } else {
2569- mutex_t* block_mutex = buf_page_get_mutex(bpage);
2570- mutex_enter(block_mutex);
2571+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
2572+
2573+ if (!block_mutex) {
2574+ /* It may be impossible case...
2575+ Something wrong, so will be scan_again */
2576+
2577+ all_freed = FALSE;
2578+
2579+ goto next_page_no_mutex;
2580+ }
2581
2582 if (bpage->buf_fix_count > 0) {
2583
adf0fb13 2584@@ -433,7 +478,9 @@
b4e1fa2c
AM
2585 ulint page_no;
2586 ulint zip_size;
2587
2588- buf_pool_mutex_exit(buf_pool);
2589+ //buf_pool_mutex_exit(buf_pool);
2590+ mutex_exit(&buf_pool->LRU_list_mutex);
2591+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
2592
2593 zip_size = buf_page_get_zip_size(bpage);
2594 page_no = buf_page_get_page_no(bpage);
adf0fb13 2595@@ -458,7 +505,7 @@
b4e1fa2c
AM
2596 if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
2597 != BUF_BLOCK_ZIP_FREE) {
2598 buf_LRU_block_free_hashed_page((buf_block_t*)
2599- bpage);
2600+ bpage, TRUE);
2601 } else {
2602 /* The block_mutex should have been
2603 released by buf_LRU_block_remove_hashed_page()
adf0fb13 2604@@ -490,7 +537,9 @@
b4e1fa2c
AM
2605 bpage = prev_bpage;
2606 }
2607
2608- buf_pool_mutex_exit(buf_pool);
2609+ //buf_pool_mutex_exit(buf_pool);
2610+ mutex_exit(&buf_pool->LRU_list_mutex);
2611+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
2612
2613 if (!all_freed) {
2614 os_thread_sleep(20000);
adf0fb13 2615@@ -536,7 +585,9 @@
b4e1fa2c
AM
2616 buf_page_t* b;
2617 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2618
2619- ut_ad(buf_pool_mutex_own(buf_pool));
2620+ //ut_ad(buf_pool_mutex_own(buf_pool));
2621+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
11822e22 2622+ ut_ad(mutex_own(&buf_pool->zip_mutex));
b4e1fa2c
AM
2623 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_PAGE);
2624
2625 /* Find the first successor of bpage in the LRU list
adf0fb13 2626@@ -544,17 +595,17 @@
b4e1fa2c
AM
2627 b = bpage;
2628 do {
2629 b = UT_LIST_GET_NEXT(LRU, b);
2630- } while (b && buf_page_get_state(b) != BUF_BLOCK_ZIP_PAGE);
2631+ } while (b && (buf_page_get_state(b) != BUF_BLOCK_ZIP_PAGE || !b->in_LRU_list));
2632
2633 /* Insert bpage before b, i.e., after the predecessor of b. */
2634 if (b) {
2635- b = UT_LIST_GET_PREV(list, b);
2636+ b = UT_LIST_GET_PREV(zip_list, b);
2637 }
2638
2639 if (b) {
2640- UT_LIST_INSERT_AFTER(list, buf_pool->zip_clean, b, bpage);
2641+ UT_LIST_INSERT_AFTER(zip_list, buf_pool->zip_clean, b, bpage);
2642 } else {
2643- UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, bpage);
2644+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_clean, bpage);
2645 }
2646 }
2647
adf0fb13 2648@@ -567,18 +618,19 @@
b4e1fa2c
AM
2649 buf_LRU_free_from_unzip_LRU_list(
2650 /*=============================*/
2651 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
2652- ulint n_iterations) /*!< in: how many times this has
2653+ ulint n_iterations, /*!< in: how many times this has
2654 been called repeatedly without
2655 result: a high value means that
2656 we should search farther; we will
2657 search n_iterations / 5 of the
2658 unzip_LRU list, or nothing if
2659 n_iterations >= 5 */
2660+ ibool have_LRU_mutex)
2661 {
2662 buf_block_t* block;
2663 ulint distance;
2664
2665- ut_ad(buf_pool_mutex_own(buf_pool));
2666+ //ut_ad(buf_pool_mutex_own(buf_pool));
2667
2668 /* Theoratically it should be much easier to find a victim
2669 from unzip_LRU as we can choose even a dirty block (as we'll
adf0fb13 2670@@ -588,7 +640,7 @@
b4e1fa2c
AM
2671 if we have done five iterations so far. */
2672
2673 if (UNIV_UNLIKELY(n_iterations >= 5)
2674- || !buf_LRU_evict_from_unzip_LRU(buf_pool)) {
2675+ || !buf_LRU_evict_from_unzip_LRU(buf_pool, have_LRU_mutex)) {
2676
2677 return(FALSE);
2678 }
adf0fb13 2679@@ -596,18 +648,25 @@
b4e1fa2c
AM
2680 distance = 100 + (n_iterations
2681 * UT_LIST_GET_LEN(buf_pool->unzip_LRU)) / 5;
2682
2683+restart:
2684 for (block = UT_LIST_GET_LAST(buf_pool->unzip_LRU);
2685 UNIV_LIKELY(block != NULL) && UNIV_LIKELY(distance > 0);
2686 block = UT_LIST_GET_PREV(unzip_LRU, block), distance--) {
2687
2688 enum buf_lru_free_block_status freed;
2689
2690+ mutex_enter(&block->mutex);
2691+ if (!block->in_unzip_LRU_list || !block->page.in_LRU_list
2692+ || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
2693+ mutex_exit(&block->mutex);
2694+ goto restart;
2695+ }
2696+
2697 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
2698 ut_ad(block->in_unzip_LRU_list);
2699 ut_ad(block->page.in_LRU_list);
2700
2701- mutex_enter(&block->mutex);
df1b5770
AM
2702- freed = buf_LRU_free_block(&block->page, FALSE);
2703+ freed = buf_LRU_free_block(&block->page, FALSE, have_LRU_mutex);
b4e1fa2c
AM
2704 mutex_exit(&block->mutex);
2705
2706 switch (freed) {
adf0fb13 2707@@ -641,21 +700,23 @@
b4e1fa2c
AM
2708 buf_LRU_free_from_common_LRU_list(
2709 /*==============================*/
2710 buf_pool_t* buf_pool,
2711- ulint n_iterations)
2712+ ulint n_iterations,
2713 /*!< in: how many times this has been called
2714 repeatedly without result: a high value means
2715 that we should search farther; if
2716 n_iterations < 10, then we search
2717 n_iterations / 10 * buf_pool->curr_size
2718 pages from the end of the LRU list */
2719+ ibool have_LRU_mutex)
2720 {
2721 buf_page_t* bpage;
2722 ulint distance;
2723
2724- ut_ad(buf_pool_mutex_own(buf_pool));
2725+ //ut_ad(buf_pool_mutex_own(buf_pool));
2726
2727 distance = 100 + (n_iterations * buf_pool->curr_size) / 10;
2728
2729+restart:
2730 for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
2731 UNIV_LIKELY(bpage != NULL) && UNIV_LIKELY(distance > 0);
2732 bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
adf0fb13 2733@@ -663,14 +724,23 @@
b4e1fa2c
AM
2734 enum buf_lru_free_block_status freed;
2735 unsigned accessed;
2736 mutex_t* block_mutex
2737- = buf_page_get_mutex(bpage);
2738+ = buf_page_get_mutex_enter(bpage);
2739+
2740+ if (!block_mutex) {
2741+ goto restart;
2742+ }
2743+
2744+ if (!bpage->in_LRU_list
2745+ || !buf_page_in_file(bpage)) {
2746+ mutex_exit(block_mutex);
2747+ goto restart;
2748+ }
2749
2750 ut_ad(buf_page_in_file(bpage));
2751 ut_ad(bpage->in_LRU_list);
2752
2753- mutex_enter(block_mutex);
2754 accessed = buf_page_is_accessed(bpage);
df1b5770
AM
2755- freed = buf_LRU_free_block(bpage, TRUE);
2756+ freed = buf_LRU_free_block(bpage, TRUE, have_LRU_mutex);
b4e1fa2c
AM
2757 mutex_exit(block_mutex);
2758
2759 switch (freed) {
adf0fb13 2760@@ -722,16 +792,23 @@
b4e1fa2c
AM
2761 n_iterations / 5 of the unzip_LRU list. */
2762 {
2763 ibool freed = FALSE;
2764+ ibool have_LRU_mutex = FALSE;
2765
2766- buf_pool_mutex_enter(buf_pool);
2767+ if (UT_LIST_GET_LEN(buf_pool->unzip_LRU))
2768+ have_LRU_mutex = TRUE;
2769+
2770+ //buf_pool_mutex_enter(buf_pool);
2771+ if (have_LRU_mutex)
2772+ mutex_enter(&buf_pool->LRU_list_mutex);
2773
2774- freed = buf_LRU_free_from_unzip_LRU_list(buf_pool, n_iterations);
2775+ freed = buf_LRU_free_from_unzip_LRU_list(buf_pool, n_iterations, have_LRU_mutex);
2776
2777 if (!freed) {
2778 freed = buf_LRU_free_from_common_LRU_list(
2779- buf_pool, n_iterations);
2780+ buf_pool, n_iterations, have_LRU_mutex);
2781 }
2782
2783+ buf_pool_mutex_enter(buf_pool);
2784 if (!freed) {
2785 buf_pool->LRU_flush_ended = 0;
2786 } else if (buf_pool->LRU_flush_ended > 0) {
adf0fb13 2787@@ -739,6 +816,8 @@
b4e1fa2c
AM
2788 }
2789
2790 buf_pool_mutex_exit(buf_pool);
2791+ if (have_LRU_mutex)
2792+ mutex_exit(&buf_pool->LRU_list_mutex);
2793
2794 return(freed);
2795 }
adf0fb13 2796@@ -799,7 +878,9 @@
b4e1fa2c
AM
2797
2798 buf_pool = buf_pool_from_array(i);
2799
2800- buf_pool_mutex_enter(buf_pool);
2801+ //buf_pool_mutex_enter(buf_pool);
2802+ mutex_enter(&buf_pool->LRU_list_mutex);
2803+ mutex_enter(&buf_pool->free_list_mutex);
2804
2805 if (!recv_recovery_on
2806 && UT_LIST_GET_LEN(buf_pool->free)
adf0fb13 2807@@ -809,7 +890,9 @@
b4e1fa2c
AM
2808 ret = TRUE;
2809 }
2810
2811- buf_pool_mutex_exit(buf_pool);
2812+ //buf_pool_mutex_exit(buf_pool);
2813+ mutex_exit(&buf_pool->LRU_list_mutex);
2814+ mutex_exit(&buf_pool->free_list_mutex);
2815 }
2816
2817 return(ret);
adf0fb13 2818@@ -827,9 +910,10 @@
b4e1fa2c
AM
2819 {
2820 buf_block_t* block;
2821
2822- ut_ad(buf_pool_mutex_own(buf_pool));
2823+ //ut_ad(buf_pool_mutex_own(buf_pool));
2824
2825- block = (buf_block_t*) UT_LIST_GET_FIRST(buf_pool->free);
2826+ mutex_enter(&buf_pool->free_list_mutex);
2827+ block = (buf_block_t*) UT_LIST_GET_LAST(buf_pool->free);
2828
2829 if (block) {
2830
adf0fb13 2831@@ -838,7 +922,9 @@
b4e1fa2c
AM
2832 ut_ad(!block->page.in_flush_list);
2833 ut_ad(!block->page.in_LRU_list);
2834 ut_a(!buf_page_in_file(&block->page));
2835- UT_LIST_REMOVE(list, buf_pool->free, (&block->page));
2836+ UT_LIST_REMOVE(free, buf_pool->free, (&block->page));
2837+
2838+ mutex_exit(&buf_pool->free_list_mutex);
2839
2840 mutex_enter(&block->mutex);
2841
adf0fb13 2842@@ -848,6 +934,8 @@
b4e1fa2c
AM
2843 ut_ad(buf_pool_from_block(block) == buf_pool);
2844
2845 mutex_exit(&block->mutex);
2846+ } else {
2847+ mutex_exit(&buf_pool->free_list_mutex);
2848 }
2849
2850 return(block);
adf0fb13 2851@@ -870,7 +958,7 @@
b4e1fa2c
AM
2852 ibool mon_value_was = FALSE;
2853 ibool started_monitor = FALSE;
2854 loop:
2855- buf_pool_mutex_enter(buf_pool);
2856+ //buf_pool_mutex_enter(buf_pool);
2857
2858 if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
2859 + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->curr_size / 20) {
adf0fb13 2860@@ -938,7 +1026,7 @@
b4e1fa2c 2861
df1b5770
AM
2862 /* If there is a block in the free list, take it */
2863 block = buf_LRU_get_free_only(buf_pool);
b4e1fa2c
AM
2864- buf_pool_mutex_exit(buf_pool);
2865+ //buf_pool_mutex_exit(buf_pool);
2866
df1b5770
AM
2867 if (block) {
2868 ut_ad(buf_pool_from_block(block) == buf_pool);
adf0fb13 2869@@ -1038,7 +1126,8 @@
b4e1fa2c
AM
2870 ulint new_len;
2871
2872 ut_a(buf_pool->LRU_old);
2873- ut_ad(buf_pool_mutex_own(buf_pool));
2874+ //ut_ad(buf_pool_mutex_own(buf_pool));
2875+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2876 ut_ad(buf_pool->LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
2877 ut_ad(buf_pool->LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
2878 #if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
adf0fb13 2879@@ -1104,7 +1193,8 @@
b4e1fa2c
AM
2880 {
2881 buf_page_t* bpage;
2882
2883- ut_ad(buf_pool_mutex_own(buf_pool));
2884+ //ut_ad(buf_pool_mutex_own(buf_pool));
2885+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2886 ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN);
2887
2888 /* We first initialize all blocks in the LRU list as old and then use
adf0fb13 2889@@ -1139,13 +1229,14 @@
b4e1fa2c
AM
2890 ut_ad(buf_pool);
2891 ut_ad(bpage);
2892 ut_ad(buf_page_in_file(bpage));
2893- ut_ad(buf_pool_mutex_own(buf_pool));
2894+ //ut_ad(buf_pool_mutex_own(buf_pool));
2895+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2896
2897 if (buf_page_belongs_to_unzip_LRU(bpage)) {
2898 buf_block_t* block = (buf_block_t*) bpage;
2899
2900 ut_ad(block->in_unzip_LRU_list);
2901- ut_d(block->in_unzip_LRU_list = FALSE);
2902+ block->in_unzip_LRU_list = FALSE;
2903
2904 UT_LIST_REMOVE(unzip_LRU, buf_pool->unzip_LRU, block);
2905 }
adf0fb13 2906@@ -1163,7 +1254,8 @@
b4e1fa2c
AM
2907
2908 ut_ad(buf_pool);
2909 ut_ad(bpage);
2910- ut_ad(buf_pool_mutex_own(buf_pool));
2911+ //ut_ad(buf_pool_mutex_own(buf_pool));
2912+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2913
2914 ut_a(buf_page_in_file(bpage));
2915
adf0fb13 2916@@ -1240,12 +1332,13 @@
b4e1fa2c
AM
2917
2918 ut_ad(buf_pool);
2919 ut_ad(block);
2920- ut_ad(buf_pool_mutex_own(buf_pool));
2921+ //ut_ad(buf_pool_mutex_own(buf_pool));
2922+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2923
2924 ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
2925
2926 ut_ad(!block->in_unzip_LRU_list);
2927- ut_d(block->in_unzip_LRU_list = TRUE);
2928+ block->in_unzip_LRU_list = TRUE;
2929
2930 if (old) {
2931 UT_LIST_ADD_LAST(unzip_LRU, buf_pool->unzip_LRU, block);
adf0fb13 2932@@ -1266,7 +1359,8 @@
b4e1fa2c
AM
2933
2934 ut_ad(buf_pool);
2935 ut_ad(bpage);
2936- ut_ad(buf_pool_mutex_own(buf_pool));
2937+ //ut_ad(buf_pool_mutex_own(buf_pool));
2938+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2939
2940 ut_a(buf_page_in_file(bpage));
2941
adf0fb13 2942@@ -1317,7 +1411,8 @@
b4e1fa2c
AM
2943
2944 ut_ad(buf_pool);
2945 ut_ad(bpage);
2946- ut_ad(buf_pool_mutex_own(buf_pool));
2947+ //ut_ad(buf_pool_mutex_own(buf_pool));
2948+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2949
2950 ut_a(buf_page_in_file(bpage));
2951 ut_ad(!bpage->in_LRU_list);
adf0fb13 2952@@ -1396,7 +1491,8 @@
b4e1fa2c
AM
2953 {
2954 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2955
2956- ut_ad(buf_pool_mutex_own(buf_pool));
2957+ //ut_ad(buf_pool_mutex_own(buf_pool));
2958+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2959
2960 if (bpage->old) {
2961 buf_pool->stat.n_pages_made_young++;
adf0fb13 2962@@ -1436,17 +1532,18 @@
df1b5770
AM
2963 buf_LRU_free_block(
2964 /*===============*/
b4e1fa2c 2965 buf_page_t* bpage, /*!< in: block to be freed */
df1b5770
AM
2966- ibool zip) /*!< in: TRUE if should remove also the
2967+ ibool zip, /*!< in: TRUE if should remove also the
b4e1fa2c 2968 compressed page of an uncompressed page */
b4e1fa2c
AM
2969+ ibool have_LRU_mutex)
2970 {
2971 buf_page_t* b = NULL;
2972 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2973 mutex_t* block_mutex = buf_page_get_mutex(bpage);
2974
2975- ut_ad(buf_pool_mutex_own(buf_pool));
2976+ //ut_ad(buf_pool_mutex_own(buf_pool));
2977 ut_ad(mutex_own(block_mutex));
2978 ut_ad(buf_page_in_file(bpage));
2979- ut_ad(bpage->in_LRU_list);
2980+ //ut_ad(bpage->in_LRU_list);
2981 ut_ad(!bpage->in_flush_list == !bpage->oldest_modification);
2982 #if UNIV_WORD_SIZE == 4
2983 /* On 32-bit systems, there is no padding in buf_page_t. On
adf0fb13 2984@@ -1455,7 +1552,7 @@
b4e1fa2c
AM
2985 UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
2986 #endif
2987
2988- if (!buf_page_can_relocate(bpage)) {
2989+ if (!bpage->in_LRU_list || !block_mutex || !buf_page_can_relocate(bpage)) {
2990
2991 /* Do not free buffer-fixed or I/O-fixed blocks. */
2992 return(BUF_LRU_NOT_FREED);
adf0fb13 2993@@ -1487,15 +1584,15 @@
b4e1fa2c
AM
2994 If it cannot be allocated (without freeing a block
2995 from the LRU list), refuse to free bpage. */
2996 alloc:
2997- buf_pool_mutex_exit_forbid(buf_pool);
2998- b = buf_buddy_alloc(buf_pool, sizeof *b, NULL);
2999- buf_pool_mutex_exit_allow(buf_pool);
3000+ //buf_pool_mutex_exit_forbid(buf_pool);
3001+ b = buf_buddy_alloc(buf_pool, sizeof *b, NULL, FALSE);
3002+ //buf_pool_mutex_exit_allow(buf_pool);
3003
3004 if (UNIV_UNLIKELY(!b)) {
3005 return(BUF_LRU_CANNOT_RELOCATE);
3006 }
3007
3008- memcpy(b, bpage, sizeof *b);
3009+ //memcpy(b, bpage, sizeof *b);
3010 }
3011
3012 #ifdef UNIV_DEBUG
adf0fb13 3013@@ -1506,6 +1603,39 @@
b4e1fa2c
AM
3014 }
3015 #endif /* UNIV_DEBUG */
3016
3017+ /* not to break latch order, must re-enter block_mutex */
3018+ mutex_exit(block_mutex);
3019+
3020+ if (!have_LRU_mutex)
3021+ mutex_enter(&buf_pool->LRU_list_mutex); /* optimistic */
3022+ rw_lock_x_lock(&buf_pool->page_hash_latch);
3023+ mutex_enter(block_mutex);
3024+
3025+ /* recheck states of block */
3026+ if (!bpage->in_LRU_list || block_mutex != buf_page_get_mutex(bpage)
3027+ || !buf_page_can_relocate(bpage)) {
3028+not_freed:
3029+ if (b) {
3030+ buf_buddy_free(buf_pool, b, sizeof *b, TRUE);
3031+ }
3032+ if (!have_LRU_mutex)
3033+ mutex_exit(&buf_pool->LRU_list_mutex);
3034+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
3035+ return(BUF_LRU_NOT_FREED);
3036+ } else if (zip || !bpage->zip.data) {
3037+ if (bpage->oldest_modification)
3038+ goto not_freed;
3039+ } else if (bpage->oldest_modification) {
3040+ if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
3041+ ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY);
3042+ goto not_freed;
3043+ }
3044+ }
3045+
3046+ if (b) {
3047+ memcpy(b, bpage, sizeof *b);
3048+ }
3049+
3050 if (buf_LRU_block_remove_hashed_page(bpage, zip)
3051 != BUF_BLOCK_ZIP_FREE) {
3052 ut_a(bpage->buf_fix_count == 0);
adf0fb13 3053@@ -1522,6 +1652,10 @@
b4e1fa2c
AM
3054
3055 ut_a(!hash_b);
3056
3057+ while (prev_b && !prev_b->in_LRU_list) {
3058+ prev_b = UT_LIST_GET_PREV(LRU, prev_b);
3059+ }
3060+
3061 b->state = b->oldest_modification
3062 ? BUF_BLOCK_ZIP_DIRTY
3063 : BUF_BLOCK_ZIP_PAGE;
adf0fb13
AM
3064@@ -1597,6 +1731,7 @@
3065 buf_LRU_add_block_low(b, buf_page_is_old(b));
3066 }
3067
3068+ mutex_enter(&buf_pool->zip_mutex);
3069 if (b->state == BUF_BLOCK_ZIP_PAGE) {
3070 buf_LRU_insert_zip_clean(b);
3071 } else {
3072@@ -1612,9 +1747,12 @@
3073 buf_pool->mutex and block_mutex. */
3074 b->buf_fix_count++;
df1b5770 3075 b->io_fix = BUF_IO_READ;
adf0fb13 3076+ mutex_exit(&buf_pool->zip_mutex);
b4e1fa2c
AM
3077 }
3078
3079- buf_pool_mutex_exit(buf_pool);
3080+ //buf_pool_mutex_exit(buf_pool);
3081+ mutex_exit(&buf_pool->LRU_list_mutex);
3082+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
3083 mutex_exit(block_mutex);
3084
3085 /* Remove possible adaptive hash index on the page.
adf0fb13 3086@@ -1646,7 +1784,9 @@
b4e1fa2c
AM
3087 : BUF_NO_CHECKSUM_MAGIC);
3088 }
3089
3090- buf_pool_mutex_enter(buf_pool);
3091+ //buf_pool_mutex_enter(buf_pool);
3092+ if (have_LRU_mutex)
3093+ mutex_enter(&buf_pool->LRU_list_mutex);
3094 mutex_enter(block_mutex);
3095
3096 if (b) {
adf0fb13 3097@@ -1656,13 +1796,17 @@
b4e1fa2c
AM
3098 mutex_exit(&buf_pool->zip_mutex);
3099 }
3100
3101- buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
3102+ buf_LRU_block_free_hashed_page((buf_block_t*) bpage, FALSE);
3103 } else {
3104 /* The block_mutex should have been released by
3105 buf_LRU_block_remove_hashed_page() when it returns
3106 BUF_BLOCK_ZIP_FREE. */
3107 ut_ad(block_mutex == &buf_pool->zip_mutex);
3108 mutex_enter(block_mutex);
3109+
3110+ if (!have_LRU_mutex)
3111+ mutex_exit(&buf_pool->LRU_list_mutex);
3112+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
3113 }
3114
3115 return(BUF_LRU_FREED);
adf0fb13 3116@@ -1674,13 +1818,14 @@
b4e1fa2c
AM
3117 void
3118 buf_LRU_block_free_non_file_page(
3119 /*=============================*/
3120- buf_block_t* block) /*!< in: block, must not contain a file page */
3121+ buf_block_t* block, /*!< in: block, must not contain a file page */
3122+ ibool have_page_hash_mutex)
3123 {
3124 void* data;
3125 buf_pool_t* buf_pool = buf_pool_from_block(block);
3126
3127 ut_ad(block);
3128- ut_ad(buf_pool_mutex_own(buf_pool));
3129+ //ut_ad(buf_pool_mutex_own(buf_pool));
3130 ut_ad(mutex_own(&block->mutex));
3131
3132 switch (buf_block_get_state(block)) {
adf0fb13 3133@@ -1714,18 +1859,21 @@
b4e1fa2c
AM
3134 if (data) {
3135 block->page.zip.data = NULL;
3136 mutex_exit(&block->mutex);
3137- buf_pool_mutex_exit_forbid(buf_pool);
3138+ //buf_pool_mutex_exit_forbid(buf_pool);
3139
3140 buf_buddy_free(
3141- buf_pool, data, page_zip_get_size(&block->page.zip));
3142+ buf_pool, data, page_zip_get_size(&block->page.zip),
3143+ have_page_hash_mutex);
3144
3145- buf_pool_mutex_exit_allow(buf_pool);
3146+ //buf_pool_mutex_exit_allow(buf_pool);
3147 mutex_enter(&block->mutex);
3148 page_zip_set_size(&block->page.zip, 0);
3149 }
3150
3151- UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->page));
3152+ mutex_enter(&buf_pool->free_list_mutex);
3153+ UT_LIST_ADD_FIRST(free, buf_pool->free, (&block->page));
3154 ut_d(block->page.in_free_list = TRUE);
3155+ mutex_exit(&buf_pool->free_list_mutex);
3156
3157 UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
3158 }
adf0fb13 3159@@ -1755,7 +1903,11 @@
b4e1fa2c
AM
3160 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3161
3162 ut_ad(bpage);
3163- ut_ad(buf_pool_mutex_own(buf_pool));
3164+ //ut_ad(buf_pool_mutex_own(buf_pool));
3165+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
3166+#ifdef UNIV_SYNC_DEBUG
3167+ ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX));
3168+#endif
3169 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
3170
3171 ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
adf0fb13 3172@@ -1863,7 +2015,9 @@
b4e1fa2c
AM
3173
3174 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
3175 mutex_exit(buf_page_get_mutex(bpage));
3176- buf_pool_mutex_exit(buf_pool);
3177+ //buf_pool_mutex_exit(buf_pool);
3178+ mutex_exit(&buf_pool->LRU_list_mutex);
3179+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
3180 buf_print();
3181 buf_LRU_print();
3182 buf_validate();
adf0fb13 3183@@ -1884,18 +2038,18 @@
b4e1fa2c
AM
3184 ut_a(bpage->zip.data);
3185 ut_a(buf_page_get_zip_size(bpage));
3186
3187- UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
3188+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, bpage);
3189
3190 mutex_exit(&buf_pool->zip_mutex);
3191- buf_pool_mutex_exit_forbid(buf_pool);
3192+ //buf_pool_mutex_exit_forbid(buf_pool);
3193
3194 buf_buddy_free(
3195 buf_pool, bpage->zip.data,
3196- page_zip_get_size(&bpage->zip));
3197+ page_zip_get_size(&bpage->zip), TRUE);
3198
adf0fb13 3199 bpage->state = BUF_BLOCK_ZIP_FREE;
b4e1fa2c
AM
3200- buf_buddy_free(buf_pool, bpage, sizeof(*bpage));
3201- buf_pool_mutex_exit_allow(buf_pool);
3202+ buf_buddy_free(buf_pool, bpage, sizeof(*bpage), TRUE);
3203+ //buf_pool_mutex_exit_allow(buf_pool);
3204
3205 UNIV_MEM_UNDESC(bpage);
3206 return(BUF_BLOCK_ZIP_FREE);
adf0fb13 3207@@ -1918,13 +2072,13 @@
b4e1fa2c
AM
3208 ut_ad(!bpage->in_flush_list);
3209 ut_ad(!bpage->in_LRU_list);
3210 mutex_exit(&((buf_block_t*) bpage)->mutex);
3211- buf_pool_mutex_exit_forbid(buf_pool);
3212+ //buf_pool_mutex_exit_forbid(buf_pool);
3213
3214 buf_buddy_free(
3215 buf_pool, data,
3216- page_zip_get_size(&bpage->zip));
3217+ page_zip_get_size(&bpage->zip), TRUE);
3218
3219- buf_pool_mutex_exit_allow(buf_pool);
3220+ //buf_pool_mutex_exit_allow(buf_pool);
3221 mutex_enter(&((buf_block_t*) bpage)->mutex);
3222 page_zip_set_size(&bpage->zip, 0);
3223 }
adf0fb13 3224@@ -1950,18 +2104,19 @@
b4e1fa2c
AM
3225 void
3226 buf_LRU_block_free_hashed_page(
3227 /*===========================*/
3228- buf_block_t* block) /*!< in: block, must contain a file page and
3229+ buf_block_t* block, /*!< in: block, must contain a file page and
3230 be in a state where it can be freed */
3231+ ibool have_page_hash_mutex)
3232 {
3233 #ifdef UNIV_DEBUG
3234- buf_pool_t* buf_pool = buf_pool_from_block(block);
3235- ut_ad(buf_pool_mutex_own(buf_pool));
3236+ //buf_pool_t* buf_pool = buf_pool_from_block(block);
3237+ //ut_ad(buf_pool_mutex_own(buf_pool));
3238 #endif
3239 ut_ad(mutex_own(&block->mutex));
3240
3241 buf_block_set_state(block, BUF_BLOCK_MEMORY);
3242
3243- buf_LRU_block_free_non_file_page(block);
3244+ buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
3245 }
3246
3247 /**********************************************************************//**
adf0fb13 3248@@ -1988,7 +2143,8 @@
b4e1fa2c
AM
3249 }
3250
3251 if (adjust) {
3252- buf_pool_mutex_enter(buf_pool);
3253+ //buf_pool_mutex_enter(buf_pool);
3254+ mutex_enter(&buf_pool->LRU_list_mutex);
3255
3256 if (ratio != buf_pool->LRU_old_ratio) {
3257 buf_pool->LRU_old_ratio = ratio;
adf0fb13 3258@@ -2000,7 +2156,8 @@
b4e1fa2c
AM
3259 }
3260 }
3261
3262- buf_pool_mutex_exit(buf_pool);
3263+ //buf_pool_mutex_exit(buf_pool);
3264+ mutex_exit(&buf_pool->LRU_list_mutex);
3265 } else {
3266 buf_pool->LRU_old_ratio = ratio;
3267 }
adf0fb13 3268@@ -2105,7 +2262,8 @@
b4e1fa2c
AM
3269 ulint new_len;
3270
3271 ut_ad(buf_pool);
3272- buf_pool_mutex_enter(buf_pool);
3273+ //buf_pool_mutex_enter(buf_pool);
3274+ mutex_enter(&buf_pool->LRU_list_mutex);
3275
3276 if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
3277
adf0fb13 3278@@ -2166,16 +2324,22 @@
b4e1fa2c
AM
3279
3280 ut_a(buf_pool->LRU_old_len == old_len);
3281
3282- UT_LIST_VALIDATE(list, buf_page_t, buf_pool->free,
3283+ mutex_exit(&buf_pool->LRU_list_mutex);
3284+ mutex_enter(&buf_pool->free_list_mutex);
3285+
3286+ UT_LIST_VALIDATE(free, buf_page_t, buf_pool->free,
3287 ut_ad(ut_list_node_313->in_free_list));
3288
3289 for (bpage = UT_LIST_GET_FIRST(buf_pool->free);
3290 bpage != NULL;
3291- bpage = UT_LIST_GET_NEXT(list, bpage)) {
3292+ bpage = UT_LIST_GET_NEXT(free, bpage)) {
3293
3294 ut_a(buf_page_get_state(bpage) == BUF_BLOCK_NOT_USED);
3295 }
3296
3297+ mutex_exit(&buf_pool->free_list_mutex);
3298+ mutex_enter(&buf_pool->LRU_list_mutex);
3299+
3300 UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU,
3301 ut_ad(ut_list_node_313->in_unzip_LRU_list
3302 && ut_list_node_313->page.in_LRU_list));
adf0fb13 3303@@ -2189,7 +2353,8 @@
b4e1fa2c
AM
3304 ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
3305 }
3306
3307- buf_pool_mutex_exit(buf_pool);
3308+ //buf_pool_mutex_exit(buf_pool);
3309+ mutex_exit(&buf_pool->LRU_list_mutex);
3310 }
3311
3312 /**********************************************************************//**
adf0fb13 3313@@ -2225,7 +2390,8 @@
b4e1fa2c
AM
3314 const buf_page_t* bpage;
3315
3316 ut_ad(buf_pool);
3317- buf_pool_mutex_enter(buf_pool);
3318+ //buf_pool_mutex_enter(buf_pool);
3319+ mutex_enter(&buf_pool->LRU_list_mutex);
3320
3321 bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
3322
adf0fb13 3323@@ -2282,7 +2448,8 @@
b4e1fa2c
AM
3324 bpage = UT_LIST_GET_NEXT(LRU, bpage);
3325 }
3326
3327- buf_pool_mutex_exit(buf_pool);
3328+ //buf_pool_mutex_exit(buf_pool);
3329+ mutex_exit(&buf_pool->LRU_list_mutex);
3330 }
3331
3332 /**********************************************************************//**
3333diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
3334--- a/storage/innobase/buf/buf0rea.c 2010-12-03 15:22:36.323977308 +0900
3335+++ b/storage/innobase/buf/buf0rea.c 2010-12-03 15:48:29.296024468 +0900
3336@@ -311,6 +311,7 @@
3337
3338 return(0);
3339 }
3340+ buf_pool_mutex_exit(buf_pool);
3341
3342 /* Check that almost all pages in the area have been accessed; if
3343 offset == low, the accesses must be in a descending order, otherwise,
3344@@ -329,6 +330,7 @@
3345
3346 fail_count = 0;
3347
3348+ rw_lock_s_lock(&buf_pool->page_hash_latch);
3349 for (i = low; i < high; i++) {
3350 bpage = buf_page_hash_get(buf_pool, space, i);
3351
3352@@ -356,7 +358,8 @@
3353
3354 if (fail_count > threshold) {
3355 /* Too many failures: return */
3356- buf_pool_mutex_exit(buf_pool);
3357+ //buf_pool_mutex_exit(buf_pool);
3358+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
3359 return(0);
3360 }
3361
3362@@ -371,7 +374,8 @@
3363 bpage = buf_page_hash_get(buf_pool, space, offset);
3364
3365 if (bpage == NULL) {
3366- buf_pool_mutex_exit(buf_pool);
3367+ //buf_pool_mutex_exit(buf_pool);
3368+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
3369
3370 return(0);
3371 }
3372@@ -397,7 +401,8 @@
3373 pred_offset = fil_page_get_prev(frame);
3374 succ_offset = fil_page_get_next(frame);
3375
3376- buf_pool_mutex_exit(buf_pool);
3377+ //buf_pool_mutex_exit(buf_pool);
3378+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
3379
3380 if ((offset == low) && (succ_offset == offset + 1)) {
3381
3382diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
3383--- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:48:03.048955897 +0900
3384+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:48:29.304024564 +0900
df1b5770 3385@@ -264,6 +264,10 @@
b4e1fa2c
AM
3386 # endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */
3387 {&buf_pool_mutex_key, "buf_pool_mutex", 0},
3388 {&buf_pool_zip_mutex_key, "buf_pool_zip_mutex", 0},
3389+ {&buf_pool_LRU_list_mutex_key, "buf_pool_LRU_list_mutex", 0},
3390+ {&buf_pool_free_list_mutex_key, "buf_pool_free_list_mutex", 0},
3391+ {&buf_pool_zip_free_mutex_key, "buf_pool_zip_free_mutex", 0},
3392+ {&buf_pool_zip_hash_mutex_key, "buf_pool_zip_hash_mutex", 0},
3393 {&cache_last_read_mutex_key, "cache_last_read_mutex", 0},
3394 {&dict_foreign_err_mutex_key, "dict_foreign_err_mutex", 0},
3395 {&dict_sys_mutex_key, "dict_sys_mutex", 0},
adf0fb13 3396@@ -313,6 +317,7 @@
b4e1fa2c
AM
3397 {&archive_lock_key, "archive_lock", 0},
3398 # endif /* UNIV_LOG_ARCHIVE */
3399 {&btr_search_latch_key, "btr_search_latch", 0},
3400+ {&buf_pool_page_hash_key, "buf_pool_page_hash_latch", 0},
3401 # ifndef PFS_SKIP_BUFFER_MUTEX_RWLOCK
3402 {&buf_block_lock_key, "buf_block_lock", 0},
3403 # endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */
3404diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
3405--- a/storage/innobase/handler/i_s.cc 2010-12-03 15:37:45.517105700 +0900
3406+++ b/storage/innobase/handler/i_s.cc 2010-12-03 15:48:29.331024462 +0900
adf0fb13 3407@@ -1563,7 +1563,8 @@
b4e1fa2c
AM
3408
3409 buf_pool = buf_pool_from_array(i);
3410
3411- buf_pool_mutex_enter(buf_pool);
3412+ //buf_pool_mutex_enter(buf_pool);
3413+ mutex_enter(&buf_pool->zip_free_mutex);
3414
3415 for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
3416 buf_buddy_stat_t* buddy_stat;
adf0fb13 3417@@ -1593,7 +1594,8 @@
b4e1fa2c
AM
3418 }
3419 }
3420
3421- buf_pool_mutex_exit(buf_pool);
3422+ //buf_pool_mutex_exit(buf_pool);
3423+ mutex_exit(&buf_pool->zip_free_mutex);
3424
3425 if (status) {
3426 break;
3427diff -ruN a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
3428--- a/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:48:03.068954202 +0900
3429+++ b/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:48:29.335988682 +0900
adf0fb13 3430@@ -3821,9 +3821,11 @@
b4e1fa2c
AM
3431 ulint fold = buf_page_address_fold(space, page_no);
3432 buf_pool_t* buf_pool = buf_pool_get(space, page_no);
3433
3434- buf_pool_mutex_enter(buf_pool);
3435+ //buf_pool_mutex_enter(buf_pool);
3436+ rw_lock_s_lock(&buf_pool->page_hash_latch);
3437 bpage = buf_page_hash_get_low(buf_pool, space, page_no, fold);
3438- buf_pool_mutex_exit(buf_pool);
3439+ //buf_pool_mutex_exit(buf_pool);
3440+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
3441
3442 if (UNIV_LIKELY_NULL(bpage)) {
3443 /* A buffer pool watch has been set or the
3444diff -ruN a/storage/innobase/include/buf0buddy.h b/storage/innobase/include/buf0buddy.h
3445--- a/storage/innobase/include/buf0buddy.h 2010-11-03 07:01:13.000000000 +0900
3446+++ b/storage/innobase/include/buf0buddy.h 2010-12-03 15:48:29.338023826 +0900
3447@@ -51,10 +51,11 @@
3448 buf_pool_t* buf_pool,
3449 /*!< buffer pool in which the block resides */
3450 ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
3451- ibool* lru) /*!< in: pointer to a variable that will be assigned
3452+ ibool* lru, /*!< in: pointer to a variable that will be assigned
3453 TRUE if storage was allocated from the LRU list
3454 and buf_pool->mutex was temporarily released,
3455 or NULL if the LRU list should not be used */
3456+ ibool have_page_hash_mutex)
3457 __attribute__((malloc));
3458
3459 /**********************************************************************//**
3460@@ -67,7 +68,8 @@
3461 /*!< buffer pool in which the block resides */
3462 void* buf, /*!< in: block to be freed, must not be
3463 pointed to by the buffer pool */
3464- ulint size) /*!< in: block size, up to UNIV_PAGE_SIZE */
3465+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
3466+ ibool have_page_hash_mutex)
3467 __attribute__((nonnull));
3468
3469 #ifndef UNIV_NONINL
3470diff -ruN a/storage/innobase/include/buf0buddy.ic b/storage/innobase/include/buf0buddy.ic
3471--- a/storage/innobase/include/buf0buddy.ic 2010-11-03 07:01:13.000000000 +0900
3472+++ b/storage/innobase/include/buf0buddy.ic 2010-12-03 15:48:29.339040413 +0900
3473@@ -46,10 +46,11 @@
3474 /*!< in: buffer pool in which the page resides */
3475 ulint i, /*!< in: index of buf_pool->zip_free[],
3476 or BUF_BUDDY_SIZES */
3477- ibool* lru) /*!< in: pointer to a variable that will be assigned
3478+ ibool* lru, /*!< in: pointer to a variable that will be assigned
3479 TRUE if storage was allocated from the LRU list
3480 and buf_pool->mutex was temporarily released,
3481 or NULL if the LRU list should not be used */
3482+ ibool have_page_hash_mutex)
3483 __attribute__((malloc));
3484
3485 /**********************************************************************//**
3486@@ -61,8 +62,9 @@
3487 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
3488 void* buf, /*!< in: block to be freed, must not be
3489 pointed to by the buffer pool */
3490- ulint i) /*!< in: index of buf_pool->zip_free[],
3491+ ulint i, /*!< in: index of buf_pool->zip_free[],
3492 or BUF_BUDDY_SIZES */
3493+ ibool have_page_hash_mutex)
3494 __attribute__((nonnull));
3495
3496 /**********************************************************************//**
3497@@ -102,16 +104,17 @@
3498 the page resides */
3499 ulint size, /*!< in: block size, up to
3500 UNIV_PAGE_SIZE */
3501- ibool* lru) /*!< in: pointer to a variable
3502+ ibool* lru, /*!< in: pointer to a variable
3503 that will be assigned TRUE if
3504 storage was allocated from the
3505 LRU list and buf_pool->mutex was
3506 temporarily released, or NULL if
3507 the LRU list should not be used */
3508+ ibool have_page_hash_mutex)
3509 {
3510- ut_ad(buf_pool_mutex_own(buf_pool));
3511+ //ut_ad(buf_pool_mutex_own(buf_pool));
3512
3513- return(buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size), lru));
3514+ return(buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size), lru, have_page_hash_mutex));
3515 }
3516
3517 /**********************************************************************//**
3518@@ -123,12 +126,25 @@
3519 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
3520 void* buf, /*!< in: block to be freed, must not be
3521 pointed to by the buffer pool */
3522- ulint size) /*!< in: block size, up to
3523+ ulint size, /*!< in: block size, up to
3524 UNIV_PAGE_SIZE */
3525+ ibool have_page_hash_mutex)
3526 {
3527- ut_ad(buf_pool_mutex_own(buf_pool));
3528+ //ut_ad(buf_pool_mutex_own(buf_pool));
3529+
3530+ if (!have_page_hash_mutex) {
3531+ mutex_enter(&buf_pool->LRU_list_mutex);
3532+ rw_lock_x_lock(&buf_pool->page_hash_latch);
3533+ }
3534
3535- buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size));
3536+ mutex_enter(&buf_pool->zip_free_mutex);
3537+ buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size), TRUE);
3538+ mutex_exit(&buf_pool->zip_free_mutex);
3539+
3540+ if (!have_page_hash_mutex) {
3541+ mutex_exit(&buf_pool->LRU_list_mutex);
3542+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
3543+ }
3544 }
3545
3546 #ifdef UNIV_MATERIALIZE
3547diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
3548--- a/storage/innobase/include/buf0buf.h 2010-12-03 15:22:36.327954660 +0900
3549+++ b/storage/innobase/include/buf0buf.h 2010-12-03 15:48:29.343024683 +0900
adf0fb13 3550@@ -205,6 +205,20 @@
b4e1fa2c
AM
3551 /*==========================*/
3552
3553 /********************************************************************//**
3554+*/
3555+UNIV_INLINE
3556+void
3557+buf_pool_page_hash_x_lock_all(void);
3558+/*================================*/
3559+
3560+/********************************************************************//**
3561+*/
3562+UNIV_INLINE
3563+void
3564+buf_pool_page_hash_x_unlock_all(void);
3565+/*==================================*/
3566+
3567+/********************************************************************//**
3568 Creates the buffer pool.
3569 @return own: buf_pool object, NULL if not enough memory or error */
3570 UNIV_INTERN
adf0fb13 3571@@ -834,6 +848,15 @@
b4e1fa2c
AM
3572 const buf_page_t* bpage) /*!< in: pointer to control block */
3573 __attribute__((pure));
3574
3575+/*************************************************************************
3576+Gets the mutex of a block and enter the mutex with consistency. */
3577+UNIV_INLINE
3578+mutex_t*
3579+buf_page_get_mutex_enter(
3580+/*=========================*/
3581+ const buf_page_t* bpage) /*!< in: pointer to control block */
3582+ __attribute__((pure));
3583+
3584 /*********************************************************************//**
3585 Get the flush type of a page.
3586 @return flush type */
adf0fb13 3587@@ -1315,7 +1338,7 @@
b4e1fa2c
AM
3588 All these are protected by buf_pool->mutex. */
3589 /* @{ */
3590
3591- UT_LIST_NODE_T(buf_page_t) list;
3592+ /* UT_LIST_NODE_T(buf_page_t) list; */
3593 /*!< based on state, this is a
3594 list node, protected either by
3595 buf_pool->mutex or by
adf0fb13 3596@@ -1343,6 +1366,10 @@
b4e1fa2c
AM
3597 BUF_BLOCK_REMOVE_HASH or
3598 BUF_BLOCK_READY_IN_USE. */
3599
3600+ /* resplit for optimistic use */
3601+ UT_LIST_NODE_T(buf_page_t) free;
3602+ UT_LIST_NODE_T(buf_page_t) flush_list;
3603+ UT_LIST_NODE_T(buf_page_t) zip_list; /* zip_clean or zip_free[] */
3604 #ifdef UNIV_DEBUG
3605 ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;
3606 when buf_pool->flush_list_mutex is
adf0fb13 3607@@ -1435,11 +1462,11 @@
b4e1fa2c
AM
3608 a block is in the unzip_LRU list
3609 if page.state == BUF_BLOCK_FILE_PAGE
3610 and page.zip.data != NULL */
3611-#ifdef UNIV_DEBUG
3612+//#ifdef UNIV_DEBUG
3613 ibool in_unzip_LRU_list;/*!< TRUE if the page is in the
3614 decompressed LRU list;
3615 used in debugging */
3616-#endif /* UNIV_DEBUG */
3617+//#endif /* UNIV_DEBUG */
3618 mutex_t mutex; /*!< mutex protecting this block:
3619 state (also protected by the buffer
3620 pool mutex), io_fix, buf_fix_count,
adf0fb13 3621@@ -1614,6 +1641,11 @@
b4e1fa2c
AM
3622 pool instance, protects compressed
3623 only pages (of type buf_page_t, not
3624 buf_block_t */
3625+ mutex_t LRU_list_mutex;
3626+ rw_lock_t page_hash_latch;
3627+ mutex_t free_list_mutex;
3628+ mutex_t zip_free_mutex;
3629+ mutex_t zip_hash_mutex;
3630 ulint instance_no; /*!< Array index of this buffer
3631 pool instance */
3632 ulint old_pool_size; /*!< Old pool size in bytes */
adf0fb13 3633@@ -1765,8 +1797,8 @@
11822e22
AM
3634 /** Test if a buffer pool mutex is owned. */
3635 #define buf_pool_mutex_own(b) mutex_own(&b->mutex)
3636 /** Acquire a buffer pool mutex. */
3637+/* the buf_pool_mutex is changed the latch order */
3638 #define buf_pool_mutex_enter(b) do { \
3639- ut_ad(!mutex_own(&b->zip_mutex)); \
3640 mutex_enter(&b->mutex); \
3641 } while (0)
3642
b4e1fa2c
AM
3643diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
3644--- a/storage/innobase/include/buf0buf.ic 2010-11-03 07:01:13.000000000 +0900
3645+++ b/storage/innobase/include/buf0buf.ic 2010-12-03 15:48:29.345024524 +0900
3646@@ -274,7 +274,7 @@
3647 case BUF_BLOCK_ZIP_FREE:
3648 /* This is a free page in buf_pool->zip_free[].
3649 Such pages should only be accessed by the buddy allocator. */
3650- ut_error;
3651+ /* ut_error; */ /* optimistic */
3652 break;
3653 case BUF_BLOCK_ZIP_PAGE:
3654 case BUF_BLOCK_ZIP_DIRTY:
11822e22 3655@@ -317,9 +317,16 @@
b4e1fa2c
AM
3656 {
3657 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3658
11822e22
AM
3659+ if (/*equivalent to buf_pool_watch_is_sentinel(buf_pool, bpage)*/
3660+ bpage >= &buf_pool->watch[0]
3661+ && bpage < &buf_pool->watch[BUF_POOL_WATCH_SIZE]) {
b4e1fa2c
AM
3662+ /* TODO: this code is the interim. should be confirmed later. */
3663+ return(&buf_pool->zip_mutex);
3664+ }
3665+
3666 switch (buf_page_get_state(bpage)) {
3667 case BUF_BLOCK_ZIP_FREE:
3668- ut_error;
3669+ /* ut_error; */ /* optimistic */
3670 return(NULL);
3671 case BUF_BLOCK_ZIP_PAGE:
3672 case BUF_BLOCK_ZIP_DIRTY:
11822e22 3673@@ -329,6 +336,28 @@
b4e1fa2c
AM
3674 }
3675 }
3676
3677+/*************************************************************************
3678+Gets the mutex of a block and enter the mutex with consistency. */
3679+UNIV_INLINE
3680+mutex_t*
3681+buf_page_get_mutex_enter(
3682+/*=========================*/
3683+ const buf_page_t* bpage) /*!< in: pointer to control block */
3684+{
3685+ mutex_t* block_mutex;
3686+
3687+ while(1) {
3688+ block_mutex = buf_page_get_mutex(bpage);
3689+ if (!block_mutex)
3690+ return block_mutex;
3691+
3692+ mutex_enter(block_mutex);
3693+ if (block_mutex == buf_page_get_mutex(bpage))
3694+ return block_mutex;
3695+ mutex_exit(block_mutex);
3696+ }
3697+}
3698+
3699 /*********************************************************************//**
3700 Get the flush type of a page.
3701 @return flush type */
11822e22 3702@@ -425,8 +454,8 @@
b4e1fa2c
AM
3703 enum buf_io_fix io_fix) /*!< in: io_fix state */
3704 {
3705 #ifdef UNIV_DEBUG
3706- buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3707- ut_ad(buf_pool_mutex_own(buf_pool));
3708+ //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3709+ //ut_ad(buf_pool_mutex_own(buf_pool));
3710 #endif
3711 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
3712
11822e22 3713@@ -456,14 +485,14 @@
b4e1fa2c
AM
3714 const buf_page_t* bpage) /*!< control block being relocated */
3715 {
3716 #ifdef UNIV_DEBUG
3717- buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3718- ut_ad(buf_pool_mutex_own(buf_pool));
3719+ //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3720+ //ut_ad(buf_pool_mutex_own(buf_pool));
3721 #endif
3722 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
3723 ut_ad(buf_page_in_file(bpage));
3724- ut_ad(bpage->in_LRU_list);
3725+ //ut_ad(bpage->in_LRU_list);
3726
3727- return(buf_page_get_io_fix(bpage) == BUF_IO_NONE
3728+ return(bpage->in_LRU_list && bpage->io_fix == BUF_IO_NONE
3729 && bpage->buf_fix_count == 0);
3730 }
3731
11822e22 3732@@ -477,8 +506,8 @@
b4e1fa2c
AM
3733 const buf_page_t* bpage) /*!< in: control block */
3734 {
3735 #ifdef UNIV_DEBUG
3736- buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3737- ut_ad(buf_pool_mutex_own(buf_pool));
3738+ //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3739+ //ut_ad(buf_pool_mutex_own(buf_pool));
3740 #endif
3741 ut_ad(buf_page_in_file(bpage));
3742
11822e22 3743@@ -498,7 +527,8 @@
b4e1fa2c
AM
3744 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3745 #endif /* UNIV_DEBUG */
3746 ut_a(buf_page_in_file(bpage));
3747- ut_ad(buf_pool_mutex_own(buf_pool));
3748+ //ut_ad(buf_pool_mutex_own(buf_pool));
3749+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
3750 ut_ad(bpage->in_LRU_list);
3751
3752 #ifdef UNIV_LRU_DEBUG
11822e22 3753@@ -545,9 +575,10 @@
b4e1fa2c
AM
3754 ulint time_ms) /*!< in: ut_time_ms() */
3755 {
3756 #ifdef UNIV_DEBUG
3757- buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3758- ut_ad(buf_pool_mutex_own(buf_pool));
3759+ //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3760+ //ut_ad(buf_pool_mutex_own(buf_pool));
3761 #endif
3762+ ut_ad(mutex_own(buf_page_get_mutex(bpage)));
3763 ut_a(buf_page_in_file(bpage));
3764
3765 if (!bpage->access_time) {
11822e22 3766@@ -761,19 +792,19 @@
b4e1fa2c
AM
3767 /*===========*/
3768 buf_block_t* block) /*!< in, own: block to be freed */
3769 {
3770- buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
3771+ //buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
3772
3773- buf_pool_mutex_enter(buf_pool);
3774+ //buf_pool_mutex_enter(buf_pool);
3775
3776 mutex_enter(&block->mutex);
3777
3778 ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
3779
3780- buf_LRU_block_free_non_file_page(block);
3781+ buf_LRU_block_free_non_file_page(block, FALSE);
3782
3783 mutex_exit(&block->mutex);
3784
3785- buf_pool_mutex_exit(buf_pool);
3786+ //buf_pool_mutex_exit(buf_pool);
3787 }
3788 #endif /* !UNIV_HOTBACKUP */
3789
11822e22 3790@@ -821,17 +852,17 @@
b4e1fa2c
AM
3791 page frame */
3792 {
3793 ib_uint64_t lsn;
3794- mutex_t* block_mutex = buf_page_get_mutex(bpage);
3795-
3796- mutex_enter(block_mutex);
3797+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
3798
3799- if (buf_page_in_file(bpage)) {
3800+ if (block_mutex && buf_page_in_file(bpage)) {
3801 lsn = bpage->newest_modification;
3802 } else {
3803 lsn = 0;
3804 }
3805
3806- mutex_exit(block_mutex);
3807+ if (block_mutex) {
3808+ mutex_exit(block_mutex);
3809+ }
3810
3811 return(lsn);
3812 }
11822e22 3813@@ -849,7 +880,7 @@
b4e1fa2c
AM
3814 #ifdef UNIV_SYNC_DEBUG
3815 buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
3816
3817- ut_ad((buf_pool_mutex_own(buf_pool)
3818+ ut_ad((mutex_own(&buf_pool->LRU_list_mutex)
3819 && (block->page.buf_fix_count == 0))
3820 || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
3821 #endif /* UNIV_SYNC_DEBUG */
11822e22 3822@@ -979,7 +1010,11 @@
b4e1fa2c
AM
3823 buf_page_t* bpage;
3824
3825 ut_ad(buf_pool);
3826- ut_ad(buf_pool_mutex_own(buf_pool));
3827+ //ut_ad(buf_pool_mutex_own(buf_pool));
3828+#ifdef UNIV_SYNC_DEBUG
3829+ ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX)
3830+ || rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_SHARED));
3831+#endif
3832 ut_ad(fold == buf_page_address_fold(space, offset));
3833
3834 /* Look for the page in the hash table */
11822e22 3835@@ -1064,11 +1099,13 @@
b4e1fa2c
AM
3836 const buf_page_t* bpage;
3837 buf_pool_t* buf_pool = buf_pool_get(space, offset);
3838
3839- buf_pool_mutex_enter(buf_pool);
3840+ //buf_pool_mutex_enter(buf_pool);
3841+ rw_lock_s_lock(&buf_pool->page_hash_latch);
3842
3843 bpage = buf_page_hash_get(buf_pool, space, offset);
3844
3845- buf_pool_mutex_exit(buf_pool);
3846+ //buf_pool_mutex_exit(buf_pool);
3847+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
3848
3849 return(bpage != NULL);
3850 }
11822e22 3851@@ -1196,4 +1233,38 @@
b4e1fa2c
AM
3852 buf_pool_mutex_exit(buf_pool);
3853 }
3854 }
3855+
3856+/********************************************************************//**
3857+*/
3858+UNIV_INLINE
3859+void
3860+buf_pool_page_hash_x_lock_all(void)
3861+/*===============================*/
3862+{
3863+ ulint i;
3864+
3865+ for (i = 0; i < srv_buf_pool_instances; i++) {
3866+ buf_pool_t* buf_pool;
3867+
3868+ buf_pool = buf_pool_from_array(i);
3869+ rw_lock_x_lock(&buf_pool->page_hash_latch);
3870+ }
3871+}
3872+
3873+/********************************************************************//**
3874+*/
3875+UNIV_INLINE
3876+void
3877+buf_pool_page_hash_x_unlock_all(void)
3878+/*=================================*/
3879+{
3880+ ulint i;
3881+
3882+ for (i = 0; i < srv_buf_pool_instances; i++) {
3883+ buf_pool_t* buf_pool;
3884+
3885+ buf_pool = buf_pool_from_array(i);
3886+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
3887+ }
3888+}
3889 #endif /* !UNIV_HOTBACKUP */
3890diff -ruN a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
3891--- a/storage/innobase/include/buf0lru.h 2010-11-03 07:01:13.000000000 +0900
3892+++ b/storage/innobase/include/buf0lru.h 2010-12-03 15:48:29.349024701 +0900
df1b5770
AM
3893@@ -111,8 +111,9 @@
3894 buf_LRU_free_block(
3895 /*===============*/
b4e1fa2c 3896 buf_page_t* bpage, /*!< in: block to be freed */
df1b5770
AM
3897- ibool zip) /*!< in: TRUE if should remove also the
3898+ ibool zip, /*!< in: TRUE if should remove also the
b4e1fa2c 3899 compressed page of an uncompressed page */
df1b5770
AM
3900+ ibool have_LRU_mutex)
3901 __attribute__((nonnull));
b4e1fa2c
AM
3902 /******************************************************************//**
3903 Try to free a replaceable block.
df1b5770 3904@@ -159,7 +160,8 @@
b4e1fa2c
AM
3905 void
3906 buf_LRU_block_free_non_file_page(
3907 /*=============================*/
3908- buf_block_t* block); /*!< in: block, must not contain a file page */
3909+ buf_block_t* block, /*!< in: block, must not contain a file page */
3910+ ibool have_page_hash_mutex);
3911 /******************************************************************//**
3912 Adds a block to the LRU list. */
3913 UNIV_INTERN
3914diff -ruN a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
3915--- a/storage/innobase/include/sync0rw.h 2010-11-03 07:01:13.000000000 +0900
3916+++ b/storage/innobase/include/sync0rw.h 2010-12-03 15:48:29.349942993 +0900
3917@@ -112,6 +112,7 @@
3918 extern mysql_pfs_key_t archive_lock_key;
3919 # endif /* UNIV_LOG_ARCHIVE */
3920 extern mysql_pfs_key_t btr_search_latch_key;
3921+extern mysql_pfs_key_t buf_pool_page_hash_key;
3922 extern mysql_pfs_key_t buf_block_lock_key;
3923 # ifdef UNIV_SYNC_DEBUG
3924 extern mysql_pfs_key_t buf_block_debug_latch_key;
3925diff -ruN a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
3926--- a/storage/innobase/include/sync0sync.h 2010-11-03 07:01:13.000000000 +0900
3927+++ b/storage/innobase/include/sync0sync.h 2010-12-03 15:48:29.352024614 +0900
3928@@ -75,6 +75,10 @@
3929 extern mysql_pfs_key_t buffer_block_mutex_key;
3930 extern mysql_pfs_key_t buf_pool_mutex_key;
3931 extern mysql_pfs_key_t buf_pool_zip_mutex_key;
3932+extern mysql_pfs_key_t buf_pool_LRU_list_mutex_key;
3933+extern mysql_pfs_key_t buf_pool_free_list_mutex_key;
3934+extern mysql_pfs_key_t buf_pool_zip_free_mutex_key;
3935+extern mysql_pfs_key_t buf_pool_zip_hash_mutex_key;
3936 extern mysql_pfs_key_t cache_last_read_mutex_key;
3937 extern mysql_pfs_key_t dict_foreign_err_mutex_key;
3938 extern mysql_pfs_key_t dict_sys_mutex_key;
adf0fb13 3939@@ -668,7 +672,7 @@
b4e1fa2c 3940 #define SYNC_TRX_SYS_HEADER 290
11822e22 3941 #define SYNC_PURGE_QUEUE 200
b4e1fa2c
AM
3942 #define SYNC_LOG 170
3943-#define SYNC_LOG_FLUSH_ORDER 147
3944+#define SYNC_LOG_FLUSH_ORDER 156
3945 #define SYNC_RECV 168
3946 #define SYNC_WORK_QUEUE 162
3947 #define SYNC_SEARCH_SYS_CONF 161 /* for assigning btr_search_enabled */
adf0fb13 3948@@ -678,8 +682,13 @@
b4e1fa2c
AM
3949 SYNC_SEARCH_SYS, as memory allocation
3950 can call routines there! Otherwise
3951 the level is SYNC_MEM_HASH. */
3952+#define SYNC_BUF_LRU_LIST 158
3953+#define SYNC_BUF_PAGE_HASH 157
3954+#define SYNC_BUF_BLOCK 155 /* Block mutex */
3955+#define SYNC_BUF_FREE_LIST 153
3956+#define SYNC_BUF_ZIP_FREE 152
3957+#define SYNC_BUF_ZIP_HASH 151
3958 #define SYNC_BUF_POOL 150 /* Buffer pool mutex */
3959-#define SYNC_BUF_BLOCK 146 /* Block mutex */
3960 #define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */
3961 #define SYNC_DOUBLEWRITE 140
3962 #define SYNC_ANY_LATCH 135
adf0fb13 3963@@ -711,7 +720,7 @@
b4e1fa2c
AM
3964 os_fast_mutex; /*!< We use this OS mutex in place of lock_word
3965 when atomic operations are not enabled */
3966 #endif
3967- ulint waiters; /*!< This ulint is set to 1 if there are (or
3968+ volatile ulint waiters; /*!< This ulint is set to 1 if there are (or
3969 may be) threads waiting in the global wait
3970 array for this mutex to be released.
3971 Otherwise, this is 0. */
3972diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
3973--- a/storage/innobase/srv/srv0srv.c 2010-12-03 15:48:03.080956216 +0900
3974+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 15:48:29.355023766 +0900
adf0fb13 3975@@ -3098,7 +3098,7 @@
b4e1fa2c
AM
3976 level += log_sys->max_checkpoint_age
3977 - (lsn - oldest_modification);
3978 }
3979- bpage = UT_LIST_GET_NEXT(list, bpage);
3980+ bpage = UT_LIST_GET_NEXT(flush_list, bpage);
3981 n_blocks++;
3982 }
3983
adf0fb13 3984@@ -3184,7 +3184,7 @@
b4e1fa2c
AM
3985 found = TRUE;
3986 break;
3987 }
3988- bpage = UT_LIST_GET_NEXT(list, bpage);
3989+ bpage = UT_LIST_GET_NEXT(flush_list, bpage);
3990 new_blocks_num++;
3991 }
3992 if (!found) {
3993diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
3994--- a/storage/innobase/sync/sync0sync.c 2010-11-03 07:01:13.000000000 +0900
3995+++ b/storage/innobase/sync/sync0sync.c 2010-12-03 15:48:29.358023890 +0900
adf0fb13 3996@@ -285,7 +285,7 @@
b4e1fa2c
AM
3997 mutex->lock_word = 0;
3998 #endif
3999 mutex->event = os_event_create(NULL);
4000- mutex_set_waiters(mutex, 0);
4001+ mutex->waiters = 0;
4002 #ifdef UNIV_DEBUG
4003 mutex->magic_n = MUTEX_MAGIC_N;
4004 #endif /* UNIV_DEBUG */
adf0fb13 4005@@ -464,6 +464,15 @@
b4e1fa2c
AM
4006 mutex_t* mutex, /*!< in: mutex */
4007 ulint n) /*!< in: value to set */
4008 {
4009+#ifdef INNODB_RW_LOCKS_USE_ATOMICS
4010+ ut_ad(mutex);
4011+
4012+ if (n) {
4013+ os_compare_and_swap_ulint(&mutex->waiters, 0, 1);
4014+ } else {
4015+ os_compare_and_swap_ulint(&mutex->waiters, 1, 0);
4016+ }
4017+#else
4018 volatile ulint* ptr; /* declared volatile to ensure that
4019 the value is stored to memory */
4020 ut_ad(mutex);
adf0fb13 4021@@ -472,6 +481,7 @@
b4e1fa2c
AM
4022
4023 *ptr = n; /* Here we assume that the write of a single
4024 word in memory is atomic */
4025+#endif
4026 }
4027
4028 /******************************************************************//**
adf0fb13 4029@@ -1234,7 +1244,12 @@
b4e1fa2c
AM
4030 ut_error;
4031 }
4032 break;
4033+ case SYNC_BUF_LRU_LIST:
4034 case SYNC_BUF_FLUSH_LIST:
4035+ case SYNC_BUF_PAGE_HASH:
4036+ case SYNC_BUF_FREE_LIST:
4037+ case SYNC_BUF_ZIP_FREE:
4038+ case SYNC_BUF_ZIP_HASH:
4039 case SYNC_BUF_POOL:
4040 /* We can have multiple mutexes of this type therefore we
4041 can only check whether the greater than condition holds. */
adf0fb13 4042@@ -1252,7 +1267,8 @@
b4e1fa2c
AM
4043 buffer block (block->mutex or buf_pool->zip_mutex). */
4044 if (!sync_thread_levels_g(array, level, FALSE)) {
4045 ut_a(sync_thread_levels_g(array, level - 1, TRUE));
4046- ut_a(sync_thread_levels_contain(array, SYNC_BUF_POOL));
4047+ /* the exact rule is not fixed yet, for now */
4048+ //ut_a(sync_thread_levels_contain(array, SYNC_BUF_LRU_LIST));
4049 }
4050 break;
4051 case SYNC_REC_LOCK:
This page took 0.566211 seconds and 4 git commands to generate.