buf0lru.c, buf0flu.c, buf0buf.c, buf0lru.h:

  Search first only 10 % of the LRU list for a replaceable block before doing an LRU flush; enable again flushing of close pages also in a flush list (checkpointing) flush
trx0trx.c:
  Add forgotten return value (it was not used anywhere, fortunately)
ha_innodb.h, mysql_priv.h:
  Move declaration of srv_buf_pool_max_modified_pct to ha_innodb.h and enclose it to denote it is a C variable, not C++
parent cf79c475
......@@ -1613,7 +1613,7 @@ buf_pool_invalidate(void)
freed = TRUE;
while (freed) {
freed = buf_LRU_search_and_free_block(0);
freed = buf_LRU_search_and_free_block(100);
}
mutex_enter(&(buf_pool->mutex));
......@@ -1898,8 +1898,10 @@ buf_print_io(
buf += sprintf(buf,
"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
buf_pool->n_flush[BUF_FLUSH_LRU],
buf_pool->n_flush[BUF_FLUSH_LIST],
buf_pool->n_flush[BUF_FLUSH_LRU]
+ buf_pool->init_flush[BUF_FLUSH_LRU],
buf_pool->n_flush[BUF_FLUSH_LIST]
+ buf_pool->init_flush[BUF_FLUSH_LIST],
buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
current_time = time(NULL);
......
......@@ -573,15 +573,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); */
......@@ -598,13 +590,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));
......@@ -723,7 +722,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,
......@@ -849,11 +847,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);
}
}
}
......
......@@ -104,12 +104,15 @@ ibool
buf_LRU_search_and_free_block(
/*==========================*/
/* out: TRUE if freed */
ulint n_iterations __attribute__((unused))) /* in: how many times
this has been called repeatedly without
result: a high value means that we should
search farther */
ulint n_iterations) /* in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; if value is
k < 10, then we only search k/10 * [number
of pages in the buffer pool] from the end
of the LRU list */
{
buf_block_t* block;
ulint distance = 0;
ibool freed;
mutex_enter(&(buf_pool->mutex));
......@@ -146,6 +149,18 @@ buf_LRU_search_and_free_block(
}
block = UT_LIST_GET_PREV(LRU, block);
distance++;
if (!freed && n_iterations <= 10
&& distance > 100 + (n_iterations * buf_pool->curr_size)
/ 10) {
buf_pool->LRU_flush_ended = 0;
mutex_exit(&(buf_pool->mutex));
return(FALSE);
}
}
if (buf_pool->LRU_flush_ended > 0) {
......@@ -180,7 +195,7 @@ buf_LRU_try_free_flushed_blocks(void)
mutex_exit(&(buf_pool->mutex));
buf_LRU_search_and_free_block(0);
buf_LRU_search_and_free_block(1);
mutex_enter(&(buf_pool->mutex));
}
......@@ -200,7 +215,7 @@ buf_LRU_get_free_block(void)
{
buf_block_t* block = NULL;
ibool freed;
ulint n_iterations = 0;
ulint n_iterations = 1;
ibool mon_value_was = 0; /* remove bug */
ibool started_monitor = FALSE;
loop:
......@@ -246,14 +261,6 @@ buf_LRU_get_free_block(void)
srv_print_innodb_monitor = FALSE;
}
if (buf_pool->LRU_flush_ended > 0) {
mutex_exit(&(buf_pool->mutex));
buf_LRU_try_free_flushed_blocks();
mutex_enter(&(buf_pool->mutex));
}
/* If there is a block in the free list, take it */
if (UT_LIST_GET_LEN(buf_pool->free) > 0) {
......@@ -319,6 +326,20 @@ buf_LRU_get_free_block(void)
os_aio_simulated_wake_handler_threads();
mutex_enter(&(buf_pool->mutex));
if (buf_pool->LRU_flush_ended > 0) {
/* We have written pages in an LRU flush. To make the insert
buffer more efficient, we try to move these pages to the free
list. */
mutex_exit(&(buf_pool->mutex));
buf_LRU_try_free_flushed_blocks();
} else {
mutex_exit(&(buf_pool->mutex));
}
if (n_iterations > 10) {
os_thread_sleep(500000);
......
......@@ -46,6 +46,20 @@ buf_LRU_get_recent_limit(void);
/*==========================*/
/* out: the limit; zero if could not determine it */
/**********************************************************************
Look for a replaceable block from the end of the LRU list and put it to
the free list if found. */
ibool
buf_LRU_search_and_free_block(
/*==========================*/
/* out: TRUE if freed */
ulint n_iterations); /* in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; if value is
k < 10, then we only search k/10 * number
of pages in the buffer pool from the end
of the LRU list */
/**********************************************************************
Returns a free block from the buf_pool. The block is taken off the
free list. If it is empty, blocks are moved from the end of the
LRU list to the free list. */
......@@ -86,17 +100,6 @@ void
buf_LRU_make_block_old(
/*===================*/
buf_block_t* block); /* in: control block */
/**********************************************************************
Look for a replaceable block from the end of the LRU list and put it to
the free list if found. */
ibool
buf_LRU_search_and_free_block(
/*==========================*/
/* out: TRUE if freed */
ulint n_iterations); /* in: how many times this has been called
repeatedly without result: a high value
means that we should search farther */
/**************************************************************************
Validates the LRU list. */
......
......@@ -1505,6 +1505,8 @@ trx_commit_complete_for_mysql(
trx->op_info = (char *) "";
}
return(0);
}
/**************************************************************************
......
......@@ -197,6 +197,9 @@ extern char *innobase_unix_file_flush_method;
/* The following variables have to be my_bool for SHOW VARIABLES to work */
extern my_bool innobase_log_archive,
innobase_use_native_aio, innobase_fast_shutdown;
extern "C" {
extern ulong srv_max_buf_pool_modified_pct;
}
extern TYPELIB innobase_lock_typelib;
......
......@@ -658,10 +658,6 @@ extern ulong max_binlog_size, rpl_recovery_rank, thread_cache_size;
extern ulong com_stat[(uint) SQLCOM_END], com_other, back_log;
extern ulong specialflag, current_pid;
#ifdef HAVE_INNOBASE_DB
extern ulong srv_max_buf_pool_modified_pct;
#endif
extern uint test_flags,select_errors,ha_open_options;
extern uint protocol_version,dropping_tables;
extern uint delay_key_write_options;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment