Merge lp:~laurynas-biveinis/percona-server/buf-mutex-split-fixes-5.1 into lp:percona-server/5.1

Proposed by Laurynas Biveinis
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 585
Proposed branch: lp:~laurynas-biveinis/percona-server/buf-mutex-split-fixes-5.1
Merge into: lp:percona-server/5.1
Diff against target: 515 lines (+102/-79)
6 files modified
Percona-Server/storage/innodb_plugin/buf/buf0buf.c (+24/-18)
Percona-Server/storage/innodb_plugin/buf/buf0flu.c (+56/-47)
Percona-Server/storage/innodb_plugin/buf/buf0lru.c (+11/-7)
Percona-Server/storage/innodb_plugin/include/buf0buf.h (+4/-4)
Percona-Server/storage/innodb_plugin/include/buf0flu.h (+4/-1)
Percona-Server/storage/innodb_plugin/include/buf0lru.h (+3/-2)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/buf-mutex-split-fixes-5.1
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve
Alexey Kopytov (community) Approve
George Ormond Lorch III (community) g2 Approve
Review via email: mp+165526@code.launchpad.net

Description of the change

http://jenkins.percona.com/job/percona-server-5.1-param/543/

Fix several buffer pool mutex split bugs:

- bug 1086680 (Valgrind: free in buf_page_get_gen (Invalid read in
  buf_flush_batch / buf_flush_list) + free in buf_page_get_gen
  (Invalid read in buf_flush_page_and_try_neighbors));

- bug 1103850 (InnoDB: Failing assertion:
  mutex_own(&buf_pool->LRU_list_mutex) in file buf0lru.c line 859);

- bug 1181269 (Unnecessary LRU list mutex acquisition in
  buf_page_io_complete()).

The Valgrind errors and crashes of bug 1086680 happen because of a
race condition involving a dirty compressed page block for which there
is uncompressed page image in the buffer pool.

First, a master thread (or possible another query thread) does a flush
list flush and for that acquires the flush list mutex, gets a pointer
to a page, releases the flush list mutex.

At this point another thread starts reading the same page into the
buffer. Since it is a dirty compressed page, it allocates an
uncompressed page, relocates the page on the flush list, frees the
compressed page descriptor.

At this point the flushing thread proceeds to use the pointer which is
now dangling, causing the issue.

Fix by adjusting buf_flush_batch() to hold the flush list mutex for
all the bpage pointer dereferences. This should not introduce any new
stalls because the mutex is released after checking a few fields
only. This also allows simplifying buf_flush_batch() to become closer
to the InnoDB version, by removing prev_bpage and remaining local
vars. However, this means that buf_flush_ready_for_flush() now
becomes callable with the flush list mutex both held and not held.
This requires additional handling because this function may call
buf_flush_remove() in XtraDB due to the lazy table drop feature. The
latter needs to acquire the flush list mutex, thus we introduce a
boolean have_flush_list_mutex for buf_flush_remove() and
buf_flush_ready_for_flush(), together with additional invariant
asserts.

Bug 1103850 is caused by buf_flush_remove() calling
buf_LRU_insert_zip_clean() for BUF_BLOCK_ZIP_DIRTY pages in debug
builds, which requires the LRU list mutex, which is not always held
here. Fixed by disabling the zip_clean list maintenance for debug
builds. The alternative would be to buffer-fix the block, release and
re-acquire all the mutexes, including the LRU list one. But since
buf_flush_remove() may be called from different contexts holding
different mutexes (also due to bug 1086680 fix), this seems to be very
impractical.

Bug 1181269 is a missed performance improvement opportunity due to
upstream fixing http://bugs.mysql.com/bug.php?id=61341, which made
that buf_LRU_insert_zip_clean() call in buf_flush_remove() confined to
debug builds only. But XtraDB still kept on acquiring the LRU list
mutex buf_flush_write_complete() for flush list flushes, which call
buf_flush_remove(). With the buf_LRU_insert_zip_clean() made
debug-only by upstream and removed by bug 1103850 fix,
buf_flush_write_complete() only has to acquire the LRU list mutex for
the LRU list flushes.

To post a comment you must log in.
Revision history for this message
George Ormond Lorch III (gl-az) wrote :

Nice work, especially the fix for bug 1086680 and the changes in buf_flush_batch.

