Commit e2c305f3 authored by marko's avatar marko

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.
parent 274f2bc6
......@@ -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. */
......
......@@ -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;
......
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