Commit 14b99876 authored by marko's avatar marko

branches/zip: Allow dirty blocks to be relocated. Allow a transition

to BUF_BLOCK_ZIP_DIRTY (discarding the uncompressed page corresponding
to a modified compressed page that has not been flushed to disk).

buf_page_can_relocate(): New function, modelled after
buf_flush_ready_for_replace().

buf_LRU_free_block(): Allow the transition to BUF_BLOCK_ZIP_DIRTY.

buf_flush_insert_into_flush_list(): Make the prototype public.

buf_buddy_relocate(): Remove an unnecessary switch statement.
Use buf_page_can_relocate() instead of buf_flush_ready_for_replace().

buf_page_peek(): Made UNIV_INLINE.

Document UNIV_ZIP_DEBUG.
parent 4861c59c
......@@ -400,19 +400,7 @@ buf_buddy_relocate(
mutex_enter(mutex);
if (buf_flush_ready_for_replace(bpage)) {
switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_ZIP_FREE:
case BUF_BLOCK_NOT_USED:
case BUF_BLOCK_READY_FOR_USE:
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
ut_error;
break;
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
case BUF_BLOCK_FILE_PAGE:
if (buf_page_can_relocate(bpage)) {
/* Relocate the compressed page. */
ut_a(bpage->zip.data == src);
memcpy(dst, src, size);
......@@ -420,7 +408,6 @@ buf_buddy_relocate(
mutex_exit(mutex);
return(TRUE);
}
}
mutex_exit(mutex);
} else if (i == buf_buddy_get_slot(sizeof(buf_page_t))) {
......@@ -444,7 +431,7 @@ buf_buddy_relocate(
case BUF_BLOCK_ZIP_PAGE:
mutex_enter(&buf_pool->zip_mutex);
if (buf_flush_ready_for_replace(bpage)) {
if (buf_page_can_relocate(bpage)) {
buf_page_t* dpage = (buf_page_t*) dst;
buf_page_t* b;
......
......@@ -1387,27 +1387,6 @@ buf_page_peek_if_search_hashed(
return(is_hashed);
}
/************************************************************************
Returns TRUE if the page can be found in the buffer pool hash table. NOTE
that it is possible that the page is not yet read from disk, though. */
ibool
buf_page_peek(
/*==========*/
/* out: TRUE if found from page hash table,
NOTE that the page is not necessarily yet read
from disk! */
ulint space, /* in: space id */
ulint offset) /* in: page number */
{
if (buf_page_peek_block(space, offset)) {
return(TRUE);
}
return(FALSE);
}
#ifdef UNIV_DEBUG_FILE_ACCESSES
/************************************************************************
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
......
......@@ -892,11 +892,18 @@ buf_LRU_free_block(
ut_ad(buf_page_in_file(bpage));
ut_ad(bpage->in_LRU_list);
if (!buf_flush_ready_for_replace(bpage)) {
if (!buf_page_can_relocate(bpage)) {
return(FALSE);
}
if (bpage->oldest_modification
&& (zip || buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE)) {
/* Do not completely free dirty blocks. */
return(FALSE);
}
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fprintf(stderr, "Putting space %lu page %lu to free list\n",
......@@ -926,7 +933,9 @@ buf_LRU_free_block(
ulint fold;
memcpy(b, bpage, sizeof *b);
b->state = BUF_BLOCK_ZIP_PAGE;
b->state = b->oldest_modification
? BUF_BLOCK_ZIP_DIRTY
: BUF_BLOCK_ZIP_PAGE;
fold = buf_page_address_fold(b->space,
b->offset);
......@@ -936,7 +945,11 @@ buf_LRU_free_block(
buf_LRU_add_block_low(b, TRUE);
if (b->state == BUF_BLOCK_ZIP_PAGE) {
buf_LRU_insert_zip_clean(b);
} else {
buf_flush_insert_into_flush_list(b);
}
mutex_enter(block_mutex);
......
......@@ -288,7 +288,7 @@ buf_page_make_young(
/************************************************************************
Returns TRUE if the page can be found in the buffer pool hash table. NOTE
that it is possible that the page is not yet read from disk, though. */
UNIV_INLINE
ibool
buf_page_peek(
/*==========*/
......@@ -702,6 +702,16 @@ buf_block_set_io_fix(
buf_block_t* block, /* in/out: control block */
enum buf_io_fix io_fix);/* in: io_fix state */
/************************************************************************
Determine if a buffer block can be relocated in memory. The block
can be dirty, but it must not be I/O-fixed or bufferfixed. */
UNIV_INLINE
ibool
buf_page_can_relocate(
/*==================*/
const buf_page_t* bpage) /* control block being relocated */
__attribute__((const));
/*************************************************************************
Determine if a block has been flagged old. */
UNIV_INLINE
......
......@@ -11,6 +11,22 @@ Created 11/5/1995 Heikki Tuuri
#include "buf0rea.h"
#include "mtr0mtr.h"
/************************************************************************
Returns TRUE if the page can be found in the buffer pool hash table. NOTE
that it is possible that the page is not yet read from disk, though. */
UNIV_INLINE
ibool
buf_page_peek(
/*==========*/
/* out: TRUE if found from page hash table,
NOTE that the page is not necessarily yet read
from disk! */
ulint space, /* in: space id */
ulint offset) /* in: page number */
{
return(buf_page_peek_block(space, offset) != NULL);
}
/************************************************************************
Reads the freed_page_clock of a buffer block. */
UNIV_INLINE
......@@ -386,6 +402,26 @@ buf_block_set_io_fix(
buf_page_set_io_fix(&block->page, io_fix);
}
/************************************************************************
Determine if a buffer block can be relocated in memory. The block
can be dirty, but it must not be I/O-fixed or bufferfixed. */
UNIV_INLINE
ibool
buf_page_can_relocate(
/*==================*/
const buf_page_t* bpage) /* control block being relocated */
{
#ifdef UNIV_SYNC_DEBUG
ut_a(mutex_own(&buf_pool->mutex));
ut_a(mutex_own(buf_page_get_mutex((buf_page_t*) bpage)));
#endif /* UNIV_SYNC_DEBUG */
ut_ad(buf_page_in_file(bpage));
ut_ad(bpage->in_LRU_list);
return(buf_page_get_io_fix(bpage) == BUF_IO_NONE
&& bpage->buf_fix_count == 0);
}
/*************************************************************************
Determine if a block has been flagged old. */
UNIV_INLINE
......
......@@ -14,6 +14,13 @@ Created 11/5/1995 Heikki Tuuri
#include "ut0byte.h"
#include "mtr0types.h"
/************************************************************************
Inserts a modified block into the flush list. */
void
buf_flush_insert_into_flush_list(
/*=============================*/
buf_page_t* bpage); /* in: block which is modified */
/************************************************************************
Remove a block from the flush list of modified blocks. */
......@@ -102,6 +109,7 @@ buf_flush_recv_note_modification(
/************************************************************************
Returns TRUE if the file page block is immediately suitable for replacement,
i.e., transition FILE_PAGE => NOT_USED allowed. */
ibool
buf_flush_ready_for_replace(
/*========================*/
......
......@@ -9,13 +9,6 @@ Created 11/5/1995 Heikki Tuuri
#include "buf0buf.h"
#include "mtr0mtr.h"
/************************************************************************
Inserts a modified block into the flush list. */
void
buf_flush_insert_into_flush_list(
/*=============================*/
buf_page_t* bpage); /* in: block which is modified */
/************************************************************************
Inserts a modified block into the flush list in the right sorted position.
This function is used by recovery, because there the modifications do not
......
......@@ -103,7 +103,8 @@ operations (very slow); also UNIV_DEBUG must be defined */
in sync0sync.c */
#define UNIV_BTR_PRINT /* enable functions for
printing B-trees */
#define UNIV_ZIP_DEBUG
#define UNIV_ZIP_DEBUG /* extensive consistency checks
for compressed pages */
#endif
#define UNIV_BTR_DEBUG /* check B-tree links */
......
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