review: Approve (g2)
Revision history for this message
Alexey Kopytov (akopytov) wrote :

Laurynas,

Thanks for implementing my idea of a fix for bug #1086680.

Approving with a nitpick about a couple of lines not using the InnoDB coding conventions:

+ ut_ad (block_mutex);

and

+ mutex_exit (block_mutex);

review: Approve
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Percona-Server/storage/innodb_plugin/buf/buf0buf.c'
--- Percona-Server/storage/innodb_plugin/buf/buf0buf.c 2013-08-05 13:11:52 +0000
+++ Percona-Server/storage/innodb_plugin/buf/buf0buf.c 2013-08-16 08:39:46 +0000
@@ -210,13 +210,6 @@
210but not written to disk yet. The block with the oldest modification210but not written to disk yet. The block with the oldest modification
211which has not yet been written to disk is at the end of the chain.211which has not yet been written to disk is at the end of the chain.
212212
213The chain of unmodified compressed blocks (buf_pool->zip_clean)
214contains the control blocks (buf_page_t) of those compressed pages
215that are not in buf_pool->flush_list and for which no uncompressed
216page has been allocated in the buffer pool. The control blocks for
217uncompressed pages are accessible via buf_block_t objects that are
218reachable via buf_pool->chunks[].
219
220The chains of free memory blocks (buf_pool->zip_free[]) are used by213The chains of free memory blocks (buf_pool->zip_free[]) are used by
221the buddy allocator (buf0buddy.c) to keep track of currently unused214the buddy allocator (buf0buddy.c) to keep track of currently unused
222memory blocks of size sizeof(buf_page_t)..UNIV_PAGE_SIZE / 2. These215memory blocks of size sizeof(buf_page_t)..UNIV_PAGE_SIZE / 2. These
@@ -2031,10 +2024,11 @@
20312024
2032 if (buf_page_get_state(&block->page)2025 if (buf_page_get_state(&block->page)
2033 == BUF_BLOCK_ZIP_PAGE) {2026 == BUF_BLOCK_ZIP_PAGE) {
2034#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG2027#if 0
2028 /* Disabled for XtraDB, see buf_flush_remove(). */
2035 UT_LIST_REMOVE(zip_list, buf_pool->zip_clean,2029 UT_LIST_REMOVE(zip_list, buf_pool->zip_clean,
2036 &block->page);2030 &block->page);
2037#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */2031#endif
2038 ut_ad(!block->page.in_flush_list);2032 ut_ad(!block->page.in_flush_list);
2039 } else {2033 } else {
2040 /* Relocate buf_pool->flush_list. */2034 /* Relocate buf_pool->flush_list. */
@@ -2858,11 +2852,12 @@
28582852
2859 /* The block must be put to the LRU list, to the old blocks */2853 /* The block must be put to the LRU list, to the old blocks */
2860 buf_LRU_add_block(bpage, TRUE/* to old blocks */);2854 buf_LRU_add_block(bpage, TRUE/* to old blocks */);
2861#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG2855#if 0
2856 /* Disabled for XtraDB, see buf_flush_remove(). */
2862 mutex_enter(&flush_list_mutex);2857 mutex_enter(&flush_list_mutex);
2863 buf_LRU_insert_zip_clean(bpage);2858 buf_LRU_insert_zip_clean(bpage);
2864 mutex_exit(&flush_list_mutex);2859 mutex_exit(&flush_list_mutex);
2865#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */2860#endif
28662861
2867 mutex_exit(&LRU_list_mutex);2862 mutex_exit(&LRU_list_mutex);
28682863
@@ -3063,6 +3058,7 @@
3063 const ibool uncompressed = (buf_page_get_state(bpage)3058 const ibool uncompressed = (buf_page_get_state(bpage)
3064 == BUF_BLOCK_FILE_PAGE);3059 == BUF_BLOCK_FILE_PAGE);
3065 mutex_t* block_mutex;3060 mutex_t* block_mutex;
3061 enum buf_flush flush_type = BUF_FLUSH_N_TYPES;
30663062
3067 ut_a(buf_page_in_file(bpage));3063 ut_a(buf_page_in_file(bpage));
30683064
@@ -3219,9 +3215,12 @@
3219 }3215 }
3220 }3216 }
32213217
3222 //buf_pool_mutex_enter();
3223 if (io_type == BUF_IO_WRITE) {3218 if (io_type == BUF_IO_WRITE) {
3224 mutex_enter(&LRU_list_mutex);3219
3220 flush_type = buf_page_get_flush_type(bpage);
3221 if (flush_type == BUF_FLUSH_LRU) {
3222 mutex_enter(&LRU_list_mutex);
3223 }
3225 }3224 }
3226 block_mutex = buf_page_get_mutex_enter(bpage);3225 block_mutex = buf_page_get_mutex_enter(bpage);
3227 ut_a(block_mutex);3226 ut_a(block_mutex);
@@ -3265,10 +3264,9 @@
32653264
3266 buf_flush_write_complete(bpage);3265 buf_flush_write_complete(bpage);
32673266
3268 /* to keep consistency at buf_LRU_insert_zip_clean() */3267 if (flush_type == BUF_FLUSH_LRU) {
3269 //if (flush_type == BUF_FLUSH_LRU) { /* optimistic! */
3270 mutex_exit(&LRU_list_mutex);3268 mutex_exit(&LRU_list_mutex);
3271 //}3269 }
32723270
3273 if (uncompressed) {3271 if (uncompressed) {
3274 rw_lock_s_unlock_gen(&((buf_block_t*) bpage)->lock,3272 rw_lock_s_unlock_gen(&((buf_block_t*) bpage)->lock,
@@ -3404,7 +3402,7 @@
3404 case BUF_BLOCK_ZIP_PAGE:3402 case BUF_BLOCK_ZIP_PAGE:
3405 case BUF_BLOCK_ZIP_DIRTY:3403 case BUF_BLOCK_ZIP_DIRTY:
3406 /* These should only occur on3404 /* These should only occur on
3407 zip_clean, zip_free[], or flush_list. */3405 zip_free[], or flush_list. */
3408 ut_error;3406 ut_error;
3409 break;3407 break;
34103408
@@ -3480,6 +3478,9 @@
34803478
3481 mutex_enter(&buf_pool_zip_mutex);3479 mutex_enter(&buf_pool_zip_mutex);
34823480
3481#if 0
3482 /* Disabled for XtraDB, see buf_flush_remove(). */
3483
3483 /* Check clean compressed-only blocks. */3484 /* Check clean compressed-only blocks. */
34843485
3485 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;3486 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
@@ -3505,6 +3506,7 @@
3505 n_lru++;3506 n_lru++;
3506 n_zip++;3507 n_zip++;
3507 }3508 }
3509#endif
35083510
3509 /* Check dirty compressed-only blocks. */3511 /* Check dirty compressed-only blocks. */
35103512
@@ -3566,7 +3568,7 @@
3566 ut_error;3568 ut_error;
3567 }3569 }
35683570
3569 ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru);3571 ut_a(UT_LIST_GET_LEN(buf_pool->LRU) >= n_lru);
3570 /* because of latching order with block->mutex, we cannot get free_list_mutex before that */3572 /* because of latching order with block->mutex, we cannot get free_list_mutex before that */
3571/*3573/*
3572 if (UT_LIST_GET_LEN(buf_pool->free) != n_free) {3574 if (UT_LIST_GET_LEN(buf_pool->free) != n_free) {
@@ -3766,6 +3768,9 @@
37663768
3767 /* Traverse the lists of clean and dirty compressed-only blocks. */3769 /* Traverse the lists of clean and dirty compressed-only blocks. */
37683770
3771#if 0
3772 /* Disabled for XtraDB, see buf_flush_remove(). */
3773
3769 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;3774 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
3770 b = UT_LIST_GET_NEXT(zip_list, b)) {3775 b = UT_LIST_GET_NEXT(zip_list, b)) {
3771 ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);3776 ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
@@ -3776,6 +3781,7 @@
3776 fixed_pages_number++;3781 fixed_pages_number++;
3777 }3782 }
3778 }3783 }
3784#endif
37793785
3780 mutex_enter(&flush_list_mutex);3786 mutex_enter(&flush_list_mutex);
3781 for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;3787 for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
37823788
=== modified file 'Percona-Server/storage/innodb_plugin/buf/buf0flu.c'
--- Percona-Server/storage/innodb_plugin/buf/buf0flu.c 2013-08-05 13:11:52 +0000
+++ Percona-Server/storage/innodb_plugin/buf/buf0flu.c 2013-08-16 08:39:46 +0000
@@ -395,12 +395,18 @@
395/*======================*/395/*======================*/
396 buf_page_t* bpage, /*!< in: buffer control block, must be396 buf_page_t* bpage, /*!< in: buffer control block, must be
397 buf_page_in_file(bpage) */397 buf_page_in_file(bpage) */
398 enum buf_flush flush_type)/*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */398 enum buf_flush flush_type,/*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
399 ibool have_flush_list_mutex)/*!< in: TRUE if flush list mutex
400 is being held */
399{401{
400 //ut_a(buf_page_in_file(bpage));402 ut_a(buf_page_in_file(bpage));
401 //ut_ad(buf_pool_mutex_own()); /*optimistic...*/403
402 ut_ad(mutex_own(buf_page_get_mutex(bpage)));404 ut_ad(have_flush_list_mutex == mutex_own(&flush_list_mutex));
403 ut_ad(flush_type == BUF_FLUSH_LRU || BUF_FLUSH_LIST);405 ut_ad(((flush_type == BUF_FLUSH_LRU
406 && mutex_own(buf_page_get_mutex(bpage)))
407 || (flush_type == BUF_FLUSH_LIST
408 && (mutex_own(buf_page_get_mutex(bpage))
409 || mutex_own(&flush_list_mutex)))));
404410
405 if (buf_page_in_file(bpage) && bpage->oldest_modification != 0411 if (buf_page_in_file(bpage) && bpage->oldest_modification != 0
406 && buf_page_get_io_fix(bpage) == BUF_IO_NONE) {412 && buf_page_get_io_fix(bpage) == BUF_IO_NONE) {
@@ -409,7 +415,7 @@
409 if (bpage->space_was_being_deleted) {415 if (bpage->space_was_being_deleted) {
410 /* should be removed from flush_list here */416 /* should be removed from flush_list here */
411 /* because buf_flush_try_neighbors() cannot flush without fil_space_get_size(space) */417 /* because buf_flush_try_neighbors() cannot flush without fil_space_get_size(space) */
412 buf_flush_remove(bpage);418 buf_flush_remove(bpage, have_flush_list_mutex);
413 return(FALSE);419 return(FALSE);
414 }420 }
415421
@@ -436,12 +442,16 @@
436void442void
437buf_flush_remove(443buf_flush_remove(
438/*=============*/444/*=============*/
439 buf_page_t* bpage) /*!< in: pointer to the block in question */445 buf_page_t* bpage, /*!< in: pointer to the block in question */
446 ibool have_flush_list_mutex) /*!< in: TRUE if
447 flush_list_mutex is held */
440{448{
441 //ut_ad(buf_pool_mutex_own());449 if (!have_flush_list_mutex) {
442 ut_ad(mutex_own(buf_page_get_mutex(bpage)));450 mutex_enter(&flush_list_mutex);
443451 } else {
444 mutex_enter(&flush_list_mutex);452 ut_ad(mutex_own(&flush_list_mutex));
453 ut_ad(!mutex_own(buf_page_get_mutex(bpage)));
454 }
445455
446 ut_ad(bpage->in_flush_list);456 ut_ad(bpage->in_flush_list);
447457
@@ -453,15 +463,17 @@
453 case BUF_BLOCK_READY_FOR_USE:463 case BUF_BLOCK_READY_FOR_USE:
454 case BUF_BLOCK_MEMORY:464 case BUF_BLOCK_MEMORY:
455 case BUF_BLOCK_REMOVE_HASH:465 case BUF_BLOCK_REMOVE_HASH:
456 mutex_exit(&flush_list_mutex);
457 ut_error;466 ut_error;
458 return;467 return;
459 case BUF_BLOCK_ZIP_DIRTY:468 case BUF_BLOCK_ZIP_DIRTY:
460 buf_page_set_state(bpage, BUF_BLOCK_ZIP_PAGE);469 buf_page_set_state(bpage, BUF_BLOCK_ZIP_PAGE);
461 UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);470 UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
462#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG471#if 0
472 /* Disabled for XtraDB. The cost of acquiring LRU mutex here
473 seems to be higher than the benefit of zip_clean list
474 maintenance. */
463 buf_LRU_insert_zip_clean(bpage);475 buf_LRU_insert_zip_clean(bpage);
464#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */476#endif
465 break;477 break;
466 case BUF_BLOCK_FILE_PAGE:478 case BUF_BLOCK_FILE_PAGE:
467 UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);479 UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
@@ -481,7 +493,9 @@
481493
482 ut_d(UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,494 ut_d(UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
483 ut_ad(ut_list_node_313->in_flush_list)));495 ut_ad(ut_list_node_313->in_flush_list)));
484 mutex_exit(&flush_list_mutex);496 if (!have_flush_list_mutex) {
497 mutex_exit(&flush_list_mutex);
498 }
485}499}
486500
487/********************************************************************//**501/********************************************************************//**
@@ -554,7 +568,7 @@
554568
555 ut_ad(bpage);569 ut_ad(bpage);
556570
557 buf_flush_remove(bpage);571 buf_flush_remove(bpage, FALSE);
558572
559 flush_type = buf_page_get_flush_type(bpage);573 flush_type = buf_page_get_flush_type(bpage);
560 buf_pool->n_flush[flush_type]--;574 buf_pool->n_flush[flush_type]--;
@@ -1089,8 +1103,9 @@
1089 //ut_ad(buf_pool_mutex_own());1103 //ut_ad(buf_pool_mutex_own());
1090 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);1104 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1091 ut_ad(mutex_own(&block->mutex));1105 ut_ad(mutex_own(&block->mutex));
1106 ut_ad(!mutex_own(&flush_list_mutex));
10921107
1093 if (!buf_flush_ready_for_flush(&block->page, BUF_FLUSH_LRU)) {1108 if (!buf_flush_ready_for_flush(&block->page, BUF_FLUSH_LRU, FALSE)) {
1094 return(FALSE);1109 return(FALSE);
1095 }1110 }
10961111
@@ -1171,6 +1186,7 @@
1171 ibool is_uncompressed;1186 ibool is_uncompressed;
11721187
1173 ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);1188 ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
1189 ut_ad(!mutex_own(&flush_list_mutex));
1174 //ut_ad(buf_pool_mutex_own());1190 //ut_ad(buf_pool_mutex_own());
1175#ifdef UNIV_SYNC_DEBUG1191#ifdef UNIV_SYNC_DEBUG
1176 ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX)1192 ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX)
@@ -1184,7 +1200,7 @@
1184 mutex_enter(&buf_pool_mutex);1200 mutex_enter(&buf_pool_mutex);
1185 rw_lock_s_unlock(&page_hash_latch);1201 rw_lock_s_unlock(&page_hash_latch);
11861202
1187 ut_ad(buf_flush_ready_for_flush(bpage, flush_type));1203 ut_ad(buf_flush_ready_for_flush(bpage, flush_type, FALSE));
11881204
1189 buf_page_set_io_fix(bpage, BUF_IO_WRITE);1205 buf_page_set_io_fix(bpage, BUF_IO_WRITE);
11901206
@@ -1294,6 +1310,7 @@
1294 ulint i;1310 ulint i;
12951311
1296 ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);1312 ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
1313 ut_ad(!mutex_own(&flush_list_mutex));
12971314
1298 if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN || !flush_neighbors) {1315 if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN || !flush_neighbors) {
1299 /* If there is little space, it is better not to flush any1316 /* If there is little space, it is better not to flush any
@@ -1340,7 +1357,9 @@
1340 || buf_page_is_old(bpage)) {1357 || buf_page_is_old(bpage)) {
1341 mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);1358 mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
13421359
1343 if (block_mutex && buf_flush_ready_for_flush(bpage, flush_type)1360 if (block_mutex
1361 && buf_flush_ready_for_flush(bpage, flush_type,
1362 FALSE)
1344 && (i == offset || !bpage->buf_fix_count)) {1363 && (i == offset || !bpage->buf_fix_count)) {
1345 /* We only try to flush those1364 /* We only try to flush those
1346 neighbors != offset where the buf fix count is1365 neighbors != offset where the buf fix count is
@@ -1394,11 +1413,9 @@
1394 min_n), otherwise ignored */1413 min_n), otherwise ignored */
1395{1414{
1396 buf_page_t* bpage;1415 buf_page_t* bpage;
1397 buf_page_t* prev_bpage = NULL;
1398 ulint page_count = 0;1416 ulint page_count = 0;
1399 ulint space;1417 ulint space;
1400 ulint offset;1418 ulint offset;
1401 ulint remaining = 0;
14021419
1403 ut_ad((flush_type == BUF_FLUSH_LRU)1420 ut_ad((flush_type == BUF_FLUSH_LRU)
1404 || (flush_type == BUF_FLUSH_LIST));1421 || (flush_type == BUF_FLUSH_LIST));
@@ -1445,16 +1462,12 @@
1445 ut_ad(flush_type == BUF_FLUSH_LIST);1462 ut_ad(flush_type == BUF_FLUSH_LIST);
14461463
1447 mutex_enter(&flush_list_mutex);1464 mutex_enter(&flush_list_mutex);
1448 remaining = UT_LIST_GET_LEN(buf_pool->flush_list);
1449 bpage = UT_LIST_GET_LAST(buf_pool->flush_list);1465 bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
1450 if (bpage) {
1451 prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
1452 }
1453 mutex_exit(&flush_list_mutex);
1454 if (!bpage1466 if (!bpage
1455 || bpage->oldest_modification >= lsn_limit) {1467 || bpage->oldest_modification >= lsn_limit) {
1456 /* We have flushed enough */1468 /* We have flushed enough */
14571469
1470 mutex_exit(&flush_list_mutex);
1458 break;1471 break;
1459 }1472 }
1460 ut_ad(bpage->in_flush_list);1473 ut_ad(bpage->in_flush_list);
@@ -1467,24 +1480,29 @@
1467 function a pointer to a block in the list! */1480 function a pointer to a block in the list! */
14681481
1469 do {1482 do {
1470 mutex_t*block_mutex = buf_page_get_mutex_enter(bpage);1483 mutex_t*block_mutex = NULL;
1471 ibool ready;1484 ibool ready;
14721485
1473 //ut_a(buf_page_in_file(bpage));1486 ut_a(buf_page_in_file(bpage));
14741487
1488 if (flush_type == BUF_FLUSH_LRU) {
1489 block_mutex = buf_page_get_mutex_enter(bpage);
1490 ut_ad(block_mutex);
1491 }
1492 ready = buf_flush_ready_for_flush(bpage, flush_type,
1493 (flush_type
1494 == BUF_FLUSH_LIST));
1475 if (block_mutex) {1495 if (block_mutex) {
1476 ready = buf_flush_ready_for_flush(bpage, flush_type);
1477 mutex_exit(block_mutex);1496 mutex_exit(block_mutex);
1478 } else {
1479 ready = FALSE;
1480 }1497 }
14811498
1482 if (ready) {1499 if (ready) {
1483 space = buf_page_get_space(bpage);1500 space = buf_page_get_space(bpage);
1484 offset = buf_page_get_page_no(bpage);1501 offset = buf_page_get_page_no(bpage);
14851502
1486 //buf_pool_mutex_exit();1503 if (flush_type == BUF_FLUSH_LIST) {
1487 if (flush_type == BUF_FLUSH_LRU) {1504 mutex_exit(&flush_list_mutex);
1505 } else if (flush_type == BUF_FLUSH_LRU) {
1488 mutex_exit(&LRU_list_mutex);1506 mutex_exit(&LRU_list_mutex);
1489 }1507 }
14901508
@@ -1503,26 +1521,17 @@
1503 } else {1521 } else {
1504 ut_ad(flush_type == BUF_FLUSH_LIST);1522 ut_ad(flush_type == BUF_FLUSH_LIST);
15051523
1506 mutex_enter(&flush_list_mutex);
1507 bpage = UT_LIST_GET_PREV(flush_list, bpage);1524 bpage = UT_LIST_GET_PREV(flush_list, bpage);
1508 //ut_ad(!bpage || bpage->in_flush_list); /* optimistic */1525 ut_ad(!bpage || bpage->in_flush_list);
1509 if (bpage != prev_bpage) {
1510 /* the search may warp.. retrying */
1511 bpage = NULL;
1512 }
1513 if (bpage) {
1514 prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
1515 }
1516 mutex_exit(&flush_list_mutex);
1517 remaining--;
1518 }1526 }
1519 } while (bpage != NULL);1527 } while (bpage != NULL);
15201528
1521 if (remaining)
1522 goto flush_next;
1523
1524 /* If we could not find anything to flush, leave the loop */1529 /* If we could not find anything to flush, leave the loop */
15251530
1531 if (flush_type == BUF_FLUSH_LIST) {
1532 mutex_exit(&flush_list_mutex);
1533 }
1534
1526 break;1535 break;
1527 }1536 }
15281537
15291538
=== modified file 'Percona-Server/storage/innodb_plugin/buf/buf0lru.c'
--- Percona-Server/storage/innodb_plugin/buf/buf0lru.c 2013-08-05 13:11:52 +0000
+++ Percona-Server/storage/innodb_plugin/buf/buf0lru.c 2013-08-16 08:39:46 +0000
@@ -481,7 +481,7 @@
481481
482 if (bpage->oldest_modification != 0) {482 if (bpage->oldest_modification != 0) {
483483
484 buf_flush_remove(bpage);484 buf_flush_remove(bpage, FALSE);
485 }485 }
486486
487 /* Remove from the LRU list. */487 /* Remove from the LRU list. */
@@ -540,7 +540,8 @@
540 ut_ad(buf_LRU_drop_page_hash_for_tablespace(id) == 0);540 ut_ad(buf_LRU_drop_page_hash_for_tablespace(id) == 0);
541}541}
542542
543#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG543#if 0
544/* Disabled for XtraDB, see buf_flush_remove(). */
544/********************************************************************//**545/********************************************************************//**
545Insert a compressed block into buf_pool->zip_clean in the LRU order. */546Insert a compressed block into buf_pool->zip_clean in the LRU order. */
546UNIV_INTERN547UNIV_INTERN
@@ -1452,7 +1453,7 @@
1452 }1453 }
14531454
1454 if (bpage->space_was_being_deleted && bpage->oldest_modification != 0) {1455 if (bpage->space_was_being_deleted && bpage->oldest_modification != 0) {
1455 buf_flush_remove(bpage);1456 buf_flush_remove(bpage, FALSE);
1456 }1457 }
14571458
1458#ifdef UNIV_IBUF_COUNT_DEBUG1459#ifdef UNIV_IBUF_COUNT_DEBUG
@@ -1619,9 +1620,11 @@
16191620
1620 mutex_enter(&flush_list_mutex);1621 mutex_enter(&flush_list_mutex);
1621 if (b->state == BUF_BLOCK_ZIP_PAGE) {1622 if (b->state == BUF_BLOCK_ZIP_PAGE) {
1622#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG1623#if 0
1624 /* Disabled for XtraDB, see
1625 buf_flush_remove(). */
1623 buf_LRU_insert_zip_clean(b);1626 buf_LRU_insert_zip_clean(b);
1624#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */1627#endif
1625 } else {1628 } else {
1626 /* Relocate on buf_pool->flush_list. */1629 /* Relocate on buf_pool->flush_list. */
1627 buf_flush_relocate_on_flush_list(bpage, b);1630 buf_flush_relocate_on_flush_list(bpage, b);
@@ -1920,9 +1923,10 @@
1920 ut_a(bpage->zip.data);1923 ut_a(bpage->zip.data);
1921 ut_a(buf_page_get_zip_size(bpage));1924 ut_a(buf_page_get_zip_size(bpage));
19221925
1923#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG1926#if 0
1927 /* Disabled for XtraDB, see buf_flush_remove(). */
1924 UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, bpage);1928 UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, bpage);
1925#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */1929#endif
19261930
1927 mutex_exit(&buf_pool_zip_mutex);1931 mutex_exit(&buf_pool_zip_mutex);
1928 //buf_pool_mutex_exit_forbid();1932 //buf_pool_mutex_exit_forbid();
19291933
=== modified file 'Percona-Server/storage/innodb_plugin/include/buf0buf.h'
--- Percona-Server/storage/innodb_plugin/include/buf0buf.h 2013-03-06 11:10:14 +0000
+++ Percona-Server/storage/innodb_plugin/include/buf0buf.h 2013-08-16 08:39:46 +0000
@@ -1219,7 +1219,6 @@
1219 - BUF_BLOCK_NOT_USED: free1219 - BUF_BLOCK_NOT_USED: free
1220 - BUF_BLOCK_FILE_PAGE: flush_list1220 - BUF_BLOCK_FILE_PAGE: flush_list
1221 - BUF_BLOCK_ZIP_DIRTY: flush_list1221 - BUF_BLOCK_ZIP_DIRTY: flush_list
1222 - BUF_BLOCK_ZIP_PAGE: zip_clean
1223 - BUF_BLOCK_ZIP_FREE: zip_free[]1222 - BUF_BLOCK_ZIP_FREE: zip_free[]
12241223
1225 The contents of the list node1224 The contents of the list node
@@ -1233,7 +1232,7 @@
1233 /* resplit for optimistic use */1232 /* resplit for optimistic use */
1234 UT_LIST_NODE_T(buf_page_t) free;1233 UT_LIST_NODE_T(buf_page_t) free;
1235 UT_LIST_NODE_T(buf_page_t) flush_list;1234 UT_LIST_NODE_T(buf_page_t) flush_list;
1236 UT_LIST_NODE_T(buf_page_t) zip_list; /* zip_clean or zip_free[] */1235 UT_LIST_NODE_T(buf_page_t) zip_list; /* zip_free[] */
1237#ifdef UNIV_DEBUG1236#ifdef UNIV_DEBUG
1238 ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;1237 ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;
1239 when buf_pool_mutex is free, the1238 when buf_pool_mutex is free, the
@@ -1587,10 +1586,11 @@
1587 frames and buf_page_t descriptors of blocks that exist1586 frames and buf_page_t descriptors of blocks that exist
1588 in the buffer pool only in compressed form. */1587 in the buffer pool only in compressed form. */
1589 /* @{ */1588 /* @{ */
1590#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG1589#if 0
1590 /* Disabled for XtraDB, see buf_flush_remove(). */
1591 UT_LIST_BASE_NODE_T(buf_page_t) zip_clean;1591 UT_LIST_BASE_NODE_T(buf_page_t) zip_clean;
1592 /*!< unmodified compressed pages */1592 /*!< unmodified compressed pages */
1593#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */1593#endif
1594 UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES_MAX];1594 UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES_MAX];
1595 /*!< buddy free lists */1595 /*!< buddy free lists */
1596//#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE1596//#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE
15971597
=== modified file 'Percona-Server/storage/innodb_plugin/include/buf0flu.h'
--- Percona-Server/storage/innodb_plugin/include/buf0flu.h 2013-08-05 13:11:52 +0000
+++ Percona-Server/storage/innodb_plugin/include/buf0flu.h 2013-08-16 08:39:46 +0000
@@ -38,7 +38,10 @@
38void38void
39buf_flush_remove(39buf_flush_remove(
40/*=============*/40/*=============*/
41 buf_page_t* bpage); /*!< in: pointer to the block in question */41 buf_page_t* bpage, /*!< in: pointer to the block in question */
42 ibool have_flush_list_mutex); /*!< in: TRUE if
43 flush_list_mutex is held */
44
42/********************************************************************//**45/********************************************************************//**
43Relocates a buffer control block on the flush_list.46Relocates a buffer control block on the flush_list.
44Note that it is assumed that the contents of bpage has already been47Note that it is assumed that the contents of bpage has already been
4548
=== modified file 'Percona-Server/storage/innodb_plugin/include/buf0lru.h'
--- Percona-Server/storage/innodb_plugin/include/buf0lru.h 2013-08-05 13:11:52 +0000
+++ Percona-Server/storage/innodb_plugin/include/buf0lru.h 2013-08-16 08:39:46 +0000
@@ -79,7 +79,8 @@
79buf_LRU_mark_space_was_deleted(79buf_LRU_mark_space_was_deleted(
80/*===========================*/80/*===========================*/
81 ulint id); /*!< in: space id */81 ulint id); /*!< in: space id */
82#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG82#if 0
83/* Disabled for XtraDB, see buf_flush_remove(). */
83/********************************************************************//**84/********************************************************************//**
84Insert a compressed block into buf_pool->zip_clean in the LRU order. */85Insert a compressed block into buf_pool->zip_clean in the LRU order. */
85UNIV_INTERN86UNIV_INTERN
@@ -87,7 +88,7 @@
87buf_LRU_insert_zip_clean(88buf_LRU_insert_zip_clean(
88/*=====================*/89/*=====================*/
89 buf_page_t* bpage); /*!< in: pointer to the block in question */90 buf_page_t* bpage); /*!< in: pointer to the block in question */
90#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */91#endif
9192
92/******************************************************************//**93/******************************************************************//**
93Try to free a block. If bpage is a descriptor of a compressed-only94Try to free a block. If bpage is a descriptor of a compressed-only

Subscribers

People subscribed via source and target branches