1 # name : innodb_split_buf_pool_mutex.patch
2 # introduced : 11 or before
3 # maintainer : Yasufumi
6 # Any small change to this file in the main branch
7 # should be done or reviewed by the maintainer!
8 --- a/storage/innobase/btr/btr0cur.c
9 +++ b/storage/innobase/btr/btr0cur.c
14 - buf_pool_mutex_enter(buf_pool);
15 + //buf_pool_mutex_enter(buf_pool);
16 + mutex_enter(&buf_pool->LRU_list_mutex);
17 mutex_enter(&block->mutex);
19 /* Only free the block if it is still allocated to
20 @@ -4102,16 +4103,21 @@
21 && buf_block_get_space(block) == space
22 && buf_block_get_page_no(block) == page_no) {
24 - if (!buf_LRU_free_block(&block->page, all)
25 - && all && block->page.zip.data) {
26 + if (!buf_LRU_free_block(&block->page, all, TRUE)
27 + && all && block->page.zip.data
28 + /* Now, buf_LRU_free_block() may release mutex temporarily */
29 + && buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
30 + && buf_block_get_space(block) == space
31 + && buf_block_get_page_no(block) == page_no) {
32 /* Attempt to deallocate the uncompressed page
33 if the whole block cannot be deallocted. */
35 - buf_LRU_free_block(&block->page, FALSE);
36 + buf_LRU_free_block(&block->page, FALSE, TRUE);
40 - buf_pool_mutex_exit(buf_pool);
41 + //buf_pool_mutex_exit(buf_pool);
42 + mutex_exit(&buf_pool->LRU_list_mutex);
43 mutex_exit(&block->mutex);
46 --- a/storage/innobase/btr/btr0sea.c
47 +++ b/storage/innobase/btr/btr0sea.c
49 rec_offs_init(offsets_);
51 rw_lock_x_lock(&btr_search_latch);
52 - buf_pool_mutex_enter_all();
53 + buf_pool_page_hash_x_lock_all();
55 cell_count = hash_get_n_cells(btr_search_sys->hash_index);
57 @@ -1952,11 +1952,11 @@
58 /* We release btr_search_latch every once in a while to
59 give other queries a chance to run. */
60 if ((i != 0) && ((i % chunk_size) == 0)) {
61 - buf_pool_mutex_exit_all();
62 + buf_pool_page_hash_x_unlock_all();
63 rw_lock_x_unlock(&btr_search_latch);
65 rw_lock_x_lock(&btr_search_latch);
66 - buf_pool_mutex_enter_all();
67 + buf_pool_page_hash_x_lock_all();
70 node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
71 @@ -2067,11 +2067,11 @@
72 /* We release btr_search_latch every once in a while to
73 give other queries a chance to run. */
75 - buf_pool_mutex_exit_all();
76 + buf_pool_page_hash_x_unlock_all();
77 rw_lock_x_unlock(&btr_search_latch);
79 rw_lock_x_lock(&btr_search_latch);
80 - buf_pool_mutex_enter_all();
81 + buf_pool_page_hash_x_lock_all();
84 if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
89 - buf_pool_mutex_exit_all();
90 + buf_pool_page_hash_x_unlock_all();
91 rw_lock_x_unlock(&btr_search_latch);
92 if (UNIV_LIKELY_NULL(heap)) {
94 --- a/storage/innobase/buf/buf0buddy.c
95 +++ b/storage/innobase/buf/buf0buddy.c
98 /** Validate a given zip_free list. */
99 #define BUF_BUDDY_LIST_VALIDATE(b, i) \
100 - UT_LIST_VALIDATE(list, buf_page_t, \
101 + UT_LIST_VALIDATE(zip_list, buf_page_t, \
103 ut_ad(buf_page_get_state( \
106 ulint i) /*!< in: index of
107 buf_pool->zip_free[] */
109 - ut_ad(buf_pool_mutex_own(buf_pool));
110 + //ut_ad(buf_pool_mutex_own(buf_pool));
111 + ut_ad(mutex_own(&buf_pool->zip_free_mutex));
112 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
113 ut_ad(buf_pool->zip_free[i].start != bpage);
114 - UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], bpage);
115 + UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_free[i], bpage);
118 /**********************************************************************//**
120 buf_pool->zip_free[] */
123 - buf_page_t* prev = UT_LIST_GET_PREV(list, bpage);
124 - buf_page_t* next = UT_LIST_GET_NEXT(list, bpage);
125 + buf_page_t* prev = UT_LIST_GET_PREV(zip_list, bpage);
126 + buf_page_t* next = UT_LIST_GET_NEXT(zip_list, bpage);
128 ut_ad(!prev || buf_page_get_state(prev) == BUF_BLOCK_ZIP_FREE);
129 ut_ad(!next || buf_page_get_state(next) == BUF_BLOCK_ZIP_FREE);
130 #endif /* UNIV_DEBUG */
132 - ut_ad(buf_pool_mutex_own(buf_pool));
133 + //ut_ad(buf_pool_mutex_own(buf_pool));
134 + ut_ad(mutex_own(&buf_pool->zip_free_mutex));
135 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
136 - UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
137 + UT_LIST_REMOVE(zip_list, buf_pool->zip_free[i], bpage);
140 /**********************************************************************//**
145 - ut_ad(buf_pool_mutex_own(buf_pool));
146 + //ut_ad(buf_pool_mutex_own(buf_pool));
147 + ut_ad(mutex_own(&buf_pool->zip_free_mutex));
148 ut_a(i < BUF_BUDDY_SIZES);
149 ut_a(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
151 @@ -159,16 +162,19 @@
152 buf_buddy_block_free(
153 /*=================*/
154 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
155 - void* buf) /*!< in: buffer frame to deallocate */
156 + void* buf, /*!< in: buffer frame to deallocate */
157 + ibool have_page_hash_mutex)
159 const ulint fold = BUF_POOL_ZIP_FOLD_PTR(buf);
163 - ut_ad(buf_pool_mutex_own(buf_pool));
164 + //ut_ad(buf_pool_mutex_own(buf_pool));
165 ut_ad(!mutex_own(&buf_pool->zip_mutex));
166 ut_a(!ut_align_offset(buf, UNIV_PAGE_SIZE));
168 + mutex_enter(&buf_pool->zip_hash_mutex);
170 HASH_SEARCH(hash, buf_pool->zip_hash, fold, buf_page_t*, bpage,
171 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_MEMORY
172 && bpage->in_zip_hash && !bpage->in_page_hash),
173 @@ -180,12 +186,14 @@
174 ut_d(bpage->in_zip_hash = FALSE);
175 HASH_DELETE(buf_page_t, hash, buf_pool->zip_hash, fold, bpage);
177 + mutex_exit(&buf_pool->zip_hash_mutex);
179 ut_d(memset(buf, 0, UNIV_PAGE_SIZE));
180 UNIV_MEM_INVALID(buf, UNIV_PAGE_SIZE);
182 block = (buf_block_t*) bpage;
183 mutex_enter(&block->mutex);
184 - buf_LRU_block_free_non_file_page(block);
185 + buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
186 mutex_exit(&block->mutex);
188 ut_ad(buf_pool->buddy_n_frames > 0);
191 buf_pool_t* buf_pool = buf_pool_from_block(block);
192 const ulint fold = BUF_POOL_ZIP_FOLD(block);
193 - ut_ad(buf_pool_mutex_own(buf_pool));
194 + //ut_ad(buf_pool_mutex_own(buf_pool));
195 ut_ad(!mutex_own(&buf_pool->zip_mutex));
196 ut_ad(buf_block_get_state(block) == BUF_BLOCK_READY_FOR_USE);
199 ut_ad(!block->page.in_page_hash);
200 ut_ad(!block->page.in_zip_hash);
201 ut_d(block->page.in_zip_hash = TRUE);
203 + mutex_enter(&buf_pool->zip_hash_mutex);
204 HASH_INSERT(buf_page_t, hash, buf_pool->zip_hash, fold, &block->page);
205 + mutex_exit(&buf_pool->zip_hash_mutex);
207 ut_d(buf_pool->buddy_n_frames++);
209 @@ -268,26 +279,30 @@
210 buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
211 ulint i, /*!< in: index of buf_pool->zip_free[],
212 or BUF_BUDDY_SIZES */
213 - ibool* lru) /*!< in: pointer to a variable that
214 + ibool* lru, /*!< in: pointer to a variable that
215 will be assigned TRUE if storage was
216 allocated from the LRU list and
217 buf_pool->mutex was temporarily
219 + ibool have_page_hash_mutex)
224 - ut_ad(buf_pool_mutex_own(buf_pool));
225 + //ut_ad(buf_pool_mutex_own(buf_pool));
226 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
227 ut_ad(!mutex_own(&buf_pool->zip_mutex));
228 ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
230 if (i < BUF_BUDDY_SIZES) {
231 /* Try to allocate from the buddy system. */
232 + mutex_enter(&buf_pool->zip_free_mutex);
233 block = buf_buddy_alloc_zip(buf_pool, i);
238 + mutex_exit(&buf_pool->zip_free_mutex);
241 /* Try allocating from the buf_pool->free list. */
242 @@ -299,19 +314,30 @@
245 /* Try replacing an uncompressed page in the buffer pool. */
246 - buf_pool_mutex_exit(buf_pool);
247 + //buf_pool_mutex_exit(buf_pool);
248 + mutex_exit(&buf_pool->LRU_list_mutex);
249 + if (have_page_hash_mutex) {
250 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
252 block = buf_LRU_get_free_block(buf_pool);
254 - buf_pool_mutex_enter(buf_pool);
255 + //buf_pool_mutex_enter(buf_pool);
256 + mutex_enter(&buf_pool->LRU_list_mutex);
257 + if (have_page_hash_mutex) {
258 + rw_lock_x_lock(&buf_pool->page_hash_latch);
262 buf_buddy_block_register(block);
264 + mutex_enter(&buf_pool->zip_free_mutex);
265 block = buf_buddy_alloc_from(
266 buf_pool, block->frame, i, BUF_BUDDY_SIZES);
269 buf_pool->buddy_stat[i].used++;
270 + mutex_exit(&buf_pool->zip_free_mutex);
276 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
277 void* src, /*!< in: block to relocate */
278 void* dst, /*!< in: free block to relocate to */
279 - ulint i) /*!< in: index of
280 + ulint i, /*!< in: index of
281 buf_pool->zip_free[] */
282 + ibool have_page_hash_mutex)
285 const ulint size = BUF_BUDDY_LOW << i;
286 @@ -334,13 +361,20 @@
290 - ut_ad(buf_pool_mutex_own(buf_pool));
291 + //ut_ad(buf_pool_mutex_own(buf_pool));
292 + ut_ad(mutex_own(&buf_pool->zip_free_mutex));
293 ut_ad(!mutex_own(&buf_pool->zip_mutex));
294 ut_ad(!ut_align_offset(src, size));
295 ut_ad(!ut_align_offset(dst, size));
296 ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
297 UNIV_MEM_ASSERT_W(dst, size);
299 + if (!have_page_hash_mutex) {
300 + mutex_exit(&buf_pool->zip_free_mutex);
301 + mutex_enter(&buf_pool->LRU_list_mutex);
302 + rw_lock_x_lock(&buf_pool->page_hash_latch);
305 /* We assume that all memory from buf_buddy_alloc()
306 is used for compressed page frames. */
309 added to buf_pool->page_hash yet. Obviously,
310 it cannot be relocated. */
312 + if (!have_page_hash_mutex) {
313 + mutex_enter(&buf_pool->zip_free_mutex);
314 + mutex_exit(&buf_pool->LRU_list_mutex);
315 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
320 @@ -383,18 +422,27 @@
321 For the sake of simplicity, give up. */
322 ut_ad(page_zip_get_size(&bpage->zip) < size);
324 + if (!have_page_hash_mutex) {
325 + mutex_enter(&buf_pool->zip_free_mutex);
326 + mutex_exit(&buf_pool->LRU_list_mutex);
327 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
332 + /* To keep latch order */
333 + if (have_page_hash_mutex)
334 + mutex_exit(&buf_pool->zip_free_mutex);
336 /* The block must have been allocated, but it may
337 contain uninitialized data. */
338 UNIV_MEM_ASSERT_W(src, size);
340 - mutex = buf_page_get_mutex(bpage);
341 + mutex = buf_page_get_mutex_enter(bpage);
343 - mutex_enter(mutex);
344 + mutex_enter(&buf_pool->zip_free_mutex);
346 - if (buf_page_can_relocate(bpage)) {
347 + if (mutex && buf_page_can_relocate(bpage)) {
348 /* Relocate the compressed page. */
349 ullint usec = ut_time_us(NULL);
350 ut_a(bpage->zip.data == src);
351 @@ -409,10 +457,22 @@
352 buddy_stat->relocated_usec
353 += ut_time_us(NULL) - usec;
356 + if (!have_page_hash_mutex) {
357 + mutex_exit(&buf_pool->LRU_list_mutex);
358 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
364 + if (!have_page_hash_mutex) {
365 + mutex_exit(&buf_pool->LRU_list_mutex);
366 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
375 @@ -425,13 +485,15 @@
376 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
377 void* buf, /*!< in: block to be freed, must not be
378 pointed to by the buffer pool */
379 - ulint i) /*!< in: index of buf_pool->zip_free[],
380 + ulint i, /*!< in: index of buf_pool->zip_free[],
381 or BUF_BUDDY_SIZES */
382 + ibool have_page_hash_mutex)
387 - ut_ad(buf_pool_mutex_own(buf_pool));
388 + //ut_ad(buf_pool_mutex_own(buf_pool));
389 + ut_ad(mutex_own(&buf_pool->zip_free_mutex));
390 ut_ad(!mutex_own(&buf_pool->zip_mutex));
391 ut_ad(i <= BUF_BUDDY_SIZES);
392 ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
394 ((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE;
396 if (i == BUF_BUDDY_SIZES) {
397 - buf_buddy_block_free(buf_pool, buf);
398 + mutex_exit(&buf_pool->zip_free_mutex);
399 + buf_buddy_block_free(buf_pool, buf, have_page_hash_mutex);
400 + mutex_enter(&buf_pool->zip_free_mutex);
407 UNIV_MEM_ASSERT_W(bpage, BUF_BUDDY_LOW << i);
408 - bpage = UT_LIST_GET_NEXT(list, bpage);
409 + bpage = UT_LIST_GET_NEXT(zip_list, bpage);
412 #ifndef UNIV_DEBUG_VALGRIND
414 ut_d(BUF_BUDDY_LIST_VALIDATE(buf_pool, i));
416 /* The buddy is not free. Is there a free block of this size? */
417 - bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
418 + bpage = UT_LIST_GET_LAST(buf_pool->zip_free[i]);
423 buf_buddy_remove_from_free(buf_pool, bpage, i);
425 /* Try to relocate the buddy of buf to the free block. */
426 - if (buf_buddy_relocate(buf_pool, buddy, bpage, i)) {
427 + if (buf_buddy_relocate(buf_pool, buddy, bpage, i, have_page_hash_mutex)) {
429 buddy->state = BUF_BLOCK_ZIP_FREE;
431 --- a/storage/innobase/buf/buf0buf.c
432 +++ b/storage/innobase/buf/buf0buf.c
434 #ifdef UNIV_PFS_RWLOCK
435 /* Keys to register buffer block related rwlocks and mutexes with
436 performance schema */
437 +UNIV_INTERN mysql_pfs_key_t buf_pool_page_hash_key;
438 UNIV_INTERN mysql_pfs_key_t buf_block_lock_key;
439 # ifdef UNIV_SYNC_DEBUG
440 UNIV_INTERN mysql_pfs_key_t buf_block_debug_latch_key;
442 UNIV_INTERN mysql_pfs_key_t buffer_block_mutex_key;
443 UNIV_INTERN mysql_pfs_key_t buf_pool_mutex_key;
444 UNIV_INTERN mysql_pfs_key_t buf_pool_zip_mutex_key;
445 +UNIV_INTERN mysql_pfs_key_t buf_pool_LRU_list_mutex_key;
446 +UNIV_INTERN mysql_pfs_key_t buf_pool_free_list_mutex_key;
447 +UNIV_INTERN mysql_pfs_key_t buf_pool_zip_free_mutex_key;
448 +UNIV_INTERN mysql_pfs_key_t buf_pool_zip_hash_mutex_key;
449 UNIV_INTERN mysql_pfs_key_t flush_list_mutex_key;
450 #endif /* UNIV_PFS_MUTEX */
453 block->page.in_zip_hash = FALSE;
454 block->page.in_flush_list = FALSE;
455 block->page.in_free_list = FALSE;
456 - block->in_unzip_LRU_list = FALSE;
457 #endif /* UNIV_DEBUG */
458 + block->page.flush_list.prev = NULL;
459 + block->page.flush_list.next = NULL;
460 + block->page.zip_list.prev = NULL;
461 + block->page.zip_list.next = NULL;
462 block->page.in_LRU_list = FALSE;
463 + block->in_unzip_LRU_list = FALSE;
464 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
465 block->n_pointers = 0;
466 #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
468 memset(block->frame, '\0', UNIV_PAGE_SIZE);
470 /* Add the block to the free list */
471 - UT_LIST_ADD_LAST(list, buf_pool->free, (&block->page));
472 + mutex_enter(&buf_pool->free_list_mutex);
473 + UT_LIST_ADD_LAST(free, buf_pool->free, (&block->page));
475 ut_d(block->page.in_free_list = TRUE);
476 + mutex_exit(&buf_pool->free_list_mutex);
477 ut_ad(buf_pool_from_block(block) == buf_pool);
480 @@ -1039,7 +1050,8 @@
481 buf_chunk_t* chunk = buf_pool->chunks;
484 - ut_ad(buf_pool_mutex_own(buf_pool));
485 + //ut_ad(buf_pool_mutex_own(buf_pool));
486 + ut_ad(mutex_own(&buf_pool->zip_free_mutex));
487 for (n = buf_pool->n_chunks; n--; chunk++) {
489 buf_block_t* block = buf_chunk_contains_zip(chunk, data);
490 @@ -1145,9 +1157,21 @@
491 ------------------------------- */
492 mutex_create(buf_pool_mutex_key,
493 &buf_pool->mutex, SYNC_BUF_POOL);
494 + mutex_create(buf_pool_LRU_list_mutex_key,
495 + &buf_pool->LRU_list_mutex, SYNC_BUF_LRU_LIST);
496 + rw_lock_create(buf_pool_page_hash_key,
497 + &buf_pool->page_hash_latch, SYNC_BUF_PAGE_HASH);
498 + mutex_create(buf_pool_free_list_mutex_key,
499 + &buf_pool->free_list_mutex, SYNC_BUF_FREE_LIST);
500 + mutex_create(buf_pool_zip_free_mutex_key,
501 + &buf_pool->zip_free_mutex, SYNC_BUF_ZIP_FREE);
502 + mutex_create(buf_pool_zip_hash_mutex_key,
503 + &buf_pool->zip_hash_mutex, SYNC_BUF_ZIP_HASH);
504 mutex_create(buf_pool_zip_mutex_key,
505 &buf_pool->zip_mutex, SYNC_BUF_BLOCK);
507 + mutex_enter(&buf_pool->LRU_list_mutex);
508 + rw_lock_x_lock(&buf_pool->page_hash_latch);
509 buf_pool_mutex_enter(buf_pool);
511 if (buf_pool_size > 0) {
512 @@ -1160,6 +1184,8 @@
516 + mutex_exit(&buf_pool->LRU_list_mutex);
517 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
518 buf_pool_mutex_exit(buf_pool);
521 @@ -1190,6 +1216,8 @@
523 /* All fields are initialized by mem_zalloc(). */
525 + mutex_exit(&buf_pool->LRU_list_mutex);
526 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
527 buf_pool_mutex_exit(buf_pool);
530 @@ -1402,7 +1430,11 @@
532 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
534 - ut_ad(buf_pool_mutex_own(buf_pool));
535 + //ut_ad(buf_pool_mutex_own(buf_pool));
536 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
537 +#ifdef UNIV_SYNC_DEBUG
538 + ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX));
540 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
541 ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
542 ut_a(bpage->buf_fix_count == 0);
543 @@ -1513,21 +1545,32 @@
546 buf_pool_t* buf_pool = buf_pool_get(space, offset);
547 + mutex_t* block_mutex;
549 - ut_ad(buf_pool_mutex_own(buf_pool));
550 + //ut_ad(buf_pool_mutex_own(buf_pool));
552 + rw_lock_x_lock(&buf_pool->page_hash_latch);
553 bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
555 + block_mutex = buf_page_get_mutex_enter(bpage);
559 if (UNIV_LIKELY_NULL(bpage)) {
560 if (!buf_pool_watch_is_sentinel(buf_pool, bpage)) {
561 /* The page was loaded meanwhile. */
562 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
565 /* Add to an existing watch. */
566 bpage->buf_fix_count++;
567 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
568 + mutex_exit(block_mutex);
572 + /* buf_pool->watch is protected by zip_mutex for now */
573 + mutex_enter(&buf_pool->zip_mutex);
574 for (i = 0; i < BUF_POOL_WATCH_SIZE; i++) {
575 bpage = &buf_pool->watch[i];
577 @@ -1551,10 +1594,12 @@
578 bpage->space = space;
579 bpage->offset = offset;
580 bpage->buf_fix_count = 1;
582 + bpage->buf_pool_index = buf_pool_index(buf_pool);
583 ut_d(bpage->in_page_hash = TRUE);
584 HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
586 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
587 + mutex_exit(&buf_pool->zip_mutex);
589 case BUF_BLOCK_ZIP_PAGE:
590 ut_ad(bpage->in_page_hash);
591 @@ -1572,6 +1617,8 @@
594 /* Fix compiler warning */
595 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
596 + mutex_exit(&buf_pool->zip_mutex);
600 @@ -1589,7 +1636,11 @@
602 buf_page_t* watch) /*!< in/out: sentinel for watch */
604 - ut_ad(buf_pool_mutex_own(buf_pool));
605 + //ut_ad(buf_pool_mutex_own(buf_pool));
606 +#ifdef UNIV_SYNC_DEBUG
607 + ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX));
609 + ut_ad(mutex_own(&buf_pool->zip_mutex)); /* for now */
611 HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, watch);
612 ut_d(watch->in_page_hash = FALSE);
613 @@ -1611,28 +1662,31 @@
614 buf_pool_t* buf_pool = buf_pool_get(space, offset);
615 ulint fold = buf_page_address_fold(space, offset);
617 - buf_pool_mutex_enter(buf_pool);
618 + //buf_pool_mutex_enter(buf_pool);
619 + rw_lock_x_lock(&buf_pool->page_hash_latch);
620 bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
621 /* The page must exist because buf_pool_watch_set()
622 increments buf_fix_count. */
625 if (UNIV_UNLIKELY(!buf_pool_watch_is_sentinel(buf_pool, bpage))) {
626 - mutex_t* mutex = buf_page_get_mutex(bpage);
627 + mutex_t* mutex = buf_page_get_mutex_enter(bpage);
629 - mutex_enter(mutex);
630 ut_a(bpage->buf_fix_count > 0);
631 bpage->buf_fix_count--;
634 + mutex_enter(&buf_pool->zip_mutex);
635 ut_a(bpage->buf_fix_count > 0);
637 if (UNIV_LIKELY(!--bpage->buf_fix_count)) {
638 buf_pool_watch_remove(buf_pool, fold, bpage);
640 + mutex_exit(&buf_pool->zip_mutex);
643 - buf_pool_mutex_exit(buf_pool);
644 + //buf_pool_mutex_exit(buf_pool);
645 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
648 /****************************************************************//**
649 @@ -1652,14 +1706,16 @@
650 buf_pool_t* buf_pool = buf_pool_get(space, offset);
651 ulint fold = buf_page_address_fold(space, offset);
653 - buf_pool_mutex_enter(buf_pool);
654 + //buf_pool_mutex_enter(buf_pool);
655 + rw_lock_s_lock(&buf_pool->page_hash_latch);
657 bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
658 /* The page must exist because buf_pool_watch_set()
659 increments buf_fix_count. */
661 ret = !buf_pool_watch_is_sentinel(buf_pool, bpage);
662 - buf_pool_mutex_exit(buf_pool);
663 + //buf_pool_mutex_exit(buf_pool);
664 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
668 @@ -1676,13 +1732,15 @@
670 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
672 - buf_pool_mutex_enter(buf_pool);
673 + //buf_pool_mutex_enter(buf_pool);
674 + mutex_enter(&buf_pool->LRU_list_mutex);
676 ut_a(buf_page_in_file(bpage));
678 buf_LRU_make_block_young(bpage);
680 - buf_pool_mutex_exit(buf_pool);
681 + //buf_pool_mutex_exit(buf_pool);
682 + mutex_exit(&buf_pool->LRU_list_mutex);
685 /********************************************************************//**
686 @@ -1706,14 +1764,20 @@
687 ut_a(buf_page_in_file(bpage));
689 if (buf_page_peek_if_too_old(bpage)) {
690 - buf_pool_mutex_enter(buf_pool);
691 + //buf_pool_mutex_enter(buf_pool);
692 + mutex_enter(&buf_pool->LRU_list_mutex);
693 buf_LRU_make_block_young(bpage);
694 - buf_pool_mutex_exit(buf_pool);
695 + //buf_pool_mutex_exit(buf_pool);
696 + mutex_exit(&buf_pool->LRU_list_mutex);
697 } else if (!access_time) {
698 ulint time_ms = ut_time_ms();
699 - buf_pool_mutex_enter(buf_pool);
700 + mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
701 + //buf_pool_mutex_enter(buf_pool);
703 buf_page_set_accessed(bpage, time_ms);
704 - buf_pool_mutex_exit(buf_pool);
705 + mutex_exit(block_mutex);
707 + //buf_pool_mutex_exit(buf_pool);
711 @@ -1730,7 +1794,8 @@
713 buf_pool_t* buf_pool = buf_pool_get(space, offset);
715 - buf_pool_mutex_enter(buf_pool);
716 + //buf_pool_mutex_enter(buf_pool);
717 + rw_lock_s_lock(&buf_pool->page_hash_latch);
719 block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset);
721 @@ -1739,7 +1804,8 @@
722 block->check_index_page_at_flush = FALSE;
725 - buf_pool_mutex_exit(buf_pool);
726 + //buf_pool_mutex_exit(buf_pool);
727 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
730 /********************************************************************//**
731 @@ -1758,7 +1824,8 @@
733 buf_pool_t* buf_pool = buf_pool_get(space, offset);
735 - buf_pool_mutex_enter(buf_pool);
736 + //buf_pool_mutex_enter(buf_pool);
737 + rw_lock_s_lock(&buf_pool->page_hash_latch);
739 block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset);
741 @@ -1769,7 +1836,8 @@
742 is_hashed = block->is_hashed;
745 - buf_pool_mutex_exit(buf_pool);
746 + //buf_pool_mutex_exit(buf_pool);
747 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
751 @@ -1791,7 +1859,8 @@
753 buf_pool_t* buf_pool = buf_pool_get(space, offset);
755 - buf_pool_mutex_enter(buf_pool);
756 + //buf_pool_mutex_enter(buf_pool);
757 + rw_lock_s_lock(&buf_pool->page_hash_latch);
759 bpage = buf_page_hash_get(buf_pool, space, offset);
761 @@ -1802,7 +1871,8 @@
762 bpage->file_page_was_freed = TRUE;
765 - buf_pool_mutex_exit(buf_pool);
766 + //buf_pool_mutex_exit(buf_pool);
767 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
771 @@ -1823,7 +1893,8 @@
773 buf_pool_t* buf_pool = buf_pool_get(space, offset);
775 - buf_pool_mutex_enter(buf_pool);
776 + //buf_pool_mutex_enter(buf_pool);
777 + rw_lock_s_lock(&buf_pool->page_hash_latch);
779 bpage = buf_page_hash_get(buf_pool, space, offset);
781 @@ -1832,7 +1903,8 @@
782 bpage->file_page_was_freed = FALSE;
785 - buf_pool_mutex_exit(buf_pool);
786 + //buf_pool_mutex_exit(buf_pool);
787 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
791 @@ -1864,8 +1936,9 @@
792 buf_pool->stat.n_page_gets++;
795 - buf_pool_mutex_enter(buf_pool);
796 + //buf_pool_mutex_enter(buf_pool);
798 + rw_lock_s_lock(&buf_pool->page_hash_latch);
799 bpage = buf_page_hash_get(buf_pool, space, offset);
801 ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
802 @@ -1874,7 +1947,8 @@
804 /* Page not in buf_pool: needs to be read from file */
806 - buf_pool_mutex_exit(buf_pool);
807 + //buf_pool_mutex_exit(buf_pool);
808 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
810 buf_read_page(space, zip_size, offset);
812 @@ -1886,10 +1960,15 @@
813 if (UNIV_UNLIKELY(!bpage->zip.data)) {
814 /* There is no compressed page. */
816 - buf_pool_mutex_exit(buf_pool);
817 + //buf_pool_mutex_exit(buf_pool);
818 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
822 + block_mutex = buf_page_get_mutex_enter(bpage);
824 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
826 ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
828 switch (buf_page_get_state(bpage)) {
829 @@ -1898,24 +1977,43 @@
830 case BUF_BLOCK_MEMORY:
831 case BUF_BLOCK_REMOVE_HASH:
832 case BUF_BLOCK_ZIP_FREE:
834 + mutex_exit(block_mutex);
836 case BUF_BLOCK_ZIP_PAGE:
837 case BUF_BLOCK_ZIP_DIRTY:
838 - block_mutex = &buf_pool->zip_mutex;
839 - mutex_enter(block_mutex);
840 + ut_a(block_mutex == &buf_pool->zip_mutex);
841 bpage->buf_fix_count++;
843 case BUF_BLOCK_FILE_PAGE:
844 - block_mutex = &((buf_block_t*) bpage)->mutex;
845 + ut_a(block_mutex == &((buf_block_t*) bpage)->mutex);
847 + /* release mutex to obey to latch-order */
848 + mutex_exit(block_mutex);
850 + /* get LRU_list_mutex for buf_LRU_free_block() */
851 + mutex_enter(&buf_pool->LRU_list_mutex);
852 mutex_enter(block_mutex);
854 - /* Discard the uncompressed page frame if possible. */
855 - if (buf_LRU_free_block(bpage, FALSE)) {
856 + if (UNIV_UNLIKELY(bpage->space != space
857 + || bpage->offset != offset
858 + || !bpage->in_LRU_list
859 + || !bpage->zip.data)) {
860 + /* someone should interrupt, retry */
861 + mutex_exit(&buf_pool->LRU_list_mutex);
862 + mutex_exit(block_mutex);
866 + /* Discard the uncompressed page frame if possible. */
867 + if (buf_LRU_free_block(bpage, FALSE, TRUE)) {
868 + mutex_exit(&buf_pool->LRU_list_mutex);
869 mutex_exit(block_mutex);
873 + mutex_exit(&buf_pool->LRU_list_mutex);
875 buf_block_buf_fix_inc((buf_block_t*) bpage,
878 @@ -1928,7 +2026,7 @@
879 must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
880 access_time = buf_page_is_accessed(bpage);
882 - buf_pool_mutex_exit(buf_pool);
883 + //buf_pool_mutex_exit(buf_pool);
885 mutex_exit(block_mutex);
887 @@ -2240,7 +2338,7 @@
888 const buf_block_t* block) /*!< in: pointer to block,
891 - ut_ad(buf_pool_mutex_own(buf_pool));
892 + //ut_ad(buf_pool_mutex_own(buf_pool));
894 if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
895 /* The pointer should be aligned. */
896 @@ -2276,6 +2374,7 @@
900 + mutex_t* block_mutex = NULL;
901 buf_pool_t* buf_pool = buf_pool_get(space, offset);
904 @@ -2309,18 +2408,24 @@
905 fold = buf_page_address_fold(space, offset);
908 - buf_pool_mutex_enter(buf_pool);
909 + //buf_pool_mutex_enter(buf_pool);
912 + block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
914 /* If the guess is a compressed page descriptor that
915 has been allocated by buf_page_alloc_descriptor(),
916 it may have been freed by buf_relocate(). */
918 - if (!buf_block_is_uncompressed(buf_pool, block)
919 + if (!block_mutex) {
920 + block = guess = NULL;
921 + } else if (!buf_block_is_uncompressed(buf_pool, block)
922 || offset != block->page.offset
923 || space != block->page.space
924 || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
926 + mutex_exit(block_mutex);
928 block = guess = NULL;
930 ut_ad(!block->page.in_zip_hash);
931 @@ -2329,12 +2434,19 @@
935 + rw_lock_s_lock(&buf_pool->page_hash_latch);
936 block = (buf_block_t*) buf_page_hash_get_low(
937 buf_pool, space, offset, fold);
939 + block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
942 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
946 if (block && buf_pool_watch_is_sentinel(buf_pool, &block->page)) {
947 + mutex_exit(block_mutex);
951 @@ -2346,12 +2458,14 @@
952 space, offset, fold);
954 if (UNIV_LIKELY_NULL(block)) {
956 + block_mutex = buf_page_get_mutex((buf_page_t*)block);
958 + ut_ad(mutex_own(block_mutex));
963 - buf_pool_mutex_exit(buf_pool);
964 + //buf_pool_mutex_exit(buf_pool);
966 if (mode == BUF_GET_IF_IN_POOL
967 || mode == BUF_PEEK_IF_IN_POOL
968 @@ -2404,7 +2518,8 @@
969 /* The page is being read to buffer pool,
970 but we cannot wait around for the read to
972 - buf_pool_mutex_exit(buf_pool);
973 + //buf_pool_mutex_exit(buf_pool);
974 + mutex_exit(block_mutex);
978 @@ -2414,38 +2529,49 @@
981 case BUF_BLOCK_FILE_PAGE:
982 + if (block_mutex == &buf_pool->zip_mutex) {
983 + /* it is wrong mutex... */
984 + mutex_exit(block_mutex);
989 case BUF_BLOCK_ZIP_PAGE:
990 case BUF_BLOCK_ZIP_DIRTY:
991 + ut_ad(block_mutex == &buf_pool->zip_mutex);
992 bpage = &block->page;
993 /* Protect bpage->buf_fix_count. */
994 - mutex_enter(&buf_pool->zip_mutex);
995 + //mutex_enter(&buf_pool->zip_mutex);
997 if (bpage->buf_fix_count
998 || buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
999 /* This condition often occurs when the buffer
1000 is not buffer-fixed, but I/O-fixed by
1001 buf_page_init_for_read(). */
1002 - mutex_exit(&buf_pool->zip_mutex);
1003 + //mutex_exit(&buf_pool->zip_mutex);
1005 /* The block is buffer-fixed or I/O-fixed.
1007 - buf_pool_mutex_exit(buf_pool);
1008 + //buf_pool_mutex_exit(buf_pool);
1009 + mutex_exit(block_mutex);
1010 os_thread_sleep(WAIT_FOR_READ);
1015 /* Allocate an uncompressed page. */
1016 - buf_pool_mutex_exit(buf_pool);
1017 - mutex_exit(&buf_pool->zip_mutex);
1018 + //buf_pool_mutex_exit(buf_pool);
1019 + //mutex_exit(&buf_pool->zip_mutex);
1020 + mutex_exit(block_mutex);
1022 block = buf_LRU_get_free_block(buf_pool);
1024 + block_mutex = &block->mutex;
1026 - buf_pool_mutex_enter(buf_pool);
1027 - mutex_enter(&block->mutex);
1028 + //buf_pool_mutex_enter(buf_pool);
1029 + mutex_enter(&buf_pool->LRU_list_mutex);
1030 + rw_lock_x_lock(&buf_pool->page_hash_latch);
1031 + mutex_enter(block_mutex);
1034 buf_page_t* hash_bpage;
1035 @@ -2458,35 +2584,47 @@
1036 while buf_pool->mutex was released.
1037 Free the block that was allocated. */
1039 - buf_LRU_block_free_non_file_page(block);
1040 - mutex_exit(&block->mutex);
1041 + buf_LRU_block_free_non_file_page(block, TRUE);
1042 + mutex_exit(block_mutex);
1044 block = (buf_block_t*) hash_bpage;
1046 + block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
1047 + ut_a(block_mutex);
1049 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1050 + mutex_exit(&buf_pool->LRU_list_mutex);
1055 + mutex_enter(&buf_pool->zip_mutex);
1058 (bpage->buf_fix_count
1059 || buf_page_get_io_fix(bpage) != BUF_IO_NONE)) {
1061 + mutex_exit(&buf_pool->zip_mutex);
1062 /* The block was buffer-fixed or I/O-fixed
1063 while buf_pool->mutex was not held by this thread.
1064 Free the block that was allocated and try again.
1065 This should be extremely unlikely. */
1067 - buf_LRU_block_free_non_file_page(block);
1068 - mutex_exit(&block->mutex);
1069 + buf_LRU_block_free_non_file_page(block, TRUE);
1070 + //mutex_exit(&block->mutex);
1072 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1073 + mutex_exit(&buf_pool->LRU_list_mutex);
1074 goto wait_until_unfixed;
1077 /* Move the compressed page from bpage to block,
1078 and uncompress it. */
1080 - mutex_enter(&buf_pool->zip_mutex);
1082 buf_relocate(bpage, &block->page);
1084 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1086 buf_block_init_low(block);
1087 block->lock_hash_val = lock_rec_hash(space, offset);
1089 @@ -2496,7 +2634,7 @@
1090 if (buf_page_get_state(&block->page)
1091 == BUF_BLOCK_ZIP_PAGE) {
1092 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1093 - UT_LIST_REMOVE(list, buf_pool->zip_clean,
1094 + UT_LIST_REMOVE(zip_list, buf_pool->zip_clean,
1096 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
1097 ut_ad(!block->page.in_flush_list);
1098 @@ -2514,18 +2652,23 @@
1099 /* Insert at the front of unzip_LRU list */
1100 buf_unzip_LRU_add_block(block, FALSE);
1102 + mutex_exit(&buf_pool->LRU_list_mutex);
1104 block->page.buf_fix_count = 1;
1105 buf_block_set_io_fix(block, BUF_IO_READ);
1106 rw_lock_x_lock_func(&block->lock, 0, file, line);
1108 UNIV_MEM_INVALID(bpage, sizeof *bpage);
1110 - mutex_exit(&block->mutex);
1111 + mutex_exit(block_mutex);
1112 mutex_exit(&buf_pool->zip_mutex);
1113 - buf_pool->n_pend_unzip++;
1115 + buf_pool_mutex_enter(buf_pool);
1116 + buf_pool->n_pend_unzip++;
1117 buf_pool_mutex_exit(buf_pool);
1119 + //buf_pool_mutex_exit(buf_pool);
1121 buf_page_free_descriptor(bpage);
1123 /* Decompress the page and apply buffered operations
1124 @@ -2539,12 +2682,15 @@
1127 /* Unfix and unlatch the block. */
1128 - buf_pool_mutex_enter(buf_pool);
1129 - mutex_enter(&block->mutex);
1130 + //buf_pool_mutex_enter(buf_pool);
1131 + block_mutex = &block->mutex;
1132 + mutex_enter(block_mutex);
1133 block->page.buf_fix_count--;
1134 buf_block_set_io_fix(block, BUF_IO_NONE);
1135 - mutex_exit(&block->mutex);
1137 + buf_pool_mutex_enter(buf_pool);
1138 buf_pool->n_pend_unzip--;
1139 + buf_pool_mutex_exit(buf_pool);
1140 rw_lock_x_unlock(&block->lock);
1143 @@ -2560,7 +2706,7 @@
1145 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1147 - mutex_enter(&block->mutex);
1148 + //mutex_enter(&block->mutex);
1149 #if UNIV_WORD_SIZE == 4
1150 /* On 32-bit systems, there is no padding in buf_page_t. On
1151 other systems, Valgrind could complain about uninitialized pad
1152 @@ -2573,8 +2719,8 @@
1153 /* Try to evict the block from the buffer pool, to use the
1154 insert buffer (change buffer) as much as possible. */
1156 - if (buf_LRU_free_block(&block->page, TRUE)) {
1157 - mutex_exit(&block->mutex);
1158 + if (buf_LRU_free_block(&block->page, TRUE, FALSE)) {
1159 + mutex_exit(block_mutex);
1160 if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
1161 /* Set the watch, as it would have
1162 been set if the page were not in the
1163 @@ -2583,6 +2729,9 @@
1164 space, offset, fold);
1166 if (UNIV_LIKELY_NULL(block)) {
1167 + block_mutex = buf_page_get_mutex((buf_page_t*)block);
1168 + ut_a(block_mutex);
1169 + ut_ad(mutex_own(block_mutex));
1171 /* The page entered the buffer
1172 pool for some reason. Try to
1173 @@ -2590,7 +2739,7 @@
1177 - buf_pool_mutex_exit(buf_pool);
1178 + //buf_pool_mutex_exit(buf_pool);
1180 "innodb_change_buffering_debug evict %u %u\n",
1181 (unsigned) space, (unsigned) offset);
1182 @@ -2612,13 +2761,14 @@
1183 ut_a(mode == BUF_GET_POSSIBLY_FREED
1184 || !block->page.file_page_was_freed);
1186 - mutex_exit(&block->mutex);
1187 + //mutex_exit(&block->mutex);
1189 /* Check if this is the first access to the page */
1191 access_time = buf_page_is_accessed(&block->page);
1193 - buf_pool_mutex_exit(buf_pool);
1194 + //buf_pool_mutex_exit(buf_pool);
1195 + mutex_exit(block_mutex);
1197 if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
1198 buf_page_set_accessed_make_young(&block->page, access_time);
1199 @@ -2851,9 +3001,11 @@
1200 buf_pool = buf_pool_from_block(block);
1202 if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
1203 - buf_pool_mutex_enter(buf_pool);
1204 + //buf_pool_mutex_enter(buf_pool);
1205 + mutex_enter(&buf_pool->LRU_list_mutex);
1206 buf_LRU_make_block_young(&block->page);
1207 - buf_pool_mutex_exit(buf_pool);
1208 + //buf_pool_mutex_exit(buf_pool);
1209 + mutex_exit(&buf_pool->LRU_list_mutex);
1210 } else if (!buf_page_is_accessed(&block->page)) {
1211 /* Above, we do a dirty read on purpose, to avoid
1212 mutex contention. The field buf_page_t::access_time
1213 @@ -2861,9 +3013,11 @@
1214 field must be protected by mutex, however. */
1215 ulint time_ms = ut_time_ms();
1217 - buf_pool_mutex_enter(buf_pool);
1218 + //buf_pool_mutex_enter(buf_pool);
1219 + mutex_enter(&block->mutex);
1220 buf_page_set_accessed(&block->page, time_ms);
1221 - buf_pool_mutex_exit(buf_pool);
1222 + //buf_pool_mutex_exit(buf_pool);
1223 + mutex_exit(&block->mutex);
1226 ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
1227 @@ -2930,18 +3084,21 @@
1229 ut_ad(mtr->state == MTR_ACTIVE);
1231 - buf_pool_mutex_enter(buf_pool);
1232 + //buf_pool_mutex_enter(buf_pool);
1233 + rw_lock_s_lock(&buf_pool->page_hash_latch);
1234 block = buf_block_hash_get(buf_pool, space_id, page_no);
1236 if (!block || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
1237 - buf_pool_mutex_exit(buf_pool);
1238 + //buf_pool_mutex_exit(buf_pool);
1239 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
1243 ut_ad(!buf_pool_watch_is_sentinel(buf_pool, &block->page));
1245 mutex_enter(&block->mutex);
1246 - buf_pool_mutex_exit(buf_pool);
1247 + //buf_pool_mutex_exit(buf_pool);
1248 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
1250 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1251 ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1252 @@ -3031,7 +3188,10 @@
1253 buf_page_t* hash_page;
1255 ut_ad(buf_pool == buf_pool_get(space, offset));
1256 - ut_ad(buf_pool_mutex_own(buf_pool));
1257 + //ut_ad(buf_pool_mutex_own(buf_pool));
1258 +#ifdef UNIV_SYNC_DEBUG
1259 + ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX));
1261 ut_ad(mutex_own(&(block->mutex)));
1262 ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
1264 @@ -3060,11 +3220,14 @@
1265 if (UNIV_LIKELY(!hash_page)) {
1266 } else if (buf_pool_watch_is_sentinel(buf_pool, hash_page)) {
1267 /* Preserve the reference count. */
1268 - ulint buf_fix_count = hash_page->buf_fix_count;
1269 + ulint buf_fix_count;
1271 + mutex_enter(&buf_pool->zip_mutex);
1272 + buf_fix_count = hash_page->buf_fix_count;
1273 ut_a(buf_fix_count > 0);
1274 block->page.buf_fix_count += buf_fix_count;
1275 buf_pool_watch_remove(buf_pool, fold, hash_page);
1276 + mutex_exit(&buf_pool->zip_mutex);
1279 "InnoDB: Error: page %lu %lu already found"
1280 @@ -3074,7 +3237,8 @@
1281 (const void*) hash_page, (const void*) block);
1282 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1283 mutex_exit(&block->mutex);
1284 - buf_pool_mutex_exit(buf_pool);
1285 + //buf_pool_mutex_exit(buf_pool);
1286 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1290 @@ -3157,7 +3321,9 @@
1292 fold = buf_page_address_fold(space, offset);
1294 - buf_pool_mutex_enter(buf_pool);
1295 + //buf_pool_mutex_enter(buf_pool);
1296 + mutex_enter(&buf_pool->LRU_list_mutex);
1297 + rw_lock_x_lock(&buf_pool->page_hash_latch);
1299 watch_page = buf_page_hash_get_low(buf_pool, space, offset, fold);
1300 if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) {
1301 @@ -3166,9 +3332,15 @@
1304 mutex_enter(&block->mutex);
1305 - buf_LRU_block_free_non_file_page(block);
1306 + mutex_exit(&buf_pool->LRU_list_mutex);
1307 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1308 + buf_LRU_block_free_non_file_page(block, FALSE);
1309 mutex_exit(&block->mutex);
1312 + mutex_exit(&buf_pool->LRU_list_mutex);
1313 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1318 @@ -3191,6 +3363,8 @@
1320 buf_page_init(buf_pool, space, offset, fold, block);
1322 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1324 /* The block must be put to the LRU list, to the old blocks */
1325 buf_LRU_add_block(bpage, TRUE/* to old blocks */);
1327 @@ -3218,7 +3392,7 @@
1328 been added to buf_pool->LRU and
1329 buf_pool->page_hash. */
1330 mutex_exit(&block->mutex);
1331 - data = buf_buddy_alloc(buf_pool, zip_size, &lru);
1332 + data = buf_buddy_alloc(buf_pool, zip_size, &lru, FALSE);
1333 mutex_enter(&block->mutex);
1334 block->page.zip.data = data;
1336 @@ -3231,13 +3405,14 @@
1337 buf_unzip_LRU_add_block(block, TRUE);
1340 + mutex_exit(&buf_pool->LRU_list_mutex);
1341 mutex_exit(&block->mutex);
1343 /* The compressed page must be allocated before the
1344 control block (bpage), in order to avoid the
1345 invocation of buf_buddy_relocate_block() on
1346 uninitialized data. */
1347 - data = buf_buddy_alloc(buf_pool, zip_size, &lru);
1348 + data = buf_buddy_alloc(buf_pool, zip_size, &lru, TRUE);
1350 /* If buf_buddy_alloc() allocated storage from the LRU list,
1351 it released and reacquired buf_pool->mutex. Thus, we must
1352 @@ -3253,7 +3428,10 @@
1354 /* The block was added by some other thread. */
1356 - buf_buddy_free(buf_pool, data, zip_size);
1357 + buf_buddy_free(buf_pool, data, zip_size, TRUE);
1359 + mutex_exit(&buf_pool->LRU_list_mutex);
1360 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1364 @@ -3301,20 +3479,26 @@
1365 HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold,
1368 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1370 /* The block must be put to the LRU list, to the old blocks */
1371 buf_LRU_add_block(bpage, TRUE/* to old blocks */);
1372 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1373 buf_LRU_insert_zip_clean(bpage);
1374 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
1376 + mutex_exit(&buf_pool->LRU_list_mutex);
1378 buf_page_set_io_fix(bpage, BUF_IO_READ);
1380 mutex_exit(&buf_pool->zip_mutex);
1383 + buf_pool_mutex_enter(buf_pool);
1384 buf_pool->n_pend_reads++;
1386 buf_pool_mutex_exit(buf_pool);
1388 + //buf_pool_mutex_exit(buf_pool);
1390 if (mode == BUF_READ_IBUF_PAGES_ONLY) {
1392 @@ -3356,7 +3540,9 @@
1394 fold = buf_page_address_fold(space, offset);
1396 - buf_pool_mutex_enter(buf_pool);
1397 + //buf_pool_mutex_enter(buf_pool);
1398 + mutex_enter(&buf_pool->LRU_list_mutex);
1399 + rw_lock_x_lock(&buf_pool->page_hash_latch);
1401 block = (buf_block_t*) buf_page_hash_get_low(
1402 buf_pool, space, offset, fold);
1403 @@ -3372,7 +3558,9 @@
1404 #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
1406 /* Page can be found in buf_pool */
1407 - buf_pool_mutex_exit(buf_pool);
1408 + //buf_pool_mutex_exit(buf_pool);
1409 + mutex_exit(&buf_pool->LRU_list_mutex);
1410 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1412 buf_block_free(free_block);
1414 @@ -3394,6 +3582,7 @@
1415 mutex_enter(&block->mutex);
1417 buf_page_init(buf_pool, space, offset, fold, block);
1418 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1420 /* The block must be put to the LRU list */
1421 buf_LRU_add_block(&block->page, FALSE);
1422 @@ -3420,7 +3609,7 @@
1423 the reacquisition of buf_pool->mutex. We also must
1424 defer this operation until after the block descriptor
1425 has been added to buf_pool->LRU and buf_pool->page_hash. */
1426 - data = buf_buddy_alloc(buf_pool, zip_size, &lru);
1427 + data = buf_buddy_alloc(buf_pool, zip_size, &lru, FALSE);
1428 mutex_enter(&block->mutex);
1429 block->page.zip.data = data;
1431 @@ -3438,7 +3627,8 @@
1433 buf_page_set_accessed(&block->page, time_ms);
1435 - buf_pool_mutex_exit(buf_pool);
1436 + //buf_pool_mutex_exit(buf_pool);
1437 + mutex_exit(&buf_pool->LRU_list_mutex);
1439 mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
1441 @@ -3493,7 +3683,9 @@
1444 /* First unfix and release lock on the bpage */
1445 - buf_pool_mutex_enter(buf_pool);
1446 + //buf_pool_mutex_enter(buf_pool);
1447 + mutex_enter(&buf_pool->LRU_list_mutex);
1448 + rw_lock_x_lock(&buf_pool->page_hash_latch);
1449 mutex_enter(buf_page_get_mutex(bpage));
1450 ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ);
1451 ut_ad(bpage->buf_fix_count == 0);
1452 @@ -3514,11 +3706,15 @@
1456 + buf_pool_mutex_enter(buf_pool);
1457 ut_ad(buf_pool->n_pend_reads > 0);
1458 buf_pool->n_pend_reads--;
1459 + buf_pool_mutex_exit(buf_pool);
1461 mutex_exit(buf_page_get_mutex(bpage));
1462 - buf_pool_mutex_exit(buf_pool);
1463 + //buf_pool_mutex_exit(buf_pool);
1464 + mutex_exit(&buf_pool->LRU_list_mutex);
1465 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1469 @@ -3536,6 +3732,8 @@
1470 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1471 const ibool uncompressed = (buf_page_get_state(bpage)
1472 == BUF_BLOCK_FILE_PAGE);
1473 + ibool have_LRU_mutex = FALSE;
1474 + mutex_t* block_mutex;
1476 ut_a(buf_page_in_file(bpage));
1478 @@ -3678,8 +3876,26 @@
1482 + if (io_type == BUF_IO_WRITE
1483 + && (buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY
1484 + || buf_page_get_flush_type(bpage) == BUF_FLUSH_LRU)) {
1485 + /* to keep consistency at buf_LRU_insert_zip_clean() */
1486 + have_LRU_mutex = TRUE; /* optimistic */
1489 + if (have_LRU_mutex)
1490 + mutex_enter(&buf_pool->LRU_list_mutex);
1491 + block_mutex = buf_page_get_mutex_enter(bpage);
1492 + ut_a(block_mutex);
1493 + if (io_type == BUF_IO_WRITE
1494 + && (buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY
1495 + || buf_page_get_flush_type(bpage) == BUF_FLUSH_LRU)
1496 + && !have_LRU_mutex) {
1497 + mutex_exit(block_mutex);
1498 + have_LRU_mutex = TRUE;
1501 buf_pool_mutex_enter(buf_pool);
1502 - mutex_enter(buf_page_get_mutex(bpage));
1504 #ifdef UNIV_IBUF_COUNT_DEBUG
1505 if (io_type == BUF_IO_WRITE || uncompressed) {
1506 @@ -3702,6 +3918,7 @@
1507 the x-latch to this OS thread: do not let this confuse you in
1510 + ut_a(!have_LRU_mutex);
1511 ut_ad(buf_pool->n_pend_reads > 0);
1512 buf_pool->n_pend_reads--;
1513 buf_pool->stat.n_pages_read++;
1514 @@ -3719,6 +3936,9 @@
1516 buf_flush_write_complete(bpage);
1518 + if (have_LRU_mutex)
1519 + mutex_exit(&buf_pool->LRU_list_mutex);
1522 rw_lock_s_unlock_gen(&((buf_block_t*) bpage)->lock,
1524 @@ -3741,8 +3961,8 @@
1526 #endif /* UNIV_DEBUG */
1528 - mutex_exit(buf_page_get_mutex(bpage));
1529 buf_pool_mutex_exit(buf_pool);
1530 + mutex_exit(block_mutex);
1533 /*********************************************************************//**
1534 @@ -3759,7 +3979,9 @@
1538 - buf_pool_mutex_enter(buf_pool);
1539 + //buf_pool_mutex_enter(buf_pool);
1540 + mutex_enter(&buf_pool->LRU_list_mutex);
1541 + rw_lock_x_lock(&buf_pool->page_hash_latch);
1543 chunk = buf_pool->chunks;
1545 @@ -3776,7 +3998,9 @@
1549 - buf_pool_mutex_exit(buf_pool);
1550 + //buf_pool_mutex_exit(buf_pool);
1551 + mutex_exit(&buf_pool->LRU_list_mutex);
1552 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1556 @@ -3824,7 +4048,8 @@
1557 freed = buf_LRU_search_and_free_block(buf_pool, 100);
1560 - buf_pool_mutex_enter(buf_pool);
1561 + //buf_pool_mutex_enter(buf_pool);
1562 + mutex_enter(&buf_pool->LRU_list_mutex);
1564 ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
1565 ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
1566 @@ -3837,7 +4062,8 @@
1567 memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
1568 buf_refresh_io_stats(buf_pool);
1570 - buf_pool_mutex_exit(buf_pool);
1571 + //buf_pool_mutex_exit(buf_pool);
1572 + mutex_exit(&buf_pool->LRU_list_mutex);
1575 /*********************************************************************//**
1576 @@ -3879,7 +4105,10 @@
1580 - buf_pool_mutex_enter(buf_pool);
1581 + //buf_pool_mutex_enter(buf_pool);
1582 + mutex_enter(&buf_pool->LRU_list_mutex);
1583 + rw_lock_x_lock(&buf_pool->page_hash_latch);
1584 + /* for keep the new latch order, it cannot validate correctly... */
1586 chunk = buf_pool->chunks;
1588 @@ -3974,7 +4203,7 @@
1589 /* Check clean compressed-only blocks. */
1591 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
1592 - b = UT_LIST_GET_NEXT(list, b)) {
1593 + b = UT_LIST_GET_NEXT(zip_list, b)) {
1594 ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
1595 switch (buf_page_get_io_fix(b)) {
1597 @@ -4005,7 +4234,7 @@
1599 buf_flush_list_mutex_enter(buf_pool);
1600 for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
1601 - b = UT_LIST_GET_NEXT(list, b)) {
1602 + b = UT_LIST_GET_NEXT(flush_list, b)) {
1603 ut_ad(b->in_flush_list);
1604 ut_a(b->oldest_modification);
1606 @@ -4064,6 +4293,8 @@
1609 ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru);
1610 + /* because of latching order with block->mutex, we cannot get needed mutexes before that */
1612 if (UT_LIST_GET_LEN(buf_pool->free) != n_free) {
1613 fprintf(stderr, "Free list len %lu, free blocks %lu\n",
1614 (ulong) UT_LIST_GET_LEN(buf_pool->free),
1615 @@ -4074,8 +4305,11 @@
1616 ut_a(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE] == n_single_flush);
1617 ut_a(buf_pool->n_flush[BUF_FLUSH_LIST] == n_list_flush);
1618 ut_a(buf_pool->n_flush[BUF_FLUSH_LRU] == n_lru_flush);
1621 - buf_pool_mutex_exit(buf_pool);
1622 + //buf_pool_mutex_exit(buf_pool);
1623 + mutex_exit(&buf_pool->LRU_list_mutex);
1624 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
1626 ut_a(buf_LRU_validate());
1627 ut_a(buf_flush_validate(buf_pool));
1628 @@ -4131,7 +4365,9 @@
1629 index_ids = mem_alloc(size * sizeof *index_ids);
1630 counts = mem_alloc(sizeof(ulint) * size);
1632 - buf_pool_mutex_enter(buf_pool);
1633 + //buf_pool_mutex_enter(buf_pool);
1634 + mutex_enter(&buf_pool->LRU_list_mutex);
1635 + mutex_enter(&buf_pool->free_list_mutex);
1636 buf_flush_list_mutex_enter(buf_pool);
1639 @@ -4200,7 +4436,9 @@
1643 - buf_pool_mutex_exit(buf_pool);
1644 + //buf_pool_mutex_exit(buf_pool);
1645 + mutex_exit(&buf_pool->LRU_list_mutex);
1646 + mutex_exit(&buf_pool->free_list_mutex);
1648 for (i = 0; i < n_found; i++) {
1649 index = dict_index_get_if_in_cache(index_ids[i]);
1650 @@ -4257,7 +4495,7 @@
1652 ulint fixed_pages_number = 0;
1654 - buf_pool_mutex_enter(buf_pool);
1655 + //buf_pool_mutex_enter(buf_pool);
1657 chunk = buf_pool->chunks;
1659 @@ -4291,7 +4529,7 @@
1660 /* Traverse the lists of clean and dirty compressed-only blocks. */
1662 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
1663 - b = UT_LIST_GET_NEXT(list, b)) {
1664 + b = UT_LIST_GET_NEXT(zip_list, b)) {
1665 ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
1666 ut_a(buf_page_get_io_fix(b) != BUF_IO_WRITE);
1668 @@ -4303,7 +4541,7 @@
1670 buf_flush_list_mutex_enter(buf_pool);
1671 for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
1672 - b = UT_LIST_GET_NEXT(list, b)) {
1673 + b = UT_LIST_GET_NEXT(flush_list, b)) {
1674 ut_ad(b->in_flush_list);
1676 switch (buf_page_get_state(b)) {
1677 @@ -4329,7 +4567,7 @@
1679 buf_flush_list_mutex_exit(buf_pool);
1680 mutex_exit(&buf_pool->zip_mutex);
1681 - buf_pool_mutex_exit(buf_pool);
1682 + //buf_pool_mutex_exit(buf_pool);
1684 return(fixed_pages_number);
1686 @@ -4487,6 +4725,8 @@
1687 /* Find appropriate pool_info to store stats for this buffer pool */
1688 pool_info = &all_pool_info[pool_id];
1690 + mutex_enter(&buf_pool->LRU_list_mutex);
1691 + mutex_enter(&buf_pool->free_list_mutex);
1692 buf_pool_mutex_enter(buf_pool);
1693 buf_flush_list_mutex_enter(buf_pool);
1695 @@ -4602,6 +4842,8 @@
1696 pool_info->unzip_cur = buf_LRU_stat_cur.unzip;
1698 buf_refresh_io_stats(buf_pool);
1699 + mutex_exit(&buf_pool->LRU_list_mutex);
1700 + mutex_exit(&buf_pool->free_list_mutex);
1701 buf_pool_mutex_exit(buf_pool);
1704 @@ -4846,11 +5088,13 @@
1708 - buf_pool_mutex_enter(buf_pool);
1709 + //buf_pool_mutex_enter(buf_pool);
1710 + mutex_enter(&buf_pool->free_list_mutex);
1712 len = UT_LIST_GET_LEN(buf_pool->free);
1714 - buf_pool_mutex_exit(buf_pool);
1715 + //buf_pool_mutex_exit(buf_pool);
1716 + mutex_exit(&buf_pool->free_list_mutex);
1720 --- a/storage/innobase/buf/buf0flu.c
1721 +++ b/storage/innobase/buf/buf0flu.c
1724 ut_d(block->page.in_flush_list = TRUE);
1725 block->page.oldest_modification = lsn;
1726 - UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page);
1727 + UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, &block->page);
1729 #ifdef UNIV_DEBUG_VALGRIND
1731 @@ -401,14 +401,14 @@
1732 > block->page.oldest_modification) {
1733 ut_ad(b->in_flush_list);
1735 - b = UT_LIST_GET_NEXT(list, b);
1736 + b = UT_LIST_GET_NEXT(flush_list, b);
1740 if (prev_b == NULL) {
1741 - UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page);
1742 + UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, &block->page);
1744 - UT_LIST_INSERT_AFTER(list, buf_pool->flush_list,
1745 + UT_LIST_INSERT_AFTER(flush_list, buf_pool->flush_list,
1746 prev_b, &block->page);
1750 //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1751 //ut_ad(buf_pool_mutex_own(buf_pool));
1753 - //ut_ad(mutex_own(buf_page_get_mutex(bpage)));
1754 + ut_ad(mutex_own(buf_page_get_mutex(bpage)));
1755 //ut_ad(bpage->in_LRU_list);
1757 if (UNIV_LIKELY(bpage->in_LRU_list && buf_page_in_file(bpage))) {
1758 @@ -470,14 +470,14 @@
1759 enum buf_flush flush_type)/*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
1762 - buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1763 - ut_ad(buf_pool_mutex_own(buf_pool));
1764 + //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1765 + //ut_ad(buf_pool_mutex_own(buf_pool));
1767 - ut_a(buf_page_in_file(bpage));
1768 + //ut_a(buf_page_in_file(bpage));
1769 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
1770 ut_ad(flush_type == BUF_FLUSH_LRU || BUF_FLUSH_LIST);
1772 - if (bpage->oldest_modification != 0
1773 + if (buf_page_in_file(bpage) && bpage->oldest_modification != 0
1774 && buf_page_get_io_fix(bpage) == BUF_IO_NONE) {
1775 ut_ad(bpage->in_flush_list);
1779 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1781 - ut_ad(buf_pool_mutex_own(buf_pool));
1782 + //ut_ad(buf_pool_mutex_own(buf_pool));
1783 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
1784 ut_ad(bpage->in_flush_list);
1786 @@ -526,13 +526,13 @@
1788 case BUF_BLOCK_ZIP_DIRTY:
1789 buf_page_set_state(bpage, BUF_BLOCK_ZIP_PAGE);
1790 - UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
1791 + UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
1792 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1793 buf_LRU_insert_zip_clean(bpage);
1794 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
1796 case BUF_BLOCK_FILE_PAGE:
1797 - UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
1798 + UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
1803 buf_page_t* prev_b = NULL;
1804 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1806 - ut_ad(buf_pool_mutex_own(buf_pool));
1807 + //ut_ad(buf_pool_mutex_own(buf_pool));
1808 /* Must reside in the same buffer pool. */
1809 ut_ad(buf_pool == buf_pool_from_bpage(dpage));
1811 @@ -605,18 +605,18 @@
1812 because we assert on in_flush_list in comparison function. */
1813 ut_d(bpage->in_flush_list = FALSE);
1815 - prev = UT_LIST_GET_PREV(list, bpage);
1816 - UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
1817 + prev = UT_LIST_GET_PREV(flush_list, bpage);
1818 + UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
1821 ut_ad(prev->in_flush_list);
1822 UT_LIST_INSERT_AFTER(
1825 buf_pool->flush_list,
1831 buf_pool->flush_list,
1834 @@ -1085,7 +1085,7 @@
1837 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1838 - ut_ad(!buf_pool_mutex_own(buf_pool));
1839 + //ut_ad(!buf_pool_mutex_own(buf_pool));
1842 #ifdef UNIV_LOG_DEBUG
1843 @@ -1099,7 +1099,8 @@
1844 io_fixed and oldest_modification != 0. Thus, it cannot be
1845 relocated in the buffer pool or removed from flush_list or
1847 - ut_ad(!buf_pool_mutex_own(buf_pool));
1848 + //ut_ad(!buf_pool_mutex_own(buf_pool));
1849 + ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));
1850 ut_ad(!buf_flush_list_mutex_own(buf_pool));
1851 ut_ad(!mutex_own(buf_page_get_mutex(bpage)));
1852 ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_WRITE);
1853 @@ -1179,7 +1180,7 @@
1854 buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
1855 buf_block_t* block) /*!< in/out: buffer control block */
1857 - ut_ad(buf_pool_mutex_own(buf_pool));
1858 + //ut_ad(buf_pool_mutex_own(buf_pool));
1859 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1860 ut_ad(mutex_own(&block->mutex));
1862 @@ -1187,8 +1188,11 @@
1866 + buf_pool_mutex_enter(buf_pool);
1868 if (buf_pool->n_flush[BUF_FLUSH_LRU] > 0
1869 || buf_pool->init_flush[BUF_FLUSH_LRU]) {
1870 + buf_pool_mutex_exit(buf_pool);
1871 /* There is already a flush batch of the same type running */
1874 @@ -1262,12 +1266,18 @@
1875 ibool is_uncompressed;
1877 ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
1878 - ut_ad(buf_pool_mutex_own(buf_pool));
1879 + //ut_ad(buf_pool_mutex_own(buf_pool));
1880 +#ifdef UNIV_SYNC_DEBUG
1881 + ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_SHARED));
1883 ut_ad(buf_page_in_file(bpage));
1885 block_mutex = buf_page_get_mutex(bpage);
1886 ut_ad(mutex_own(block_mutex));
1888 + buf_pool_mutex_enter(buf_pool);
1889 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
1891 ut_ad(buf_flush_ready_for_flush(bpage, flush_type));
1893 buf_page_set_io_fix(bpage, BUF_IO_WRITE);
1894 @@ -1429,14 +1439,16 @@
1896 buf_pool = buf_pool_get(space, i);
1898 - buf_pool_mutex_enter(buf_pool);
1899 + //buf_pool_mutex_enter(buf_pool);
1900 + rw_lock_s_lock(&buf_pool->page_hash_latch);
1902 /* We only want to flush pages from this buffer pool. */
1903 bpage = buf_page_hash_get(buf_pool, space, i);
1907 - buf_pool_mutex_exit(buf_pool);
1908 + //buf_pool_mutex_exit(buf_pool);
1909 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
1913 @@ -1448,11 +1460,9 @@
1914 if (flush_type != BUF_FLUSH_LRU
1916 || buf_page_is_old(bpage)) {
1917 - mutex_t* block_mutex = buf_page_get_mutex(bpage);
1918 + mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
1920 - mutex_enter(block_mutex);
1922 - if (buf_flush_ready_for_flush(bpage, flush_type)
1923 + if (block_mutex && buf_flush_ready_for_flush(bpage, flush_type)
1924 && (i == offset || !bpage->buf_fix_count)) {
1925 /* We only try to flush those
1926 neighbors != offset where the buf fix
1927 @@ -1468,11 +1478,12 @@
1928 ut_ad(!buf_pool_mutex_own(buf_pool));
1932 + } else if (block_mutex) {
1933 mutex_exit(block_mutex);
1936 - buf_pool_mutex_exit(buf_pool);
1937 + //buf_pool_mutex_exit(buf_pool);
1938 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
1942 @@ -1505,21 +1516,25 @@
1943 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1944 #endif /* UNIV_DEBUG */
1946 - ut_ad(buf_pool_mutex_own(buf_pool));
1947 + //ut_ad(buf_pool_mutex_own(buf_pool));
1948 + ut_ad(flush_type != BUF_FLUSH_LRU
1949 + || mutex_own(&buf_pool->LRU_list_mutex));
1951 - block_mutex = buf_page_get_mutex(bpage);
1952 - mutex_enter(block_mutex);
1953 + block_mutex = buf_page_get_mutex_enter(bpage);
1955 - ut_a(buf_page_in_file(bpage));
1956 + //ut_a(buf_page_in_file(bpage));
1958 - if (buf_flush_ready_for_flush(bpage, flush_type)) {
1959 + if (block_mutex && buf_flush_ready_for_flush(bpage, flush_type)) {
1962 buf_pool_t* buf_pool;
1964 buf_pool = buf_pool_from_bpage(bpage);
1966 - buf_pool_mutex_exit(buf_pool);
1967 + //buf_pool_mutex_exit(buf_pool);
1968 + if (flush_type == BUF_FLUSH_LRU) {
1969 + mutex_exit(&buf_pool->LRU_list_mutex);
1972 /* These fields are protected by both the
1973 buffer pool mutex and block mutex. */
1974 @@ -1535,13 +1550,18 @@
1978 - buf_pool_mutex_enter(buf_pool);
1979 + //buf_pool_mutex_enter(buf_pool);
1980 + if (flush_type == BUF_FLUSH_LRU) {
1981 + mutex_enter(&buf_pool->LRU_list_mutex);
1985 + } else if (block_mutex) {
1986 mutex_exit(block_mutex);
1989 - ut_ad(buf_pool_mutex_own(buf_pool));
1990 + //ut_ad(buf_pool_mutex_own(buf_pool));
1991 + ut_ad(flush_type != BUF_FLUSH_LRU
1992 + || mutex_own(&buf_pool->LRU_list_mutex));
1996 @@ -1562,7 +1582,8 @@
2000 - ut_ad(buf_pool_mutex_own(buf_pool));
2001 + //ut_ad(buf_pool_mutex_own(buf_pool));
2002 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2005 /* Start from the end of the list looking for a
2006 @@ -1584,7 +1605,8 @@
2007 should be flushed, we factor in this value. */
2008 buf_lru_flush_page_count += count;
2010 - ut_ad(buf_pool_mutex_own(buf_pool));
2011 + //ut_ad(buf_pool_mutex_own(buf_pool));
2012 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2016 @@ -1612,9 +1634,10 @@
2020 + buf_page_t* prev_bpage = NULL;
2023 - ut_ad(buf_pool_mutex_own(buf_pool));
2024 + //ut_ad(buf_pool_mutex_own(buf_pool));
2026 /* If we have flushed enough, leave the loop */
2028 @@ -1633,6 +1656,7 @@
2031 ut_a(bpage->oldest_modification > 0);
2032 + prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
2035 if (!bpage || bpage->oldest_modification >= lsn_limit) {
2036 @@ -1674,9 +1698,17 @@
2040 - bpage = UT_LIST_GET_PREV(list, bpage);
2041 + bpage = UT_LIST_GET_PREV(flush_list, bpage);
2043 - ut_ad(!bpage || bpage->in_flush_list);
2044 + //ut_ad(!bpage || bpage->in_flush_list);
2045 + if (bpage != prev_bpage) {
2046 + /* the search might warp.. retrying */
2047 + buf_flush_list_mutex_exit(buf_pool);
2051 + prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
2054 buf_flush_list_mutex_exit(buf_pool);
2056 @@ -1685,7 +1717,7 @@
2058 } while (count < min_n && bpage != NULL && len > 0);
2060 - ut_ad(buf_pool_mutex_own(buf_pool));
2061 + //ut_ad(buf_pool_mutex_own(buf_pool));
2065 @@ -1724,13 +1756,15 @@
2066 || sync_thread_levels_empty_except_dict());
2067 #endif /* UNIV_SYNC_DEBUG */
2069 - buf_pool_mutex_enter(buf_pool);
2070 + //buf_pool_mutex_enter(buf_pool);
2072 /* Note: The buffer pool mutex is released and reacquired within
2073 the flush functions. */
2074 switch(flush_type) {
2076 + mutex_enter(&buf_pool->LRU_list_mutex);
2077 count = buf_flush_LRU_list_batch(buf_pool, min_n);
2078 + mutex_exit(&buf_pool->LRU_list_mutex);
2080 case BUF_FLUSH_LIST:
2081 count = buf_flush_flush_list_batch(buf_pool, min_n, lsn_limit);
2082 @@ -1739,7 +1773,7 @@
2086 - buf_pool_mutex_exit(buf_pool);
2087 + //buf_pool_mutex_exit(buf_pool);
2089 buf_flush_buffered_writes();
2091 @@ -1995,7 +2029,7 @@
2093 //buf_pool_mutex_enter(buf_pool);
2095 - buf_pool_mutex_enter(buf_pool);
2096 + mutex_enter(&buf_pool->LRU_list_mutex);
2098 n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
2100 @@ -2012,15 +2046,15 @@
2101 bpage = UT_LIST_GET_LAST(buf_pool->LRU);
2104 - block_mutex = buf_page_get_mutex(bpage);
2106 - mutex_enter(block_mutex);
2107 + block_mutex = buf_page_get_mutex_enter(bpage);
2109 - if (buf_flush_ready_for_replace(bpage)) {
2110 + if (block_mutex && buf_flush_ready_for_replace(bpage)) {
2114 - mutex_exit(block_mutex);
2115 + if (block_mutex) {
2116 + mutex_exit(block_mutex);
2121 @@ -2029,7 +2063,7 @@
2123 //buf_pool_mutex_exit(buf_pool);
2125 - buf_pool_mutex_exit(buf_pool);
2126 + mutex_exit(&buf_pool->LRU_list_mutex);
2128 if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN(buf_pool)) {
2130 @@ -2228,7 +2262,7 @@
2132 ut_ad(buf_flush_list_mutex_own(buf_pool));
2134 - UT_LIST_VALIDATE(list, buf_page_t, buf_pool->flush_list,
2135 + UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
2136 ut_ad(ut_list_node_313->in_flush_list));
2138 bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
2139 @@ -2268,7 +2302,7 @@
2140 rnode = rbt_next(buf_pool->flush_rbt, rnode);
2143 - bpage = UT_LIST_GET_NEXT(list, bpage);
2144 + bpage = UT_LIST_GET_NEXT(flush_list, bpage);
2146 ut_a(!bpage || om >= bpage->oldest_modification);
2148 --- a/storage/innobase/buf/buf0lru.c
2149 +++ b/storage/innobase/buf/buf0lru.c
2152 buf_LRU_block_free_hashed_page(
2153 /*===========================*/
2154 - buf_block_t* block); /*!< in: block, must contain a file page and
2155 + buf_block_t* block, /*!< in: block, must contain a file page and
2156 be in a state where it can be freed */
2157 + ibool have_page_hash_mutex);
2159 /******************************************************************//**
2160 Determines if the unzip_LRU list should be used for evicting a victim
2161 @@ -154,15 +155,20 @@
2163 buf_LRU_evict_from_unzip_LRU(
2164 /*=========================*/
2165 - buf_pool_t* buf_pool)
2166 + buf_pool_t* buf_pool,
2167 + ibool have_LRU_mutex)
2172 - ut_ad(buf_pool_mutex_own(buf_pool));
2173 + //ut_ad(buf_pool_mutex_own(buf_pool));
2175 + if (!have_LRU_mutex)
2176 + mutex_enter(&buf_pool->LRU_list_mutex);
2177 /* If the unzip_LRU list is empty, we can only use the LRU. */
2178 if (UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0) {
2179 + if (!have_LRU_mutex)
2180 + mutex_exit(&buf_pool->LRU_list_mutex);
2184 @@ -171,14 +177,20 @@
2185 decompressed pages in the buffer pool. */
2186 if (UT_LIST_GET_LEN(buf_pool->unzip_LRU)
2187 <= UT_LIST_GET_LEN(buf_pool->LRU) / 10) {
2188 + if (!have_LRU_mutex)
2189 + mutex_exit(&buf_pool->LRU_list_mutex);
2193 /* If eviction hasn't started yet, we assume by default
2194 that a workload is disk bound. */
2195 if (buf_pool->freed_page_clock == 0) {
2196 + if (!have_LRU_mutex)
2197 + mutex_exit(&buf_pool->LRU_list_mutex);
2200 + if (!have_LRU_mutex)
2201 + mutex_exit(&buf_pool->LRU_list_mutex);
2203 /* Calculate the average over past intervals, and add the values
2204 of the current interval. */
2205 @@ -246,18 +258,25 @@
2206 page_arr = ut_malloc(
2207 sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE);
2209 - buf_pool_mutex_enter(buf_pool);
2210 + //buf_pool_mutex_enter(buf_pool);
2211 + mutex_enter(&buf_pool->LRU_list_mutex);
2215 bpage = UT_LIST_GET_LAST(buf_pool->LRU);
2217 while (bpage != NULL) {
2218 + /* bpage->state,space,io_fix,buf_fix_count are protected by block_mutex at XtraDB */
2219 + mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
2220 buf_page_t* prev_bpage;
2223 prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
2225 + if (UNIV_UNLIKELY(!block_mutex)) {
2229 ut_a(buf_page_in_file(bpage));
2231 if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
2232 @@ -266,23 +285,27 @@
2233 /* Compressed pages are never hashed.
2234 Skip blocks of other tablespaces.
2235 Skip I/O-fixed blocks (to be dealt with later). */
2236 + mutex_exit(block_mutex);
2242 - mutex_enter(&((buf_block_t*) bpage)->mutex);
2243 + //mutex_enter(&((buf_block_t*) bpage)->mutex);
2244 is_fixed = bpage->buf_fix_count > 0
2245 || !((buf_block_t*) bpage)->is_hashed;
2246 - mutex_exit(&((buf_block_t*) bpage)->mutex);
2247 + //mutex_exit(&((buf_block_t*) bpage)->mutex);
2250 + mutex_exit(block_mutex);
2254 /* Store the page number so that we can drop the hash
2255 index in a batch later. */
2256 page_arr[num_entries] = bpage->offset;
2257 + mutex_exit(block_mutex);
2259 ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
2262 @@ -292,14 +315,16 @@
2264 /* Array full. We release the buf_pool->mutex to obey
2265 the latching order. */
2266 - buf_pool_mutex_exit(buf_pool);
2267 + //buf_pool_mutex_exit(buf_pool);
2268 + mutex_exit(&buf_pool->LRU_list_mutex);
2270 buf_LRU_drop_page_hash_batch(
2271 id, zip_size, page_arr, num_entries);
2275 - buf_pool_mutex_enter(buf_pool);
2276 + //buf_pool_mutex_enter(buf_pool);
2277 + mutex_enter(&buf_pool->LRU_list_mutex);
2279 /* Note that we released the buf_pool mutex above
2280 after reading the prev_bpage during processing of a
2281 @@ -317,13 +342,23 @@
2282 /* If, however, bpage has been removed from LRU list
2283 to the free list then we should restart the scan.
2284 bpage->state is protected by buf_pool mutex. */
2286 + /* obtain block_mutex again to avoid race condition of bpage->state */
2287 + block_mutex = buf_page_get_mutex_enter(bpage);
2288 + if (!block_mutex) {
2293 && buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
2294 + mutex_exit(block_mutex);
2297 + mutex_exit(block_mutex);
2300 - buf_pool_mutex_exit(buf_pool);
2301 + //buf_pool_mutex_exit(buf_pool);
2302 + mutex_exit(&buf_pool->LRU_list_mutex);
2304 /* Drop any remaining batch of search hashed pages. */
2305 buf_LRU_drop_page_hash_batch(id, zip_size, page_arr, num_entries);
2310 - buf_pool_mutex_enter(buf_pool);
2311 + //buf_pool_mutex_enter(buf_pool);
2312 + mutex_enter(&buf_pool->LRU_list_mutex);
2313 + rw_lock_x_lock(&buf_pool->page_hash_latch);
2317 @@ -375,8 +412,15 @@
2321 - block_mutex = buf_page_get_mutex(bpage);
2322 - mutex_enter(block_mutex);
2323 + block_mutex = buf_page_get_mutex_enter(bpage);
2325 + if (!block_mutex) {
2326 + /* It may be impossible case...
2327 + Something wrong, so will be scan_again */
2329 + all_freed = FALSE;
2333 if (bpage->buf_fix_count > 0) {
2339 - buf_pool_mutex_exit(buf_pool);
2340 + //buf_pool_mutex_exit(buf_pool);
2341 + mutex_exit(&buf_pool->LRU_list_mutex);
2342 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
2344 zip_size = buf_page_get_zip_size(bpage);
2345 page_no = buf_page_get_page_no(bpage);
2348 if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
2349 != BUF_BLOCK_ZIP_FREE) {
2350 - buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
2351 + buf_LRU_block_free_hashed_page((buf_block_t*) bpage, TRUE);
2352 mutex_exit(block_mutex);
2354 /* The block_mutex should have been released
2359 - buf_pool_mutex_exit(buf_pool);
2360 + //buf_pool_mutex_exit(buf_pool);
2361 + mutex_exit(&buf_pool->LRU_list_mutex);
2362 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
2365 os_thread_sleep(20000);
2368 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2370 - ut_ad(buf_pool_mutex_own(buf_pool));
2371 + //ut_ad(buf_pool_mutex_own(buf_pool));
2372 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2373 + ut_ad(mutex_own(&buf_pool->zip_mutex));
2374 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_PAGE);
2376 /* Find the first successor of bpage in the LRU list
2377 @@ -501,17 +551,17 @@
2380 b = UT_LIST_GET_NEXT(LRU, b);
2381 - } while (b && buf_page_get_state(b) != BUF_BLOCK_ZIP_PAGE);
2382 + } while (b && (buf_page_get_state(b) != BUF_BLOCK_ZIP_PAGE || !b->in_LRU_list));
2384 /* Insert bpage before b, i.e., after the predecessor of b. */
2386 - b = UT_LIST_GET_PREV(list, b);
2387 + b = UT_LIST_GET_PREV(zip_list, b);
2391 - UT_LIST_INSERT_AFTER(list, buf_pool->zip_clean, b, bpage);
2392 + UT_LIST_INSERT_AFTER(zip_list, buf_pool->zip_clean, b, bpage);
2394 - UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, bpage);
2395 + UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_clean, bpage);
2398 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
2399 @@ -525,18 +575,19 @@
2400 buf_LRU_free_from_unzip_LRU_list(
2401 /*=============================*/
2402 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
2403 - ulint n_iterations) /*!< in: how many times this has
2404 + ulint n_iterations, /*!< in: how many times this has
2405 been called repeatedly without
2406 result: a high value means that
2407 we should search farther; we will
2408 search n_iterations / 5 of the
2409 unzip_LRU list, or nothing if
2410 n_iterations >= 5 */
2411 + ibool have_LRU_mutex)
2416 - ut_ad(buf_pool_mutex_own(buf_pool));
2417 + //ut_ad(buf_pool_mutex_own(buf_pool));
2419 /* Theoratically it should be much easier to find a victim
2420 from unzip_LRU as we can choose even a dirty block (as we'll
2422 if we have done five iterations so far. */
2424 if (UNIV_UNLIKELY(n_iterations >= 5)
2425 - || !buf_LRU_evict_from_unzip_LRU(buf_pool)) {
2426 + || !buf_LRU_evict_from_unzip_LRU(buf_pool, have_LRU_mutex)) {
2430 @@ -554,18 +605,25 @@
2431 distance = 100 + (n_iterations
2432 * UT_LIST_GET_LEN(buf_pool->unzip_LRU)) / 5;
2435 for (block = UT_LIST_GET_LAST(buf_pool->unzip_LRU);
2436 UNIV_LIKELY(block != NULL) && UNIV_LIKELY(distance > 0);
2437 block = UT_LIST_GET_PREV(unzip_LRU, block), distance--) {
2441 + mutex_enter(&block->mutex);
2442 + if (!block->in_unzip_LRU_list || !block->page.in_LRU_list
2443 + || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
2444 + mutex_exit(&block->mutex);
2448 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
2449 ut_ad(block->in_unzip_LRU_list);
2450 ut_ad(block->page.in_LRU_list);
2452 - mutex_enter(&block->mutex);
2453 - freed = buf_LRU_free_block(&block->page, FALSE);
2454 + freed = buf_LRU_free_block(&block->page, FALSE, have_LRU_mutex);
2455 mutex_exit(&block->mutex);
2458 @@ -584,35 +642,46 @@
2459 buf_LRU_free_from_common_LRU_list(
2460 /*==============================*/
2461 buf_pool_t* buf_pool,
2462 - ulint n_iterations)
2463 + ulint n_iterations,
2464 /*!< in: how many times this has been called
2465 repeatedly without result: a high value means
2466 that we should search farther; if
2467 n_iterations < 10, then we search
2468 n_iterations / 10 * buf_pool->curr_size
2469 pages from the end of the LRU list */
2470 + ibool have_LRU_mutex)
2475 - ut_ad(buf_pool_mutex_own(buf_pool));
2476 + //ut_ad(buf_pool_mutex_own(buf_pool));
2478 distance = 100 + (n_iterations * buf_pool->curr_size) / 10;
2481 for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
2482 UNIV_LIKELY(bpage != NULL) && UNIV_LIKELY(distance > 0);
2483 bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
2487 - mutex_t* block_mutex = buf_page_get_mutex(bpage);
2488 + mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
2490 + if (!block_mutex) {
2494 + if (!bpage->in_LRU_list
2495 + || !buf_page_in_file(bpage)) {
2496 + mutex_exit(block_mutex);
2500 ut_ad(buf_page_in_file(bpage));
2501 ut_ad(bpage->in_LRU_list);
2503 - mutex_enter(block_mutex);
2504 accessed = buf_page_is_accessed(bpage);
2505 - freed = buf_LRU_free_block(bpage, TRUE);
2506 + freed = buf_LRU_free_block(bpage, TRUE, have_LRU_mutex);
2507 mutex_exit(block_mutex);
2510 @@ -649,16 +718,23 @@
2511 n_iterations / 5 of the unzip_LRU list. */
2513 ibool freed = FALSE;
2514 + ibool have_LRU_mutex = FALSE;
2516 - buf_pool_mutex_enter(buf_pool);
2517 + if (UT_LIST_GET_LEN(buf_pool->unzip_LRU))
2518 + have_LRU_mutex = TRUE;
2520 - freed = buf_LRU_free_from_unzip_LRU_list(buf_pool, n_iterations);
2521 + //buf_pool_mutex_enter(buf_pool);
2522 + if (have_LRU_mutex)
2523 + mutex_enter(&buf_pool->LRU_list_mutex);
2525 + freed = buf_LRU_free_from_unzip_LRU_list(buf_pool, n_iterations, have_LRU_mutex);
2528 freed = buf_LRU_free_from_common_LRU_list(
2529 - buf_pool, n_iterations);
2530 + buf_pool, n_iterations, have_LRU_mutex);
2533 + buf_pool_mutex_enter(buf_pool);
2535 buf_pool->LRU_flush_ended = 0;
2536 } else if (buf_pool->LRU_flush_ended > 0) {
2540 buf_pool_mutex_exit(buf_pool);
2541 + if (have_LRU_mutex)
2542 + mutex_exit(&buf_pool->LRU_list_mutex);
2548 buf_pool = buf_pool_from_array(i);
2550 - buf_pool_mutex_enter(buf_pool);
2551 + //buf_pool_mutex_enter(buf_pool);
2552 + mutex_enter(&buf_pool->LRU_list_mutex);
2553 + mutex_enter(&buf_pool->free_list_mutex);
2555 if (!recv_recovery_on
2556 && UT_LIST_GET_LEN(buf_pool->free)
2561 - buf_pool_mutex_exit(buf_pool);
2562 + //buf_pool_mutex_exit(buf_pool);
2563 + mutex_exit(&buf_pool->LRU_list_mutex);
2564 + mutex_exit(&buf_pool->free_list_mutex);
2568 @@ -754,9 +836,10 @@
2572 - ut_ad(buf_pool_mutex_own(buf_pool));
2573 + //ut_ad(buf_pool_mutex_own(buf_pool));
2575 - block = (buf_block_t*) UT_LIST_GET_FIRST(buf_pool->free);
2576 + mutex_enter(&buf_pool->free_list_mutex);
2577 + block = (buf_block_t*) UT_LIST_GET_LAST(buf_pool->free);
2582 ut_ad(!block->page.in_flush_list);
2583 ut_ad(!block->page.in_LRU_list);
2584 ut_a(!buf_page_in_file(&block->page));
2585 - UT_LIST_REMOVE(list, buf_pool->free, (&block->page));
2586 + UT_LIST_REMOVE(free, buf_pool->free, (&block->page));
2588 + mutex_exit(&buf_pool->free_list_mutex);
2590 mutex_enter(&block->mutex);
2593 ut_ad(buf_pool_from_block(block) == buf_pool);
2595 mutex_exit(&block->mutex);
2597 + mutex_exit(&buf_pool->free_list_mutex);
2602 ibool mon_value_was = FALSE;
2603 ibool started_monitor = FALSE;
2605 - buf_pool_mutex_enter(buf_pool);
2606 + //buf_pool_mutex_enter(buf_pool);
2608 if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
2609 + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->curr_size / 20) {
2612 /* If there is a block in the free list, take it */
2613 block = buf_LRU_get_free_only(buf_pool);
2614 - buf_pool_mutex_exit(buf_pool);
2615 + //buf_pool_mutex_exit(buf_pool);
2618 ut_ad(buf_pool_from_block(block) == buf_pool);
2619 @@ -965,7 +1052,8 @@
2622 ut_a(buf_pool->LRU_old);
2623 - ut_ad(buf_pool_mutex_own(buf_pool));
2624 + //ut_ad(buf_pool_mutex_own(buf_pool));
2625 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2626 ut_ad(buf_pool->LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
2627 ut_ad(buf_pool->LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
2628 #if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
2629 @@ -1031,7 +1119,8 @@
2633 - ut_ad(buf_pool_mutex_own(buf_pool));
2634 + //ut_ad(buf_pool_mutex_own(buf_pool));
2635 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2636 ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN);
2638 /* We first initialize all blocks in the LRU list as old and then use
2639 @@ -1066,13 +1155,14 @@
2642 ut_ad(buf_page_in_file(bpage));
2643 - ut_ad(buf_pool_mutex_own(buf_pool));
2644 + //ut_ad(buf_pool_mutex_own(buf_pool));
2645 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2647 if (buf_page_belongs_to_unzip_LRU(bpage)) {
2648 buf_block_t* block = (buf_block_t*) bpage;
2650 ut_ad(block->in_unzip_LRU_list);
2651 - ut_d(block->in_unzip_LRU_list = FALSE);
2652 + block->in_unzip_LRU_list = FALSE;
2654 UT_LIST_REMOVE(unzip_LRU, buf_pool->unzip_LRU, block);
2656 @@ -1090,7 +1180,8 @@
2660 - ut_ad(buf_pool_mutex_own(buf_pool));
2661 + //ut_ad(buf_pool_mutex_own(buf_pool));
2662 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2664 ut_a(buf_page_in_file(bpage));
2666 @@ -1167,12 +1258,13 @@
2670 - ut_ad(buf_pool_mutex_own(buf_pool));
2671 + //ut_ad(buf_pool_mutex_own(buf_pool));
2672 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2674 ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
2676 ut_ad(!block->in_unzip_LRU_list);
2677 - ut_d(block->in_unzip_LRU_list = TRUE);
2678 + block->in_unzip_LRU_list = TRUE;
2681 UT_LIST_ADD_LAST(unzip_LRU, buf_pool->unzip_LRU, block);
2682 @@ -1193,7 +1285,8 @@
2686 - ut_ad(buf_pool_mutex_own(buf_pool));
2687 + //ut_ad(buf_pool_mutex_own(buf_pool));
2688 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2690 ut_a(buf_page_in_file(bpage));
2692 @@ -1244,7 +1337,8 @@
2696 - ut_ad(buf_pool_mutex_own(buf_pool));
2697 + //ut_ad(buf_pool_mutex_own(buf_pool));
2698 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2700 ut_a(buf_page_in_file(bpage));
2701 ut_ad(!bpage->in_LRU_list);
2702 @@ -1323,7 +1417,8 @@
2704 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2706 - ut_ad(buf_pool_mutex_own(buf_pool));
2707 + //ut_ad(buf_pool_mutex_own(buf_pool));
2708 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2711 buf_pool->stat.n_pages_made_young++;
2712 @@ -1362,17 +1457,18 @@
2715 buf_page_t* bpage, /*!< in: block to be freed */
2716 - ibool zip) /*!< in: TRUE if should remove also the
2717 + ibool zip, /*!< in: TRUE if should remove also the
2718 compressed page of an uncompressed page */
2719 + ibool have_LRU_mutex)
2721 buf_page_t* b = NULL;
2722 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2723 mutex_t* block_mutex = buf_page_get_mutex(bpage);
2725 - ut_ad(buf_pool_mutex_own(buf_pool));
2726 + //ut_ad(buf_pool_mutex_own(buf_pool));
2727 ut_ad(mutex_own(block_mutex));
2728 ut_ad(buf_page_in_file(bpage));
2729 - ut_ad(bpage->in_LRU_list);
2730 + //ut_ad(bpage->in_LRU_list);
2731 ut_ad(!bpage->in_flush_list == !bpage->oldest_modification);
2732 #if UNIV_WORD_SIZE == 4
2733 /* On 32-bit systems, there is no padding in buf_page_t. On
2734 @@ -1381,7 +1477,7 @@
2735 UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
2738 - if (!buf_page_can_relocate(bpage)) {
2739 + if (!bpage->in_LRU_list || !block_mutex || !buf_page_can_relocate(bpage)) {
2741 /* Do not free buffer-fixed or I/O-fixed blocks. */
2743 @@ -1415,7 +1511,7 @@
2745 b = buf_page_alloc_descriptor();
2747 - memcpy(b, bpage, sizeof *b);
2748 + //memcpy(b, bpage, sizeof *b);
2752 @@ -1426,6 +1522,39 @@
2754 #endif /* UNIV_DEBUG */
2756 + /* not to break latch order, must re-enter block_mutex */
2757 + mutex_exit(block_mutex);
2759 + if (!have_LRU_mutex)
2760 + mutex_enter(&buf_pool->LRU_list_mutex); /* optimistic */
2761 + rw_lock_x_lock(&buf_pool->page_hash_latch);
2762 + mutex_enter(block_mutex);
2764 + /* recheck states of block */
2765 + if (!bpage->in_LRU_list || block_mutex != buf_page_get_mutex(bpage)
2766 + || !buf_page_can_relocate(bpage)) {
2769 + buf_buddy_free(buf_pool, b, sizeof *b, TRUE);
2771 + if (!have_LRU_mutex)
2772 + mutex_exit(&buf_pool->LRU_list_mutex);
2773 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
2775 + } else if (zip || !bpage->zip.data) {
2776 + if (bpage->oldest_modification)
2778 + } else if (bpage->oldest_modification) {
2779 + if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
2780 + ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY);
2786 + memcpy(b, bpage, sizeof *b);
2789 if (buf_LRU_block_remove_hashed_page(bpage, zip)
2790 != BUF_BLOCK_ZIP_FREE) {
2791 ut_a(bpage->buf_fix_count == 0);
2792 @@ -1442,6 +1571,10 @@
2796 + while (prev_b && !prev_b->in_LRU_list) {
2797 + prev_b = UT_LIST_GET_PREV(LRU, prev_b);
2800 b->state = b->oldest_modification
2801 ? BUF_BLOCK_ZIP_DIRTY
2802 : BUF_BLOCK_ZIP_PAGE;
2803 @@ -1517,6 +1650,7 @@
2804 buf_LRU_add_block_low(b, buf_page_is_old(b));
2807 + mutex_enter(&buf_pool->zip_mutex);
2808 if (b->state == BUF_BLOCK_ZIP_PAGE) {
2809 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
2810 buf_LRU_insert_zip_clean(b);
2811 @@ -1534,9 +1668,12 @@
2812 buf_pool->mutex and block_mutex. */
2814 b->io_fix = BUF_IO_READ;
2815 + mutex_exit(&buf_pool->zip_mutex);
2818 - buf_pool_mutex_exit(buf_pool);
2819 + //buf_pool_mutex_exit(buf_pool);
2820 + mutex_exit(&buf_pool->LRU_list_mutex);
2821 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
2822 mutex_exit(block_mutex);
2824 /* Remove possible adaptive hash index on the page.
2825 @@ -1568,7 +1705,9 @@
2826 : BUF_NO_CHECKSUM_MAGIC);
2829 - buf_pool_mutex_enter(buf_pool);
2830 + //buf_pool_mutex_enter(buf_pool);
2831 + if (have_LRU_mutex)
2832 + mutex_enter(&buf_pool->LRU_list_mutex);
2833 mutex_enter(block_mutex);
2836 @@ -1578,13 +1717,17 @@
2837 mutex_exit(&buf_pool->zip_mutex);
2840 - buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
2841 + buf_LRU_block_free_hashed_page((buf_block_t*) bpage, FALSE);
2843 /* The block_mutex should have been released by
2844 buf_LRU_block_remove_hashed_page() when it returns
2845 BUF_BLOCK_ZIP_FREE. */
2846 ut_ad(block_mutex == &buf_pool->zip_mutex);
2847 mutex_enter(block_mutex);
2849 + if (!have_LRU_mutex)
2850 + mutex_exit(&buf_pool->LRU_list_mutex);
2851 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
2855 @@ -1596,13 +1739,14 @@
2857 buf_LRU_block_free_non_file_page(
2858 /*=============================*/
2859 - buf_block_t* block) /*!< in: block, must not contain a file page */
2860 + buf_block_t* block, /*!< in: block, must not contain a file page */
2861 + ibool have_page_hash_mutex)
2864 buf_pool_t* buf_pool = buf_pool_from_block(block);
2867 - ut_ad(buf_pool_mutex_own(buf_pool));
2868 + //ut_ad(buf_pool_mutex_own(buf_pool));
2869 ut_ad(mutex_own(&block->mutex));
2871 switch (buf_block_get_state(block)) {
2872 @@ -1636,18 +1780,21 @@
2874 block->page.zip.data = NULL;
2875 mutex_exit(&block->mutex);
2876 - buf_pool_mutex_exit_forbid(buf_pool);
2877 + //buf_pool_mutex_exit_forbid(buf_pool);
2880 - buf_pool, data, page_zip_get_size(&block->page.zip));
2881 + buf_pool, data, page_zip_get_size(&block->page.zip),
2882 + have_page_hash_mutex);
2884 - buf_pool_mutex_exit_allow(buf_pool);
2885 + //buf_pool_mutex_exit_allow(buf_pool);
2886 mutex_enter(&block->mutex);
2887 page_zip_set_size(&block->page.zip, 0);
2890 - UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->page));
2891 + mutex_enter(&buf_pool->free_list_mutex);
2892 + UT_LIST_ADD_FIRST(free, buf_pool->free, (&block->page));
2893 ut_d(block->page.in_free_list = TRUE);
2894 + mutex_exit(&buf_pool->free_list_mutex);
2896 UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
2898 @@ -1677,7 +1824,11 @@
2899 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2902 - ut_ad(buf_pool_mutex_own(buf_pool));
2903 + //ut_ad(buf_pool_mutex_own(buf_pool));
2904 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
2905 +#ifdef UNIV_SYNC_DEBUG
2906 + ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX));
2908 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
2910 ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
2911 @@ -1785,7 +1936,9 @@
2913 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
2914 mutex_exit(buf_page_get_mutex(bpage));
2915 - buf_pool_mutex_exit(buf_pool);
2916 + //buf_pool_mutex_exit(buf_pool);
2917 + mutex_exit(&buf_pool->LRU_list_mutex);
2918 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
2922 @@ -1807,17 +1960,17 @@
2923 ut_a(buf_page_get_zip_size(bpage));
2925 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
2926 - UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
2927 + UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, bpage);
2928 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
2930 mutex_exit(&buf_pool->zip_mutex);
2931 - buf_pool_mutex_exit_forbid(buf_pool);
2932 + //buf_pool_mutex_exit_forbid(buf_pool);
2935 buf_pool, bpage->zip.data,
2936 - page_zip_get_size(&bpage->zip));
2937 + page_zip_get_size(&bpage->zip), TRUE);
2939 - buf_pool_mutex_exit_allow(buf_pool);
2940 + //buf_pool_mutex_exit_allow(buf_pool);
2941 buf_page_free_descriptor(bpage);
2942 return(BUF_BLOCK_ZIP_FREE);
2944 @@ -1839,13 +1992,13 @@
2945 ut_ad(!bpage->in_flush_list);
2946 ut_ad(!bpage->in_LRU_list);
2947 mutex_exit(&((buf_block_t*) bpage)->mutex);
2948 - buf_pool_mutex_exit_forbid(buf_pool);
2949 + //buf_pool_mutex_exit_forbid(buf_pool);
2953 - page_zip_get_size(&bpage->zip));
2954 + page_zip_get_size(&bpage->zip), TRUE);
2956 - buf_pool_mutex_exit_allow(buf_pool);
2957 + //buf_pool_mutex_exit_allow(buf_pool);
2958 mutex_enter(&((buf_block_t*) bpage)->mutex);
2959 page_zip_set_size(&bpage->zip, 0);
2961 @@ -1871,18 +2024,19 @@
2963 buf_LRU_block_free_hashed_page(
2964 /*===========================*/
2965 - buf_block_t* block) /*!< in: block, must contain a file page and
2966 + buf_block_t* block, /*!< in: block, must contain a file page and
2967 be in a state where it can be freed */
2968 + ibool have_page_hash_mutex)
2971 - buf_pool_t* buf_pool = buf_pool_from_block(block);
2972 - ut_ad(buf_pool_mutex_own(buf_pool));
2973 + //buf_pool_t* buf_pool = buf_pool_from_block(block);
2974 + //ut_ad(buf_pool_mutex_own(buf_pool));
2976 ut_ad(mutex_own(&block->mutex));
2978 buf_block_set_state(block, BUF_BLOCK_MEMORY);
2980 - buf_LRU_block_free_non_file_page(block);
2981 + buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
2984 /******************************************************************//**
2985 @@ -1897,7 +2051,7 @@
2987 if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
2988 != BUF_BLOCK_ZIP_FREE) {
2989 - buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
2990 + buf_LRU_block_free_hashed_page((buf_block_t*) bpage, TRUE);
2994 @@ -1925,7 +2079,8 @@
2998 - buf_pool_mutex_enter(buf_pool);
2999 + //buf_pool_mutex_enter(buf_pool);
3000 + mutex_enter(&buf_pool->LRU_list_mutex);
3002 if (ratio != buf_pool->LRU_old_ratio) {
3003 buf_pool->LRU_old_ratio = ratio;
3004 @@ -1937,7 +2092,8 @@
3008 - buf_pool_mutex_exit(buf_pool);
3009 + //buf_pool_mutex_exit(buf_pool);
3010 + mutex_exit(&buf_pool->LRU_list_mutex);
3012 buf_pool->LRU_old_ratio = ratio;
3014 @@ -2042,7 +2198,8 @@
3018 - buf_pool_mutex_enter(buf_pool);
3019 + //buf_pool_mutex_enter(buf_pool);
3020 + mutex_enter(&buf_pool->LRU_list_mutex);
3022 if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
3024 @@ -2103,16 +2260,22 @@
3026 ut_a(buf_pool->LRU_old_len == old_len);
3028 - UT_LIST_VALIDATE(list, buf_page_t, buf_pool->free,
3029 + mutex_exit(&buf_pool->LRU_list_mutex);
3030 + mutex_enter(&buf_pool->free_list_mutex);
3032 + UT_LIST_VALIDATE(free, buf_page_t, buf_pool->free,
3033 ut_ad(ut_list_node_313->in_free_list));
3035 for (bpage = UT_LIST_GET_FIRST(buf_pool->free);
3037 - bpage = UT_LIST_GET_NEXT(list, bpage)) {
3038 + bpage = UT_LIST_GET_NEXT(free, bpage)) {
3040 ut_a(buf_page_get_state(bpage) == BUF_BLOCK_NOT_USED);
3043 + mutex_exit(&buf_pool->free_list_mutex);
3044 + mutex_enter(&buf_pool->LRU_list_mutex);
3046 UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU,
3047 ut_ad(ut_list_node_313->in_unzip_LRU_list
3048 && ut_list_node_313->page.in_LRU_list));
3049 @@ -2126,7 +2289,8 @@
3050 ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
3053 - buf_pool_mutex_exit(buf_pool);
3054 + //buf_pool_mutex_exit(buf_pool);
3055 + mutex_exit(&buf_pool->LRU_list_mutex);
3058 /**********************************************************************//**
3059 @@ -2162,7 +2326,8 @@
3060 const buf_page_t* bpage;
3063 - buf_pool_mutex_enter(buf_pool);
3064 + //buf_pool_mutex_enter(buf_pool);
3065 + mutex_enter(&buf_pool->LRU_list_mutex);
3067 bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
3069 @@ -2219,7 +2384,8 @@
3070 bpage = UT_LIST_GET_NEXT(LRU, bpage);
3073 - buf_pool_mutex_exit(buf_pool);
3074 + //buf_pool_mutex_exit(buf_pool);
3075 + mutex_exit(&buf_pool->LRU_list_mutex);
3078 /**********************************************************************//**
3079 --- a/storage/innobase/buf/buf0rea.c
3080 +++ b/storage/innobase/buf/buf0rea.c
3085 + buf_pool_mutex_exit(buf_pool);
3087 /* Check that almost all pages in the area have been accessed; if
3088 offset == low, the accesses must be in a descending order, otherwise,
3093 + rw_lock_s_lock(&buf_pool->page_hash_latch);
3094 for (i = low; i < high; i++) {
3095 bpage = buf_page_hash_get(buf_pool, space, i);
3099 if (fail_count > threshold) {
3100 /* Too many failures: return */
3101 - buf_pool_mutex_exit(buf_pool);
3102 + //buf_pool_mutex_exit(buf_pool);
3103 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
3108 bpage = buf_page_hash_get(buf_pool, space, offset);
3110 if (bpage == NULL) {
3111 - buf_pool_mutex_exit(buf_pool);
3112 + //buf_pool_mutex_exit(buf_pool);
3113 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
3118 pred_offset = fil_page_get_prev(frame);
3119 succ_offset = fil_page_get_next(frame);
3121 - buf_pool_mutex_exit(buf_pool);
3122 + //buf_pool_mutex_exit(buf_pool);
3123 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
3125 if ((offset == low) && (succ_offset == offset + 1)) {
3127 --- a/storage/innobase/handler/ha_innodb.cc
3128 +++ b/storage/innobase/handler/ha_innodb.cc
3129 @@ -265,6 +265,10 @@
3130 # endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */
3131 {&buf_pool_mutex_key, "buf_pool_mutex", 0},
3132 {&buf_pool_zip_mutex_key, "buf_pool_zip_mutex", 0},
3133 + {&buf_pool_LRU_list_mutex_key, "buf_pool_LRU_list_mutex", 0},
3134 + {&buf_pool_free_list_mutex_key, "buf_pool_free_list_mutex", 0},
3135 + {&buf_pool_zip_free_mutex_key, "buf_pool_zip_free_mutex", 0},
3136 + {&buf_pool_zip_hash_mutex_key, "buf_pool_zip_hash_mutex", 0},
3137 {&cache_last_read_mutex_key, "cache_last_read_mutex", 0},
3138 {&dict_foreign_err_mutex_key, "dict_foreign_err_mutex", 0},
3139 {&dict_sys_mutex_key, "dict_sys_mutex", 0},
3141 {&archive_lock_key, "archive_lock", 0},
3142 # endif /* UNIV_LOG_ARCHIVE */
3143 {&btr_search_latch_key, "btr_search_latch", 0},
3144 + {&buf_pool_page_hash_key, "buf_pool_page_hash_latch", 0},
3145 # ifndef PFS_SKIP_BUFFER_MUTEX_RWLOCK
3146 {&buf_block_lock_key, "buf_block_lock", 0},
3147 # endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */
3148 --- a/storage/innobase/handler/i_s.cc
3149 +++ b/storage/innobase/handler/i_s.cc
3150 @@ -1583,7 +1583,8 @@
3152 buf_pool = buf_pool_from_array(i);
3154 - buf_pool_mutex_enter(buf_pool);
3155 + //buf_pool_mutex_enter(buf_pool);
3156 + mutex_enter(&buf_pool->zip_free_mutex);
3158 for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
3159 buf_buddy_stat_t* buddy_stat;
3160 @@ -1613,7 +1614,8 @@
3164 - buf_pool_mutex_exit(buf_pool);
3165 + //buf_pool_mutex_exit(buf_pool);
3166 + mutex_exit(&buf_pool->zip_free_mutex);
3170 --- a/storage/innobase/ibuf/ibuf0ibuf.c
3171 +++ b/storage/innobase/ibuf/ibuf0ibuf.c
3172 @@ -3821,9 +3821,11 @@
3173 ulint fold = buf_page_address_fold(space, page_no);
3174 buf_pool_t* buf_pool = buf_pool_get(space, page_no);
3176 - buf_pool_mutex_enter(buf_pool);
3177 + //buf_pool_mutex_enter(buf_pool);
3178 + rw_lock_s_lock(&buf_pool->page_hash_latch);
3179 bpage = buf_page_hash_get_low(buf_pool, space, page_no, fold);
3180 - buf_pool_mutex_exit(buf_pool);
3181 + //buf_pool_mutex_exit(buf_pool);
3182 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
3184 if (UNIV_LIKELY_NULL(bpage)) {
3185 /* A buffer pool watch has been set or the
3186 --- a/storage/innobase/include/buf0buddy.h
3187 +++ b/storage/innobase/include/buf0buddy.h
3189 ulint size, /*!< in: compressed page size
3190 (between PAGE_ZIP_MIN_SIZE and
3192 - ibool* lru) /*!< in: pointer to a variable
3193 + ibool* lru, /*!< in: pointer to a variable
3194 that will be assigned TRUE if
3195 storage was allocated from the
3196 LRU list and buf_pool->mutex was
3197 temporarily released */
3198 + ibool have_page_hash_mutex)
3199 __attribute__((malloc, nonnull));
3201 /**********************************************************************//**
3203 the block resides */
3204 void* buf, /*!< in: block to be freed, must not
3205 be pointed to by the buffer pool */
3206 - ulint size) /*!< in: block size,
3207 + ulint size, /*!< in: block size,
3208 up to UNIV_PAGE_SIZE */
3209 + ibool have_page_hash_mutex)
3210 __attribute__((nonnull));
3213 --- a/storage/innobase/include/buf0buddy.ic
3214 +++ b/storage/innobase/include/buf0buddy.ic
3216 buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
3217 ulint i, /*!< in: index of buf_pool->zip_free[],
3218 or BUF_BUDDY_SIZES */
3219 - ibool* lru) /*!< in: pointer to a variable that
3220 + ibool* lru, /*!< in: pointer to a variable that
3221 will be assigned TRUE if storage was
3222 allocated from the LRU list and
3223 buf_pool->mutex was temporarily
3225 + ibool have_page_hash_mutex)
3226 __attribute__((malloc, nonnull));
3228 /**********************************************************************//**
3230 buf_pool_t* buf_pool, /*!< in: buffer pool instance */
3231 void* buf, /*!< in: block to be freed, must not be
3232 pointed to by the buffer pool */
3233 - ulint i) /*!< in: index of buf_pool->zip_free[],
3234 + ulint i, /*!< in: index of buf_pool->zip_free[],
3235 or BUF_BUDDY_SIZES */
3236 + ibool have_page_hash_mutex)
3237 __attribute__((nonnull));
3239 /**********************************************************************//**
3240 @@ -101,19 +103,20 @@
3241 ulint size, /*!< in: compressed page size
3242 (between PAGE_ZIP_MIN_SIZE and
3244 - ibool* lru) /*!< in: pointer to a variable
3245 + ibool* lru, /*!< in: pointer to a variable
3246 that will be assigned TRUE if
3247 storage was allocated from the
3248 LRU list and buf_pool->mutex was
3249 temporarily released */
3250 + ibool have_page_hash_mutex)
3252 - ut_ad(buf_pool_mutex_own(buf_pool));
3253 + //ut_ad(buf_pool_mutex_own(buf_pool));
3254 ut_ad(ut_is_2pow(size));
3255 ut_ad(size >= PAGE_ZIP_MIN_SIZE);
3256 ut_ad(size <= UNIV_PAGE_SIZE);
3258 return((byte*) buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size),
3260 + lru, have_page_hash_mutex));
3263 /**********************************************************************//**
3264 @@ -126,15 +129,28 @@
3265 the block resides */
3266 void* buf, /*!< in: block to be freed, must not
3267 be pointed to by the buffer pool */
3268 - ulint size) /*!< in: block size,
3269 + ulint size, /*!< in: block size,
3270 up to UNIV_PAGE_SIZE */
3271 + ibool have_page_hash_mutex)
3273 - ut_ad(buf_pool_mutex_own(buf_pool));
3274 + //ut_ad(buf_pool_mutex_own(buf_pool));
3275 ut_ad(ut_is_2pow(size));
3276 ut_ad(size >= PAGE_ZIP_MIN_SIZE);
3277 ut_ad(size <= UNIV_PAGE_SIZE);
3279 - buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size));
3280 + if (!have_page_hash_mutex) {
3281 + mutex_enter(&buf_pool->LRU_list_mutex);
3282 + rw_lock_x_lock(&buf_pool->page_hash_latch);
3285 + mutex_enter(&buf_pool->zip_free_mutex);
3286 + buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size), TRUE);
3287 + mutex_exit(&buf_pool->zip_free_mutex);
3289 + if (!have_page_hash_mutex) {
3290 + mutex_exit(&buf_pool->LRU_list_mutex);
3291 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
3295 #ifdef UNIV_MATERIALIZE
3296 --- a/storage/innobase/include/buf0buf.h
3297 +++ b/storage/innobase/include/buf0buf.h
3298 @@ -212,6 +212,20 @@
3299 /*==========================*/
3301 /********************************************************************//**
3305 +buf_pool_page_hash_x_lock_all(void);
3306 +/*================================*/
3308 +/********************************************************************//**
3312 +buf_pool_page_hash_x_unlock_all(void);
3313 +/*==================================*/
3315 +/********************************************************************//**
3316 Creates the buffer pool.
3317 @return own: buf_pool object, NULL if not enough memory or error */
3319 @@ -864,6 +878,15 @@
3320 const buf_page_t* bpage) /*!< in: pointer to control block */
3321 __attribute__((pure));
3323 +/*************************************************************************
3324 +Gets the mutex of a block and enter the mutex with consistency. */
3327 +buf_page_get_mutex_enter(
3328 +/*=========================*/
3329 + const buf_page_t* bpage) /*!< in: pointer to control block */
3330 + __attribute__((pure));
3332 /*********************************************************************//**
3333 Get the flush type of a page.
3334 @return flush type */
3335 @@ -1345,7 +1368,7 @@
3336 All these are protected by buf_pool->mutex. */
3339 - UT_LIST_NODE_T(buf_page_t) list;
3340 + /* UT_LIST_NODE_T(buf_page_t) list; */
3341 /*!< based on state, this is a
3342 list node, protected either by
3343 buf_pool->mutex or by
3344 @@ -1373,6 +1396,10 @@
3345 BUF_BLOCK_REMOVE_HASH or
3346 BUF_BLOCK_READY_IN_USE. */
3348 + /* resplit for optimistic use */
3349 + UT_LIST_NODE_T(buf_page_t) free;
3350 + UT_LIST_NODE_T(buf_page_t) flush_list;
3351 + UT_LIST_NODE_T(buf_page_t) zip_list; /* zip_clean or zip_free[] */
3353 ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;
3354 when buf_pool->flush_list_mutex is
3355 @@ -1465,11 +1492,11 @@
3356 a block is in the unzip_LRU list
3357 if page.state == BUF_BLOCK_FILE_PAGE
3358 and page.zip.data != NULL */
3360 +//#ifdef UNIV_DEBUG
3361 ibool in_unzip_LRU_list;/*!< TRUE if the page is in the
3362 decompressed LRU list;
3363 used in debugging */
3364 -#endif /* UNIV_DEBUG */
3365 +//#endif /* UNIV_DEBUG */
3366 mutex_t mutex; /*!< mutex protecting this block:
3367 state (also protected by the buffer
3368 pool mutex), io_fix, buf_fix_count,
3369 @@ -1646,6 +1673,11 @@
3370 pool instance, protects compressed
3371 only pages (of type buf_page_t, not
3373 + mutex_t LRU_list_mutex;
3374 + rw_lock_t page_hash_latch;
3375 + mutex_t free_list_mutex;
3376 + mutex_t zip_free_mutex;
3377 + mutex_t zip_hash_mutex;
3378 ulint instance_no; /*!< Array index of this buffer
3380 ulint old_pool_size; /*!< Old pool size in bytes */
3381 @@ -1799,8 +1831,8 @@
3382 /** Test if a buffer pool mutex is owned. */
3383 #define buf_pool_mutex_own(b) mutex_own(&b->mutex)
3384 /** Acquire a buffer pool mutex. */
3385 +/* the buf_pool_mutex is changed the latch order */
3386 #define buf_pool_mutex_enter(b) do { \
3387 - ut_ad(!mutex_own(&b->zip_mutex)); \
3388 mutex_enter(&b->mutex); \
3391 --- a/storage/innobase/include/buf0buf.ic
3392 +++ b/storage/innobase/include/buf0buf.ic
3394 case BUF_BLOCK_ZIP_FREE:
3395 /* This is a free page in buf_pool->zip_free[].
3396 Such pages should only be accessed by the buddy allocator. */
3398 + /* ut_error; */ /* optimistic */
3400 case BUF_BLOCK_ZIP_PAGE:
3401 case BUF_BLOCK_ZIP_DIRTY:
3402 @@ -335,9 +335,16 @@
3404 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3406 + if (/*equivalent to buf_pool_watch_is_sentinel(buf_pool, bpage)*/
3407 + bpage >= &buf_pool->watch[0]
3408 + && bpage < &buf_pool->watch[BUF_POOL_WATCH_SIZE]) {
3409 + /* TODO: this code is the interim. should be confirmed later. */
3410 + return(&buf_pool->zip_mutex);
3413 switch (buf_page_get_state(bpage)) {
3414 case BUF_BLOCK_ZIP_FREE:
3416 + /* ut_error; */ /* optimistic */
3418 case BUF_BLOCK_ZIP_PAGE:
3419 case BUF_BLOCK_ZIP_DIRTY:
3420 @@ -347,6 +354,28 @@
3424 +/*************************************************************************
3425 +Gets the mutex of a block and enter the mutex with consistency. */
3428 +buf_page_get_mutex_enter(
3429 +/*=========================*/
3430 + const buf_page_t* bpage) /*!< in: pointer to control block */
3432 + mutex_t* block_mutex;
3435 + block_mutex = buf_page_get_mutex(bpage);
3437 + return block_mutex;
3439 + mutex_enter(block_mutex);
3440 + if (block_mutex == buf_page_get_mutex(bpage))
3441 + return block_mutex;
3442 + mutex_exit(block_mutex);
3446 /*********************************************************************//**
3447 Get the flush type of a page.
3448 @return flush type */
3450 enum buf_io_fix io_fix) /*!< in: io_fix state */
3453 - buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3454 - ut_ad(buf_pool_mutex_own(buf_pool));
3455 + //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3456 + //ut_ad(buf_pool_mutex_own(buf_pool));
3458 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
3460 @@ -474,14 +503,14 @@
3461 const buf_page_t* bpage) /*!< control block being relocated */
3464 - buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3465 - ut_ad(buf_pool_mutex_own(buf_pool));
3466 + //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3467 + //ut_ad(buf_pool_mutex_own(buf_pool));
3469 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
3470 ut_ad(buf_page_in_file(bpage));
3471 - ut_ad(bpage->in_LRU_list);
3472 + //ut_ad(bpage->in_LRU_list);
3474 - return(buf_page_get_io_fix(bpage) == BUF_IO_NONE
3475 + return(bpage->in_LRU_list && bpage->io_fix == BUF_IO_NONE
3476 && bpage->buf_fix_count == 0);
3480 const buf_page_t* bpage) /*!< in: control block */
3483 - buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3484 - ut_ad(buf_pool_mutex_own(buf_pool));
3485 + //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3486 + //ut_ad(buf_pool_mutex_own(buf_pool));
3488 ut_ad(buf_page_in_file(bpage));
3491 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3492 #endif /* UNIV_DEBUG */
3493 ut_a(buf_page_in_file(bpage));
3494 - ut_ad(buf_pool_mutex_own(buf_pool));
3495 + //ut_ad(buf_pool_mutex_own(buf_pool));
3496 + ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
3497 ut_ad(bpage->in_LRU_list);
3499 #ifdef UNIV_LRU_DEBUG
3500 @@ -563,9 +593,10 @@
3501 ulint time_ms) /*!< in: ut_time_ms() */
3504 - buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3505 - ut_ad(buf_pool_mutex_own(buf_pool));
3506 + //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
3507 + //ut_ad(buf_pool_mutex_own(buf_pool));
3509 + ut_ad(mutex_own(buf_page_get_mutex(bpage)));
3510 ut_a(buf_page_in_file(bpage));
3512 if (!bpage->access_time) {
3513 @@ -808,19 +839,19 @@
3515 buf_block_t* block) /*!< in, own: block to be freed */
3517 - buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
3518 + //buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
3520 - buf_pool_mutex_enter(buf_pool);
3521 + //buf_pool_mutex_enter(buf_pool);
3523 mutex_enter(&block->mutex);
3525 ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
3527 - buf_LRU_block_free_non_file_page(block);
3528 + buf_LRU_block_free_non_file_page(block, FALSE);
3530 mutex_exit(&block->mutex);
3532 - buf_pool_mutex_exit(buf_pool);
3533 + //buf_pool_mutex_exit(buf_pool);
3535 #endif /* !UNIV_HOTBACKUP */
3537 @@ -868,17 +899,17 @@
3541 - mutex_t* block_mutex = buf_page_get_mutex(bpage);
3543 - mutex_enter(block_mutex);
3544 + mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
3546 - if (buf_page_in_file(bpage)) {
3547 + if (block_mutex && buf_page_in_file(bpage)) {
3548 lsn = bpage->newest_modification;
3553 - mutex_exit(block_mutex);
3554 + if (block_mutex) {
3555 + mutex_exit(block_mutex);
3561 #ifdef UNIV_SYNC_DEBUG
3562 buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
3564 - ut_ad((buf_pool_mutex_own(buf_pool)
3565 + ut_ad((mutex_own(&buf_pool->LRU_list_mutex)
3566 && (block->page.buf_fix_count == 0))
3567 || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
3568 #endif /* UNIV_SYNC_DEBUG */
3569 @@ -1026,7 +1057,11 @@
3573 - ut_ad(buf_pool_mutex_own(buf_pool));
3574 + //ut_ad(buf_pool_mutex_own(buf_pool));
3575 +#ifdef UNIV_SYNC_DEBUG
3576 + ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX)
3577 + || rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_SHARED));
3579 ut_ad(fold == buf_page_address_fold(space, offset));
3581 /* Look for the page in the hash table */
3582 @@ -1111,11 +1146,13 @@
3583 const buf_page_t* bpage;
3584 buf_pool_t* buf_pool = buf_pool_get(space, offset);
3586 - buf_pool_mutex_enter(buf_pool);
3587 + //buf_pool_mutex_enter(buf_pool);
3588 + rw_lock_s_lock(&buf_pool->page_hash_latch);
3590 bpage = buf_page_hash_get(buf_pool, space, offset);
3592 - buf_pool_mutex_exit(buf_pool);
3593 + //buf_pool_mutex_exit(buf_pool);
3594 + rw_lock_s_unlock(&buf_pool->page_hash_latch);
3596 return(bpage != NULL);
3598 @@ -1243,4 +1280,38 @@
3599 buf_pool_mutex_exit(buf_pool);
3603 +/********************************************************************//**
3607 +buf_pool_page_hash_x_lock_all(void)
3608 +/*===============================*/
3612 + for (i = 0; i < srv_buf_pool_instances; i++) {
3613 + buf_pool_t* buf_pool;
3615 + buf_pool = buf_pool_from_array(i);
3616 + rw_lock_x_lock(&buf_pool->page_hash_latch);
3620 +/********************************************************************//**
3624 +buf_pool_page_hash_x_unlock_all(void)
3625 +/*=================================*/
3629 + for (i = 0; i < srv_buf_pool_instances; i++) {
3630 + buf_pool_t* buf_pool;
3632 + buf_pool = buf_pool_from_array(i);
3633 + rw_lock_x_unlock(&buf_pool->page_hash_latch);
3636 #endif /* !UNIV_HOTBACKUP */
3637 --- a/storage/innobase/include/buf0lru.h
3638 +++ b/storage/innobase/include/buf0lru.h
3642 buf_page_t* bpage, /*!< in: block to be freed */
3643 - ibool zip) /*!< in: TRUE if should remove also the
3644 + ibool zip, /*!< in: TRUE if should remove also the
3645 compressed page of an uncompressed page */
3646 + ibool have_LRU_mutex)
3647 __attribute__((nonnull));
3648 /******************************************************************//**
3649 Try to free a replaceable block.
3652 buf_LRU_block_free_non_file_page(
3653 /*=============================*/
3654 - buf_block_t* block); /*!< in: block, must not contain a file page */
3655 + buf_block_t* block, /*!< in: block, must not contain a file page */
3656 + ibool have_page_hash_mutex);
3657 /******************************************************************//**
3658 Adds a block to the LRU list. */
3660 --- a/storage/innobase/include/sync0rw.h
3661 +++ b/storage/innobase/include/sync0rw.h
3663 extern mysql_pfs_key_t archive_lock_key;
3664 # endif /* UNIV_LOG_ARCHIVE */
3665 extern mysql_pfs_key_t btr_search_latch_key;
3666 +extern mysql_pfs_key_t buf_pool_page_hash_key;
3667 extern mysql_pfs_key_t buf_block_lock_key;
3668 # ifdef UNIV_SYNC_DEBUG
3669 extern mysql_pfs_key_t buf_block_debug_latch_key;
3670 --- a/storage/innobase/include/sync0sync.h
3671 +++ b/storage/innobase/include/sync0sync.h
3673 extern mysql_pfs_key_t buffer_block_mutex_key;
3674 extern mysql_pfs_key_t buf_pool_mutex_key;
3675 extern mysql_pfs_key_t buf_pool_zip_mutex_key;
3676 +extern mysql_pfs_key_t buf_pool_LRU_list_mutex_key;
3677 +extern mysql_pfs_key_t buf_pool_free_list_mutex_key;
3678 +extern mysql_pfs_key_t buf_pool_zip_free_mutex_key;
3679 +extern mysql_pfs_key_t buf_pool_zip_hash_mutex_key;
3680 extern mysql_pfs_key_t cache_last_read_mutex_key;
3681 extern mysql_pfs_key_t dict_foreign_err_mutex_key;
3682 extern mysql_pfs_key_t dict_sys_mutex_key;
3684 #define SYNC_TRX_SYS_HEADER 290
3685 #define SYNC_PURGE_QUEUE 200
3686 #define SYNC_LOG 170
3687 -#define SYNC_LOG_FLUSH_ORDER 147
3688 +#define SYNC_LOG_FLUSH_ORDER 156
3689 #define SYNC_RECV 168
3690 #define SYNC_WORK_QUEUE 162
3691 #define SYNC_SEARCH_SYS_CONF 161 /* for assigning btr_search_enabled */
3692 @@ -677,8 +681,13 @@
3693 SYNC_SEARCH_SYS, as memory allocation
3694 can call routines there! Otherwise
3695 the level is SYNC_MEM_HASH. */
3696 +#define SYNC_BUF_LRU_LIST 158
3697 +#define SYNC_BUF_PAGE_HASH 157
3698 +#define SYNC_BUF_BLOCK 155 /* Block mutex */
3699 +#define SYNC_BUF_FREE_LIST 153
3700 +#define SYNC_BUF_ZIP_FREE 152
3701 +#define SYNC_BUF_ZIP_HASH 151
3702 #define SYNC_BUF_POOL 150 /* Buffer pool mutex */
3703 -#define SYNC_BUF_BLOCK 146 /* Block mutex */
3704 #define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */
3705 #define SYNC_DOUBLEWRITE 140
3706 #define SYNC_ANY_LATCH 135
3708 os_fast_mutex; /*!< We use this OS mutex in place of lock_word
3709 when atomic operations are not enabled */
3711 - ulint waiters; /*!< This ulint is set to 1 if there are (or
3712 + volatile ulint waiters; /*!< This ulint is set to 1 if there are (or
3713 may be) threads waiting in the global wait
3714 array for this mutex to be released.
3715 Otherwise, this is 0. */
3716 --- a/storage/innobase/srv/srv0srv.c
3717 +++ b/storage/innobase/srv/srv0srv.c
3718 @@ -3102,7 +3102,7 @@
3719 level += log_sys->max_checkpoint_age
3720 - (lsn - oldest_modification);
3722 - bpage = UT_LIST_GET_NEXT(list, bpage);
3723 + bpage = UT_LIST_GET_NEXT(flush_list, bpage);
3727 @@ -3188,7 +3188,7 @@
3731 - bpage = UT_LIST_GET_NEXT(list, bpage);
3732 + bpage = UT_LIST_GET_NEXT(flush_list, bpage);
3736 --- a/storage/innobase/sync/sync0sync.c
3737 +++ b/storage/innobase/sync/sync0sync.c
3739 mutex->lock_word = 0;
3741 mutex->event = os_event_create(NULL);
3742 - mutex_set_waiters(mutex, 0);
3743 + mutex->waiters = 0;
3745 mutex->magic_n = MUTEX_MAGIC_N;
3746 #endif /* UNIV_DEBUG */
3747 @@ -464,6 +464,15 @@
3748 mutex_t* mutex, /*!< in: mutex */
3749 ulint n) /*!< in: value to set */
3751 +#ifdef INNODB_RW_LOCKS_USE_ATOMICS
3755 + os_compare_and_swap_ulint(&mutex->waiters, 0, 1);
3757 + os_compare_and_swap_ulint(&mutex->waiters, 1, 0);
3760 volatile ulint* ptr; /* declared volatile to ensure that
3761 the value is stored to memory */
3765 *ptr = n; /* Here we assume that the write of a single
3766 word in memory is atomic */
3770 /******************************************************************//**
3771 @@ -1234,7 +1244,12 @@
3775 + case SYNC_BUF_LRU_LIST:
3776 case SYNC_BUF_FLUSH_LIST:
3777 + case SYNC_BUF_PAGE_HASH:
3778 + case SYNC_BUF_FREE_LIST:
3779 + case SYNC_BUF_ZIP_FREE:
3780 + case SYNC_BUF_ZIP_HASH:
3782 /* We can have multiple mutexes of this type therefore we
3783 can only check whether the greater than condition holds. */
3784 @@ -1252,7 +1267,8 @@
3785 buffer block (block->mutex or buf_pool->zip_mutex). */
3786 if (!sync_thread_levels_g(array, level, FALSE)) {
3787 ut_a(sync_thread_levels_g(array, level - 1, TRUE));
3788 - ut_a(sync_thread_levels_contain(array, SYNC_BUF_POOL));
3789 + /* the exact rule is not fixed yet, for now */
3790 + //ut_a(sync_thread_levels_contain(array, SYNC_BUF_LRU_LIST));