diff options
Diffstat (limited to 'innobase/buf/buf0flu.c')
-rw-r--r-- | innobase/buf/buf0flu.c | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index 02587487a92..47ac9c6b041 100644 --- a/innobase/buf/buf0flu.c +++ b/innobase/buf/buf0flu.c @@ -107,7 +107,7 @@ buf_flush_ready_for_replace( BUF_BLOCK_FILE_PAGE and in the LRU list */ { ut_ad(mutex_own(&(buf_pool->mutex))); - ut_ad(block->state == BUF_BLOCK_FILE_PAGE); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); if ((ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0) || (block->buf_fix_count != 0) @@ -227,7 +227,9 @@ buf_flush_buffered_writes(void) } for (i = 0; i < trx_doublewrite->first_free; i++) { + block = trx_doublewrite->buf_block_arr[i]; + ut_a(block->state == BUF_BLOCK_FILE_PAGE); if (block->check_index_page_at_flush && !page_simple_validate(block->frame)) { @@ -236,10 +238,12 @@ buf_flush_buffered_writes(void) ut_print_timestamp(stderr); fprintf(stderr, - " InnoDB: Apparent corruption of an index page\n" + " InnoDB: Apparent corruption of an index page n:o %lu in space %lu\n" "InnoDB: to be written to data file. We intentionally crash server\n" "InnoDB: to prevent corrupt data from ending up in data\n" - "InnoDB: files.\n"); + "InnoDB: files.\n", + block->offset, block->space); + ut_a(0); } } @@ -394,7 +398,7 @@ buf_flush_write_block_low( "Warning: cannot force log to disk in the log debug version!\n"); #else /* Force the log to the disk before writing the modified block */ - log_flush_up_to(block->newest_modification, LOG_WAIT_ALL_GROUPS); + log_write_up_to(block->newest_modification, LOG_WAIT_ALL_GROUPS, TRUE); #endif buf_flush_init_for_writing(block->frame, block->newest_modification, block->space, block->offset); @@ -432,6 +436,8 @@ buf_flush_try_page( block = buf_page_hash_get(space, offset); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + if (flush_type == BUF_FLUSH_LIST && block && buf_flush_ready_for_flush(block, flush_type)) { @@ -567,7 +573,8 @@ buf_flush_try_page( rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE); if (buf_debug_prints) { - printf("Flushing single page space %lu, page no %lu \n", + printf( + "Flushing single page space %lu, page no %lu \n", block->space, block->offset); } @@ -608,15 +615,7 @@ buf_flush_try_neighbors( low = offset; high = offset + 1; - } else if (flush_type == BUF_FLUSH_LIST) { - /* Since semaphore waits require us to flush the - doublewrite buffer to disk, it is best that the - search area is just the page itself, to minimize - chances for semaphore waits */ - - low = offset; - high = offset + 1; - } + } /* printf("Flush area: low %lu high %lu\n", low, high); */ @@ -633,13 +632,20 @@ buf_flush_try_neighbors( if (block && flush_type == BUF_FLUSH_LRU && i != offset && !block->old) { - /* We avoid flushing 'non-old' blocks in an LRU flush, - because the flushed blocks are soon freed */ + /* We avoid flushing 'non-old' blocks in an LRU flush, + because the flushed blocks are soon freed */ - continue; + continue; } - if (block && buf_flush_ready_for_flush(block, flush_type)) { + if (block && buf_flush_ready_for_flush(block, flush_type) + && (i == offset || block->buf_fix_count == 0)) { + /* We only try to flush those neighbors != offset + where the buf fix count is zero, as we then know that + we probably can latch the page without a semaphore + wait. Semaphore waits are expensive because we must + flush the doublewrite buffer before we start + waiting. */ mutex_exit(&(buf_pool->mutex)); @@ -758,7 +764,6 @@ buf_flush_batch( page_count += buf_flush_try_neighbors(space, offset, flush_type); - /* printf( "Flush type %lu, page no %lu, neighb %lu\n", flush_type, offset, @@ -884,11 +889,19 @@ buf_flush_free_margin(void) /*=======================*/ { ulint n_to_flush; + ulint n_flushed; n_to_flush = buf_flush_LRU_recommendation(); if (n_to_flush > 0) { - buf_flush_batch(BUF_FLUSH_LRU, n_to_flush, ut_dulint_zero); + n_flushed = buf_flush_batch(BUF_FLUSH_LRU, n_to_flush, + ut_dulint_zero); + if (n_flushed == ULINT_UNDEFINED) { + /* There was an LRU type flush batch already running; + let us wait for it to end */ + + buf_flush_wait_batch_end(BUF_FLUSH_LRU); + } } } |