From e2c305f32b39ee4dc9cf003f2e078366ce7a70f3 Mon Sep 17 00:00:00 2001 From: marko <Unknown> Date: Wed, 15 Nov 2006 21:49:14 +0000 Subject: [PATCH] branches/zip: Improve the shrinking of the buffer pool. buf_LRU_block_free_non_file_page(): Deallocate block->page_zip.data to avoid ut_a(!block->page_zip.data) in buf_chunk_free(). buf_chunk_free(): Add the assertion ut_a(!block->in_LRU_list). buf_pool_resize(): When shrinking the buffer pool and there are non-free blocks in the candidate chunk, free the clean blocks and move the dirty blocks to the end of the LRU list and request a flush. Proceed if the chunk becomes free, and retry otherwise. --- buf/buf0buf.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++----- buf/buf0lru.c | 8 ++++- 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/buf/buf0buf.c b/buf/buf0buf.c index 25ad81505e4..cf68b9156c0 100644 --- a/buf/buf0buf.c +++ b/buf/buf0buf.c @@ -798,6 +798,7 @@ buf_chunk_free( ut_a(block->state == BUF_BLOCK_NOT_USED); ut_a(!block->page_zip.data); + ut_a(!block->in_LRU_list); /* Remove the block from the free list. */ ut_a(block->in_free_list); UT_LIST_REMOVE(free, buf_pool->free, block); @@ -904,6 +905,7 @@ buf_pool_resize(void) buf_chunk_t* chunks; buf_chunk_t* chunk; +try_again: mutex_enter(&buf_pool->mutex); if (srv_buf_pool_old_size == srv_buf_pool_size) { @@ -919,7 +921,9 @@ buf_pool_resize(void) = (srv_buf_pool_curr_size - srv_buf_pool_size) / UNIV_PAGE_SIZE; ulint max_size; + ulint max_free_size; buf_chunk_t* max_chunk; + buf_chunk_t* max_free_chunk; shrink_again: if (buf_pool->n_chunks <= 1) { @@ -932,25 +936,86 @@ buf_pool_resize(void) not larger than the size difference */ chunks = buf_pool->chunks; chunk = chunks + buf_pool->n_chunks; - max_size = 0; - max_chunk = NULL; + max_size = max_free_size = 0; + max_chunk = max_free_chunk = NULL; while (--chunk >= chunks) { if (chunk->size <= chunk_size - && chunk->size > max_size - && buf_chunk_all_free(chunk)) { - max_size = chunk->size; - max_chunk = chunk; + && chunk->size > max_free_size) { + if (chunk->size > max_size) { + max_size = chunk->size; + max_chunk = chunk; + } + + if (buf_chunk_all_free(chunk)) { + max_free_size = chunk->size; + max_free_chunk = chunk; + } } } - if (!max_size) { + if (!max_free_size) { + + ulint dirty = 0; + ulint nonfree = 0; + buf_block_t* block; + buf_block_t* bend; /* Cannot shrink: try again later (do not assign srv_buf_pool_old_size) */ - goto func_exit; + if (!max_chunk) { + + goto func_exit; + } + + block = max_chunk->blocks; + bend = block + max_chunk->size; + + /* Move the blocks of chunk to the end of the + LRU list and try to flush them. */ + for (; block < bend; block++) { + if (block->state != BUF_BLOCK_FILE_PAGE) { + + continue; + } + + mutex_enter(&block->mutex); + + if (!buf_flush_ready_for_replace(block)) { + + buf_LRU_make_block_old(block); + dirty++; + } else if (!buf_LRU_free_block(block)) { + nonfree++; + } + + mutex_exit(&block->mutex); + } + + /* See if the chunk was in fact free. */ + if (!dirty && !nonfree) { + + goto is_free; + } + + mutex_exit(&buf_pool->mutex); + + /* Request for a flush of the chunk. */ + if (buf_flush_batch(BUF_FLUSH_LRU, dirty, + ut_dulint_zero) + == ULINT_UNDEFINED) { + + buf_flush_wait_batch_end(BUF_FLUSH_LRU); + } + + /* Retry after flushing. */ + goto try_again; } + max_size = max_free_size; + max_chunk = max_free_chunk; + +is_free: srv_buf_pool_old_size = srv_buf_pool_size; /* Rewrite buf_pool->chunks. Copy everything but max_chunk. */ diff --git a/buf/buf0lru.c b/buf/buf0lru.c index 461dd752c3c..a5db248f585 100644 --- a/buf/buf0lru.c +++ b/buf/buf0lru.c @@ -868,12 +868,18 @@ buf_LRU_block_free_non_file_page( #ifdef UNIV_DEBUG /* Wipe contents of page to reveal possible stale pointers to it */ memset(block->frame, '\0', UNIV_PAGE_SIZE); - memset(block->page_zip.data, 0xff, block->page_zip.size); #else /* Wipe page_no and space_id */ memset(block->frame + FIL_PAGE_OFFSET, 0xfe, 4); memset(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xfe, 4); #endif + if (block->page_zip.data) { + /* TODO: return zip to an aligned pool */ + ut_free(block->page_zip.data); + block->page_zip.data = NULL; + block->page_zip.size = 0; + } + UT_LIST_ADD_FIRST(free, buf_pool->free, block); block->in_free_list = TRUE; -- 2.30.9