Commit 274f2bc6 authored by marko's avatar marko

branches/zip: buf_LRU_free_block(): New function, split from

buf_LRU_search_and_free_block().
parent 2018ce35
...@@ -116,7 +116,7 @@ buf_flush_ready_for_replace( ...@@ -116,7 +116,7 @@ buf_flush_ready_for_replace(
ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&(buf_pool->mutex)));
ut_ad(mutex_own(&block->mutex)); ut_ad(mutex_own(&block->mutex));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
if (block->state != BUF_BLOCK_FILE_PAGE) { if (UNIV_UNLIKELY(block->state != BUF_BLOCK_FILE_PAGE)) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: Error: buffer block state %lu" " InnoDB: Error: buffer block state %lu"
......
...@@ -194,43 +194,30 @@ buf_LRU_get_recent_limit(void) ...@@ -194,43 +194,30 @@ buf_LRU_get_recent_limit(void)
} }
/********************************************************************** /**********************************************************************
Look for a replaceable block from the end of the LRU list and put it to Try to free a block. */
the free list if found. */
ibool ibool
buf_LRU_search_and_free_block( buf_LRU_free_block(
/*==========================*/ /*===============*/
/* out: TRUE if freed */ /* out: TRUE if freed */
ulint n_iterations) /* in: how many times this has been called buf_block_t* block) /* in: block to be freed */
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; #ifdef UNIV_SYNC_DEBUG
ulint distance = 0; ut_ad(mutex_own(&buf_pool->mutex));
ibool freed; ut_ad(mutex_own(&block->mutex));
#endif /* UNIV_SYNC_DEBUG */
mutex_enter(&(buf_pool->mutex));
freed = FALSE;
block = UT_LIST_GET_LAST(buf_pool->LRU);
while (block != NULL) {
ut_a(block->in_LRU_list); ut_a(block->in_LRU_list);
mutex_enter(&block->mutex); if (!buf_flush_ready_for_replace(block)) {
if (buf_flush_ready_for_replace(block)) { return(FALSE);
}
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
if (buf_debug_prints) { if (buf_debug_prints) {
fprintf(stderr, fprintf(stderr, "Putting space %lu page %lu to free list\n",
"Putting space %lu page %lu" (ulong) block->space, (ulong) block->offset);
" to free list\n",
(ulong) block->space,
(ulong) block->offset);
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
...@@ -243,37 +230,65 @@ buf_LRU_search_and_free_block( ...@@ -243,37 +230,65 @@ buf_LRU_search_and_free_block(
btr_search_drop_page_hash_index(block); btr_search_drop_page_hash_index(block);
ut_a(block->buf_fix_count == 0); ut_a(block->buf_fix_count == 0);
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
mutex_enter(&block->mutex); mutex_enter(&block->mutex);
buf_LRU_block_free_hashed_page(block); buf_LRU_block_free_hashed_page(block);
freed = TRUE;
return(TRUE);
}
/**********************************************************************
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 */
{
buf_block_t* block;
ulint distance = 0;
ibool freed;
mutex_enter(&(buf_pool->mutex));
freed = FALSE;
block = UT_LIST_GET_LAST(buf_pool->LRU);
while (block != NULL) {
mutex_enter(&block->mutex);
freed = buf_LRU_free_block(block);
mutex_exit(&block->mutex); mutex_exit(&block->mutex);
if (freed) {
break; break;
} }
mutex_exit(&block->mutex);
block = UT_LIST_GET_PREV(LRU, block); block = UT_LIST_GET_PREV(LRU, block);
distance++; distance++;
if (!freed && n_iterations <= 10 if (n_iterations <= 10
&& distance > 100 + (n_iterations * buf_pool->curr_size) && distance > 100 + (n_iterations * buf_pool->curr_size)
/ 10) { / 10) {
buf_pool->LRU_flush_ended = 0; goto func_exit;
mutex_exit(&(buf_pool->mutex));
return(FALSE);
} }
} }
if (buf_pool->LRU_flush_ended > 0) { if (buf_pool->LRU_flush_ended > 0) {
buf_pool->LRU_flush_ended--; buf_pool->LRU_flush_ended--;
} }
func_exit:
if (!freed) { if (!freed) {
buf_pool->LRU_flush_ended = 0; buf_pool->LRU_flush_ended = 0;
} }
......
...@@ -66,6 +66,14 @@ buf_LRU_get_recent_limit(void); ...@@ -66,6 +66,14 @@ buf_LRU_get_recent_limit(void);
/*==========================*/ /*==========================*/
/* out: the limit; zero if could not determine it */ /* out: the limit; zero if could not determine it */
/********************************************************************** /**********************************************************************
Try to free a block. */
ibool
buf_LRU_free_block(
/*===============*/
/* out: TRUE if freed */
buf_block_t* block); /* in: block to be freed */
/**********************************************************************
Look for a replaceable block from the end of the LRU list and put it to Look for a replaceable block from the end of the LRU list and put it to
the free list if found. */ the free list if found. */
......
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