Merge lp:~laurynas-biveinis/percona-server/bpage-io-fix into lp:percona-server/5.5

Proposed by Laurynas Biveinis
Status: Merged
Approved by: Stewart Smith
Approved revision: no longer in the source branch.
Merged at revision: 428
Proposed branch: lp:~laurynas-biveinis/percona-server/bpage-io-fix
Merge into: lp:percona-server/5.5
Diff against target: 434 lines (+153/-46)
7 files modified
Percona-Server/storage/innobase/buf/buf0buf.c (+1/-1)
Percona-Server/storage/innobase/buf/buf0flu.c (+2/-2)
Percona-Server/storage/innobase/buf/buf0lru.c (+97/-37)
Percona-Server/storage/innobase/fil/fil0fil.c (+1/-1)
Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c (+1/-1)
Percona-Server/storage/innobase/include/buf0buf.h (+22/-2)
Percona-Server/storage/innobase/include/buf0buf.ic (+29/-2)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/bpage-io-fix
Reviewer Review Type Date Requested Status
Stewart Smith (community) Approve
Review via email: mp+146852@code.launchpad.net

Description of the change

To post a comment you must log in.
Revision history for this message
Stewart Smith (stewart) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Percona-Server/storage/innobase/buf/buf0buf.c'
--- Percona-Server/storage/innobase/buf/buf0buf.c 2013-01-18 12:02:28 +0000
+++ Percona-Server/storage/innobase/buf/buf0buf.c 2013-02-06 13:11:25 +0000
@@ -3938,7 +3938,7 @@
3938 ensures that this is the only thread that handles the i/o for this3938 ensures that this is the only thread that handles the i/o for this
3939 block. */3939 block. */
39403940
3941 io_type = buf_page_get_io_fix(bpage);3941 io_type = buf_page_get_io_fix_unlocked(bpage);
3942 ut_ad(io_type == BUF_IO_READ || io_type == BUF_IO_WRITE);3942 ut_ad(io_type == BUF_IO_READ || io_type == BUF_IO_WRITE);
39433943
3944 if (io_type == BUF_IO_READ) {3944 if (io_type == BUF_IO_READ) {
39453945
=== modified file 'Percona-Server/storage/innobase/buf/buf0flu.c'
--- Percona-Server/storage/innobase/buf/buf0flu.c 2013-01-16 16:12:15 +0000
+++ Percona-Server/storage/innobase/buf/buf0flu.c 2013-02-06 13:11:25 +0000
@@ -915,7 +915,7 @@
915 "InnoDB: Page buf fix count %lu,"915 "InnoDB: Page buf fix count %lu,"
916 " io fix %lu, state %lu\n",916 " io fix %lu, state %lu\n",
917 (ulong)block->page.buf_fix_count,917 (ulong)block->page.buf_fix_count,
918 (ulong)buf_block_get_io_fix(block),918 (ulong)buf_block_get_io_fix_unlocked(block),
919 (ulong)buf_block_get_state(block));919 (ulong)buf_block_get_state(block));
920 }920 }
921921
@@ -1115,7 +1115,7 @@
1115 ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));1115 ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));
1116 ut_ad(!buf_flush_list_mutex_own(buf_pool));1116 ut_ad(!buf_flush_list_mutex_own(buf_pool));
1117 ut_ad(!mutex_own(buf_page_get_mutex(bpage)));1117 ut_ad(!mutex_own(buf_page_get_mutex(bpage)));
1118 ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_WRITE);1118 ut_ad(buf_page_get_io_fix_unlocked(bpage) == BUF_IO_WRITE);
1119 ut_ad(bpage->oldest_modification != 0);1119 ut_ad(bpage->oldest_modification != 0);
11201120
1121#ifdef UNIV_IBUF_COUNT_DEBUG1121#ifdef UNIV_IBUF_COUNT_DEBUG
11221122
=== modified file 'Percona-Server/storage/innobase/buf/buf0lru.c'
--- Percona-Server/storage/innobase/buf/buf0lru.c 2013-01-16 13:31:48 +0000
+++ Percona-Server/storage/innobase/buf/buf0lru.c 2013-02-06 13:11:25 +0000
@@ -393,18 +393,18 @@
393{393{
394 mutex_t* block_mutex;394 mutex_t* block_mutex;
395395
396 block_mutex = buf_page_get_mutex(bpage);
397
398 ut_ad(mutex_own(block_mutex));
396 ut_ad(mutex_own(&buf_pool->LRU_list_mutex));399 ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
397 ut_ad(buf_page_in_file(bpage));400 ut_ad(buf_page_in_file(bpage));
398401
399 block_mutex = buf_page_get_mutex(bpage);
400
401 mutex_enter(block_mutex);
402 /* "Fix" the block so that the position cannot be402 /* "Fix" the block so that the position cannot be
403 changed after we release the buffer pool and403 changed after we release the buffer pool and
404 block mutexes. */404 block mutexes. */
405 buf_page_set_sticky(bpage);405 buf_page_set_sticky(bpage);
406406
407 /* Now it is safe to release the buf_pool->mutex. */407 /* Now it is safe to release the LRU list mutex. */
408 mutex_exit(&buf_pool->LRU_list_mutex);408 mutex_exit(&buf_pool->LRU_list_mutex);
409409
410 mutex_exit(block_mutex);410 mutex_exit(block_mutex);
@@ -415,7 +415,7 @@
415415
416 mutex_enter(block_mutex);416 mutex_enter(block_mutex);
417 /* "Unfix" the block now that we have both the417 /* "Unfix" the block now that we have both the
418 buffer pool and block mutex again. */418 LRU list and block mutex again. */
419 buf_page_unset_sticky(bpage);419 buf_page_unset_sticky(bpage);
420 mutex_exit(block_mutex);420 mutex_exit(block_mutex);
421}421}
@@ -431,7 +431,9 @@
431/*================*/431/*================*/
432 buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */432 buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
433 buf_page_t* bpage, /*!< in/out: bpage to remove */433 buf_page_t* bpage, /*!< in/out: bpage to remove */
434 ulint processed) /*!< in: number of pages processed */434 ulint processed, /*!< in: number of pages processed */
435 ibool* must_restart) /*!< in/out: if TRUE, we have to
436 restart the flush list scan */
435{437{
436 /* Every BUF_LRU_DROP_SEARCH_SIZE iterations in the438 /* Every BUF_LRU_DROP_SEARCH_SIZE iterations in the
437 loop we release buf_pool->mutex to let other threads439 loop we release buf_pool->mutex to let other threads
@@ -441,10 +443,40 @@
441443
442 if (bpage != NULL444 if (bpage != NULL
443 && processed >= BUF_LRU_DROP_SEARCH_SIZE445 && processed >= BUF_LRU_DROP_SEARCH_SIZE
444 && buf_page_get_io_fix(bpage) == BUF_IO_NONE) {446 && buf_page_get_io_fix_unlocked(bpage) == BUF_IO_NONE) {
447
448 mutex_t* block_mutex;
445449
446 buf_flush_list_mutex_exit(buf_pool);450 buf_flush_list_mutex_exit(buf_pool);
447451
452 /* We don't have to worry about bpage becoming a dangling
453 pointer by a compressed page flush list relocation because
454 buf_page_get_gen() won't be called for pages from this
455 tablespace. */
456
457 block_mutex = buf_page_get_mutex_enter(bpage);
458 if (UNIV_UNLIKELY(block_mutex == NULL)) {
459
460 buf_flush_list_mutex_enter(buf_pool);
461
462 *must_restart = TRUE;
463 return FALSE;
464 }
465
466 /* Recheck the I/O fix and the flush list presence now that we
467 hold the right mutex */
468 if (UNIV_UNLIKELY(buf_page_get_io_fix(bpage) != BUF_IO_NONE
469 || bpage->oldest_modification == 0)) {
470
471 mutex_exit(block_mutex);
472 buf_flush_list_mutex_enter(buf_pool);
473
474 *must_restart = TRUE;
475 return FALSE;
476 }
477
478 *must_restart = FALSE;
479
448 /* Release the LRU list and block mutex480 /* Release the LRU list and block mutex
449 to give the other threads a go. */481 to give the other threads a go. */
450482
@@ -473,7 +505,9 @@
473buf_flush_or_remove_page(505buf_flush_or_remove_page(
474/*=====================*/506/*=====================*/
475 buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */507 buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
476 buf_page_t* bpage) /*!< in/out: bpage to remove */508 buf_page_t* bpage, /*!< in/out: bpage to remove */
509 ibool* must_restart) /*!< in/out: if TRUE, must restart the
510 flush list scan */
477{511{
478 mutex_t* block_mutex;512 mutex_t* block_mutex;
479 ibool processed = FALSE;513 ibool processed = FALSE;
@@ -487,7 +521,8 @@
487 buf_pool->mutex and block_mutex. It is safe to check521 buf_pool->mutex and block_mutex. It is safe to check
488 them while holding buf_pool->mutex only. */522 them while holding buf_pool->mutex only. */
489523
490 if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {524 if (UNIV_UNLIKELY(buf_page_get_io_fix_unlocked(bpage)
525 != BUF_IO_NONE)) {
491526
492 /* We cannot remove this page during this scan527 /* We cannot remove this page during this scan
493 yet; maybe the system is currently reading it528 yet; maybe the system is currently reading it
@@ -496,21 +531,38 @@
496 } else {531 } else {
497532
498 /* We have to release the flush_list_mutex to obey the533 /* We have to release the flush_list_mutex to obey the
499 latching order. We are however guaranteed that the page534 latching order. We are not however guaranteed that the page
500 will stay in the flush_list because buf_flush_remove()535 will stay in the flush_list. */
501 needs buf_pool->mutex as well (for the non-flush case). */
502536
503 buf_flush_list_mutex_exit(buf_pool);537 buf_flush_list_mutex_exit(buf_pool);
504538
539 /* We don't have to worry about bpage becoming a dangling
540 pointer by a compressed page flush list relocation because
541 buf_page_get_gen() won't be called for pages from this
542 tablespace. */
543
505 mutex_enter(block_mutex);544 mutex_enter(block_mutex);
506545
507 ut_ad(bpage->oldest_modification != 0);546 /* Recheck the page I/O fix and the flush list presence now
508547 thatwe hold the right mutex. */
509 if (bpage->buf_fix_count == 0) {548 if (UNIV_UNLIKELY(buf_page_get_io_fix(bpage) != BUF_IO_NONE
510549 || bpage->oldest_modification == 0)) {
511 buf_flush_remove(bpage);550
512551 /* The page became I/O-fixed or is not on the flush
513 processed = TRUE;552 list anymore, this invalidates any flush-list-page
553 pointers we have. */
554 *must_restart = TRUE;
555
556 } else {
557
558 ut_ad(bpage->oldest_modification != 0);
559
560 if (bpage->buf_fix_count == 0) {
561
562 buf_flush_remove(bpage);
563
564 processed = TRUE;
565 }
514 }566 }
515567
516 mutex_exit(block_mutex);568 mutex_exit(block_mutex);
@@ -541,11 +593,12 @@
541 buf_page_t* bpage;593 buf_page_t* bpage;
542 ulint processed = 0;594 ulint processed = 0;
543 ibool all_freed = TRUE;595 ibool all_freed = TRUE;
596 ibool must_restart = FALSE;
544597
545 buf_flush_list_mutex_enter(buf_pool);598 buf_flush_list_mutex_enter(buf_pool);
546599
547 for (bpage = UT_LIST_GET_LAST(buf_pool->flush_list);600 for (bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
548 bpage != NULL;601 !must_restart && bpage != NULL;
549 bpage = prev) {602 bpage = prev) {
550603
551 ut_a(buf_page_in_file(bpage));604 ut_a(buf_page_in_file(bpage));
@@ -561,22 +614,31 @@
561 /* Skip this block, as it does not belong to614 /* Skip this block, as it does not belong to
562 the target space. */615 the target space. */
563616
564 } else if (!buf_flush_or_remove_page(buf_pool, bpage)) {617 } else if (!buf_flush_or_remove_page(buf_pool, bpage,
618 &must_restart)) {
565619
566 /* Remove was unsuccessful, we have to try again620 /* Remove was unsuccessful, we have to try again
567 by scanning the entire list from the end. */621 by scanning the entire list from the end. */
568622
569 all_freed = FALSE;623 all_freed = FALSE;
570 }624 }
625 if (UNIV_UNLIKELY(must_restart)) {
626 ut_ad(!all_freed);
627 break;
628 }
571629
572 ++processed;630 ++processed;
573631
574 /* Yield if we have hogged the CPU and mutexes for too long. */632 /* Yield if we have hogged the CPU and mutexes for too long. */
575 if (buf_flush_try_yield(buf_pool, prev, processed)) {633 if (buf_flush_try_yield(buf_pool, prev, processed,
634 &must_restart)) {
576635
636 ut_ad(!must_restart);
577 /* Reset the batch size counter if we had to yield. */637 /* Reset the batch size counter if we had to yield. */
578638
579 processed = 0;639 processed = 0;
640 } else if (UNIV_UNLIKELY(must_restart)) {
641 all_freed = FALSE;
580 }642 }
581643
582 }644 }
@@ -641,41 +703,39 @@
641 /* No op */) {703 /* No op */) {
642704
643 buf_page_t* prev_bpage;705 buf_page_t* prev_bpage;
644 mutex_t* block_mutex = NULL;706 mutex_t* block_mutex;
645707
646 ut_a(buf_page_in_file(bpage));708 ut_a(buf_page_in_file(bpage));
647 ut_ad(bpage->in_LRU_list);709 ut_ad(bpage->in_LRU_list);
648710
649 prev_bpage = UT_LIST_GET_PREV(LRU, bpage);711 prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
650712
651 /* bpage->space and bpage->io_fix are protected by713 block_mutex = buf_page_get_mutex_enter(bpage);
652 buf_pool->mutex and the block_mutex. It is safe to check714
653 them while holding buf_pool->mutex only. */715 if (!block_mutex) {
716 /* It may be impossible case...
717 Something wrong, so will be scan_again */
718
719 all_freed = FALSE;
720 goto next_page;
721 }
654722
655 if (buf_page_get_space(bpage) != id) {723 if (buf_page_get_space(bpage) != id) {
656 /* Skip this block, as it does not belong to724 /* Skip this block, as it does not belong to
657 the space that is being invalidated. */725 the space that is being invalidated. */
726
727 mutex_exit(block_mutex);
658 goto next_page;728 goto next_page;
659 } else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {729 } else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
660 /* We cannot remove this page during this scan730 /* We cannot remove this page during this scan
661 yet; maybe the system is currently reading it731 yet; maybe the system is currently reading it
662 in, or flushing the modifications to the file */732 in, or flushing the modifications to the file */
663733
734 mutex_exit(block_mutex);
664 all_freed = FALSE;735 all_freed = FALSE;
665 goto next_page;736 goto next_page;
666 } else {737 } else {
667738
668 block_mutex = buf_page_get_mutex_enter(bpage);
669
670 if (!block_mutex) {
671 /* It may be impossible case...
672 Something wrong, so will be scan_again */
673
674 all_freed = FALSE;
675 goto next_page;
676 }
677
678
679 if (bpage->buf_fix_count > 0) {739 if (bpage->buf_fix_count > 0) {
680740
681 mutex_exit(block_mutex);741 mutex_exit(block_mutex);
682742
=== modified file 'Percona-Server/storage/innobase/fil/fil0fil.c'
--- Percona-Server/storage/innobase/fil/fil0fil.c 2013-01-09 23:45:25 +0000
+++ Percona-Server/storage/innobase/fil/fil0fil.c 2013-02-06 13:11:25 +0000
@@ -5575,7 +5575,7 @@
5575 && ((buf_page_t*)message)->space_was_being_deleted) {5575 && ((buf_page_t*)message)->space_was_being_deleted) {
55765576
5577 /* intended not to be uncompress read page */5577 /* intended not to be uncompress read page */
5578 ut_a(buf_page_get_io_fix(message) == BUF_IO_WRITE5578 ut_a(buf_page_get_io_fix_unlocked(message) == BUF_IO_WRITE
5579 || !buf_page_get_zip_size(message)5579 || !buf_page_get_zip_size(message)
5580 || buf_page_get_state(message) != BUF_BLOCK_FILE_PAGE);5580 || buf_page_get_state(message) != BUF_BLOCK_FILE_PAGE);
55815581
55825582
=== modified file 'Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c'
--- Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c 2013-01-18 03:34:53 +0000
+++ Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c 2013-02-06 13:11:25 +0000
@@ -4478,7 +4478,7 @@
4478 ut_ad(!block || buf_block_get_space(block) == space);4478 ut_ad(!block || buf_block_get_space(block) == space);
4479 ut_ad(!block || buf_block_get_page_no(block) == page_no);4479 ut_ad(!block || buf_block_get_page_no(block) == page_no);
4480 ut_ad(!block || buf_block_get_zip_size(block) == zip_size);4480 ut_ad(!block || buf_block_get_zip_size(block) == zip_size);
4481 ut_ad(!block || buf_block_get_io_fix(block) == BUF_IO_READ);4481 ut_ad(!block || buf_block_get_io_fix_unlocked(block) == BUF_IO_READ);
44824482
4483 if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE4483 if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE
4484 || trx_sys_hdr_page(space, page_no)) {4484 || trx_sys_hdr_page(space, page_no)) {
44854485
=== modified file 'Percona-Server/storage/innobase/include/buf0buf.h'
--- Percona-Server/storage/innobase/include/buf0buf.h 2013-01-18 12:02:28 +0000
+++ Percona-Server/storage/innobase/include/buf0buf.h 2013-02-06 13:11:25 +0000
@@ -958,7 +958,7 @@
958 ulint space, /*!< in: tablespace id */958 ulint space, /*!< in: tablespace id */
959 ulint page_no);/*!< in: page number */959 ulint page_no);/*!< in: page number */
960/*********************************************************************//**960/*********************************************************************//**
961Gets the io_fix state of a block.961Gets the io_fix state of a block. Requires that the block mutex is held.
962@return io_fix state */962@return io_fix state */
963UNIV_INLINE963UNIV_INLINE
964enum buf_io_fix964enum buf_io_fix
@@ -967,7 +967,17 @@
967 const buf_page_t* bpage) /*!< in: pointer to the control block */967 const buf_page_t* bpage) /*!< in: pointer to the control block */
968 __attribute__((pure));968 __attribute__((pure));
969/*********************************************************************//**969/*********************************************************************//**
970Gets the io_fix state of a block.970Gets the io_fix state of a block. Does not assert that the block mutex is
971held, to be used in the cases where it is safe not to hold it.
972@return io_fix state */
973UNIV_INLINE
974enum buf_io_fix
975buf_page_get_io_fix_unlocked(
976/*=========================*/
977 const buf_page_t* bpage) /*!< in: pointer to the control block */
978 __attribute__((pure));
979/*********************************************************************//**
980Gets the io_fix state of a block. Requires that the block mutex is held.
971@return io_fix state */981@return io_fix state */
972UNIV_INLINE982UNIV_INLINE
973enum buf_io_fix983enum buf_io_fix
@@ -976,6 +986,16 @@
976 const buf_block_t* block) /*!< in: pointer to the control block */986 const buf_block_t* block) /*!< in: pointer to the control block */
977 __attribute__((pure));987 __attribute__((pure));
978/*********************************************************************//**988/*********************************************************************//**
989Gets the io_fix state of a block. Does not assert that the block mutex is
990held, to be used in the cases where it is safe not to hold it.
991@return io_fix state */
992UNIV_INLINE
993enum buf_io_fix
994buf_block_get_io_fix_unlocked(
995/*==========================*/
996 const buf_block_t* block) /*!< in: pointer to the control block */
997 __attribute__((pure));
998/*********************************************************************//**
979Sets the io_fix state of a block. */999Sets the io_fix state of a block. */
980UNIV_INLINE1000UNIV_INLINE
981void1001void
9821002
=== modified file 'Percona-Server/storage/innobase/include/buf0buf.ic'
--- Percona-Server/storage/innobase/include/buf0buf.ic 2013-01-17 22:50:22 +0000
+++ Percona-Server/storage/innobase/include/buf0buf.ic 2013-02-06 13:11:25 +0000
@@ -434,7 +434,7 @@
434}434}
435435
436/*********************************************************************//**436/*********************************************************************//**
437Gets the io_fix state of a block.437Gets the io_fix state of a block. Requires that the block mutex is held.
438@return io_fix state */438@return io_fix state */
439UNIV_INLINE439UNIV_INLINE
440enum buf_io_fix440enum buf_io_fix
@@ -442,6 +442,20 @@
442/*================*/442/*================*/
443 const buf_page_t* bpage) /*!< in: pointer to the control block */443 const buf_page_t* bpage) /*!< in: pointer to the control block */
444{444{
445 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
446 return buf_page_get_io_fix_unlocked(bpage);
447}
448
449/*********************************************************************//**
450Gets the io_fix state of a block. Does not assert that the block mutex is
451held, to be used in the cases where it is safe not to hold it.
452@return io_fix state */
453UNIV_INLINE
454enum buf_io_fix
455buf_page_get_io_fix_unlocked(
456/*=========================*/
457 const buf_page_t* bpage) /*!< in: pointer to the control block */
458{
445 enum buf_io_fix io_fix = (enum buf_io_fix) bpage->io_fix;459 enum buf_io_fix io_fix = (enum buf_io_fix) bpage->io_fix;
446#ifdef UNIV_DEBUG460#ifdef UNIV_DEBUG
447 switch (io_fix) {461 switch (io_fix) {
@@ -457,7 +471,7 @@
457}471}
458472
459/*********************************************************************//**473/*********************************************************************//**
460Gets the io_fix state of a block.474Gets the io_fix state of a block. Requires that the block mutex is held.
461@return io_fix state */475@return io_fix state */
462UNIV_INLINE476UNIV_INLINE
463enum buf_io_fix477enum buf_io_fix
@@ -469,6 +483,19 @@
469}483}
470484
471/*********************************************************************//**485/*********************************************************************//**
486Gets the io_fix state of a block. Does not assert that the block mutex is
487held, to be used in the cases where it is safe not to hold it.
488@return io_fix state */
489UNIV_INLINE
490enum buf_io_fix
491buf_block_get_io_fix_unlocked(
492/*==========================*/
493 const buf_block_t* block) /*!< in: pointer to the control block */
494{
495 return(buf_page_get_io_fix_unlocked(&block->page));
496}
497
498/*********************************************************************//**
472Sets the io_fix state of a block. */499Sets the io_fix state of a block. */
473UNIV_INLINE500UNIV_INLINE
474void501void

Subscribers

People subscribed via source and target branches