Commit d56453be authored by marko's avatar marko

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.
parent e67d5c76
......@@ -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. */
......
......@@ -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;
}
}
}
......
......@@ -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
......
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