From 9c663a0c461e8518fadc697d9021135e5b668f2d Mon Sep 17 00:00:00 2001 From: marko <Unknown> Date: Fri, 16 Feb 2007 09:22:50 +0000 Subject: [PATCH] branches/zip: buf_LRU_search_and_free_block(): Avoid freeing compressed-only pages when they do not occupy too much of the buffer pool. buf0buddy.c, buf0buddy.h: Export buf_buddy_n_frames and buf_buddy_min_n_frames. --- buf/buf0buddy.c | 15 +++++--- buf/buf0lru.c | 90 ++++++++++++++++++++++++++++++++++++++------- include/buf0buddy.h | 9 +++++ 3 files changed, 94 insertions(+), 20 deletions(-) diff --git a/buf/buf0buddy.c b/buf/buf0buddy.c index 69c344a52f8..efe55af8ff9 100644 --- a/buf/buf0buddy.c +++ b/buf/buf0buddy.c @@ -17,20 +17,23 @@ Created December 2006 by Marko Makela #include "buf0flu.h" #include "page0zip.h" -/* Statistic counters, protected by buf_pool->mutex */ +/* Statistic counters */ -/** Number of frames allocated from the buffer pool to the buddy system */ -static ulint buf_buddy_n_frames; -/** Counts of blocks allocated from the buddy system */ +/** Number of frames allocated from the buffer pool to the buddy system. +Protected by buf_pool->mutex. */ +ulint buf_buddy_n_frames; +/** Counts of blocks allocated from the buddy system. +Protected by buf_pool->mutex. */ static ulint buf_buddy_used[BUF_BUDDY_SIZES + 1]; -/** Counts of blocks relocated by the buddy system */ +/** Counts of blocks relocated by the buddy system. +Protected by buf_pool->mutex. */ static ib_uint64_t buf_buddy_relocated[BUF_BUDDY_SIZES + 1]; /** Preferred minimum number of frames allocated from the buffer pool to the buddy system. When this number is exceeded, the buddy allocator will not try to free clean compressed-only pages in order to satisfy an allocation request. Protected by buf_pool->mutex. */ -static ulint buf_buddy_min_n_frames = ULINT_UNDEFINED; +ulint buf_buddy_min_n_frames = ULINT_UNDEFINED; /************************************************************************** Get the offset of the buddy of a compressed page frame. */ diff --git a/buf/buf0lru.c b/buf/buf0lru.c index b4967da257b..ba4918fede0 100644 --- a/buf/buf0lru.c +++ b/buf/buf0lru.c @@ -264,7 +264,6 @@ buf_LRU_search_and_free_block( of the LRU list */ { buf_page_t* bpage; - ulint distance = 0; ibool freed; mutex_enter(&(buf_pool->mutex)); @@ -272,25 +271,88 @@ buf_LRU_search_and_free_block( freed = FALSE; bpage = UT_LIST_GET_LAST(buf_pool->LRU); - while (bpage != NULL) { - mutex_t* block_mutex = buf_page_get_mutex(bpage); + if (UNIV_UNLIKELY(n_iterations > 10)) { + /* The buffer pool is scarce. Search the whole + LRU list, and also free any compressed pages. */ + + while (bpage != NULL) { + mutex_t* block_mutex + = buf_page_get_mutex(bpage); + + mutex_enter(block_mutex); + /* Discard also the compressed page. */ + freed = buf_LRU_free_block(bpage, TRUE); + if (!freed && bpage->zip.data) { + /* Could not free the compressed page; + try freeing the uncompressed page then. */ + freed = buf_LRU_free_block(bpage, FALSE); + } + mutex_exit(block_mutex); - mutex_enter(block_mutex); - freed = buf_LRU_free_block(bpage, n_iterations > 10); - mutex_exit(block_mutex); + if (freed) { + + break; + } + + bpage = UT_LIST_GET_PREV(LRU, bpage); + } + } else if (buf_buddy_n_frames > buf_buddy_min_n_frames) { + /* There are enough compressed blocks. Free the + least recently used block, whether or not it + comprises an uncompressed page. */ - if (freed) { + ulint distance = 100 + + (n_iterations * buf_pool->curr_size) / 10; - break; + while (bpage != NULL) { + mutex_t* block_mutex + = buf_page_get_mutex(bpage); + + mutex_enter(block_mutex); + /* Preserve any compressed page. */ + freed = buf_LRU_free_block(bpage, FALSE); + mutex_exit(block_mutex); + + if (freed) { + + break; + } + + bpage = UT_LIST_GET_PREV(LRU, bpage); + + if (!--distance) { + goto func_exit; + } } + } else { + /* There are few compressed blocks. Skip compressed-only + blocks in the search for the least recently used block + that can be freed. Preserve any compressed page. */ + + ulint distance = 100 + + (n_iterations * buf_pool->curr_size) / 10; - bpage = UT_LIST_GET_PREV(LRU, bpage); - distance++; + while (bpage != NULL) { + if (buf_page_get_state(bpage) + == BUF_BLOCK_FILE_PAGE) { - if (n_iterations <= 10 - && distance > 100 + (n_iterations * buf_pool->curr_size) - / 10) { - goto func_exit; + buf_block_t* block = (buf_block_t*) bpage; + mutex_enter(&block->mutex); + /* Preserve any compressed page. */ + freed = buf_LRU_free_block(bpage, FALSE); + mutex_exit(&block->mutex); + + if (freed) { + + break; + } + } + + bpage = UT_LIST_GET_PREV(LRU, bpage); + + if (!--distance) { + goto func_exit; + } } } diff --git a/include/buf0buddy.h b/include/buf0buddy.h index 5bd2dbc779f..2e8cc694558 100644 --- a/include/buf0buddy.h +++ b/include/buf0buddy.h @@ -46,6 +46,15 @@ buf_buddy_free( ulint size) /* in: block size, up to UNIV_PAGE_SIZE */ __attribute__((nonnull)); +/** Number of frames allocated from the buffer pool to the buddy system. +Protected by buf_pool->mutex. */ +extern ulint buf_buddy_n_frames; +/** Preferred minimum number of frames allocated from the buffer pool +to the buddy system. When this number is exceeded, the buddy allocator +will not try to free clean compressed-only pages in order to satisfy +an allocation request. Protected by buf_pool->mutex. */ +extern ulint buf_buddy_min_n_frames; + #ifndef UNIV_NONINL # include "buf0buddy.ic" #endif -- 2.30.9