Commit 519ba6f4 authored by marko's avatar marko

branches/zip: Make buf_pool->page_hash point to buf_page_t instead of

buf_block_t.  Move the fields "hash" and "file_page_was_freed" from
buf_block_t to buf_page_t.

buf_page_in_file(): New function, for checking block state in assertions.
parent 17842af3
...@@ -791,11 +791,13 @@ btr_search_guess_on_hash( ...@@ -791,11 +791,13 @@ btr_search_guess_on_hash(
ulint space_id = page_get_space_id(page); ulint space_id = page_get_space_id(page);
mutex_enter(&buf_pool->mutex); mutex_enter(&buf_pool->mutex);
block = buf_page_hash_get(space_id, page_no); block = (buf_block_t*) buf_page_hash_get(space_id, page_no);
mutex_exit(&buf_pool->mutex); mutex_exit(&buf_pool->mutex);
} }
if (UNIV_UNLIKELY(!block)) { if (UNIV_UNLIKELY(!block)
|| UNIV_UNLIKELY(buf_block_get_state(block)
!= BUF_BLOCK_FILE_PAGE)) {
/* The block is most probably being freed. /* The block is most probably being freed.
The function buf_LRU_search_and_free_block() The function buf_LRU_search_and_free_block()
...@@ -1680,10 +1682,13 @@ btr_search_validate(void) ...@@ -1680,10 +1682,13 @@ btr_search_validate(void)
ulint page_no = page_get_page_no(page); ulint page_no = page_get_page_no(page);
ulint space_id= page_get_space_id(page); ulint space_id= page_get_space_id(page);
block = buf_page_hash_get(space_id, page_no); block = (buf_block_t*)
buf_page_hash_get(space_id, page_no);
} }
if (UNIV_UNLIKELY(!block)) { if (UNIV_UNLIKELY(!block)
|| UNIV_UNLIKELY(buf_block_get_state(block)
!= BUF_BLOCK_FILE_PAGE)) {
/* The block is most probably being freed. /* The block is most probably being freed.
The function buf_LRU_search_and_free_block() The function buf_LRU_search_and_free_block()
......
...@@ -603,7 +603,7 @@ buf_block_init( ...@@ -603,7 +603,7 @@ buf_block_init(
block->modify_clock = 0; block->modify_clock = 0;
#ifdef UNIV_DEBUG_FILE_ACCESSES #ifdef UNIV_DEBUG_FILE_ACCESSES
block->file_page_was_freed = FALSE; block->page.file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* UNIV_DEBUG_FILE_ACCESSES */
block->check_index_page_at_flush = FALSE; block->check_index_page_at_flush = FALSE;
...@@ -1069,11 +1069,11 @@ buf_pool_page_hash_rebuild(void) ...@@ -1069,11 +1069,11 @@ buf_pool_page_hash_rebuild(void)
for (j = 0; j < chunk->size; j++, block++) { for (j = 0; j < chunk->size; j++, block++) {
if (buf_block_get_state(block) if (buf_block_get_state(block)
== BUF_BLOCK_FILE_PAGE) { == BUF_BLOCK_FILE_PAGE) {
HASH_INSERT(buf_block_t, hash, page_hash, HASH_INSERT(buf_page_t, hash, page_hash,
buf_page_address_fold( buf_page_address_fold(
block->page.space, block->page.space,
block->page.offset), block->page.offset),
block); &block->page);
} }
} }
} }
...@@ -1203,10 +1203,14 @@ buf_page_peek_block( ...@@ -1203,10 +1203,14 @@ buf_page_peek_block(
mutex_enter_fast(&(buf_pool->mutex)); mutex_enter_fast(&(buf_pool->mutex));
block = buf_page_hash_get(space, offset); block = (buf_block_t*) buf_page_hash_get(space, offset);
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
if (UNIV_UNLIKELY(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE)) {
block = NULL;
}
return(block); return(block);
} }
...@@ -1224,9 +1228,9 @@ buf_reset_check_index_page_at_flush( ...@@ -1224,9 +1228,9 @@ buf_reset_check_index_page_at_flush(
mutex_enter_fast(&(buf_pool->mutex)); mutex_enter_fast(&(buf_pool->mutex));
block = buf_page_hash_get(space, offset); block = (buf_block_t*) buf_page_hash_get(space, offset);
if (block) { if (block && buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE) {
block->check_index_page_at_flush = FALSE; block->check_index_page_at_flush = FALSE;
} }
...@@ -1251,9 +1255,9 @@ buf_page_peek_if_search_hashed( ...@@ -1251,9 +1255,9 @@ buf_page_peek_if_search_hashed(
mutex_enter_fast(&(buf_pool->mutex)); mutex_enter_fast(&(buf_pool->mutex));
block = buf_page_hash_get(space, offset); block = (buf_block_t*) buf_page_hash_get(space, offset);
if (!block) { if (!block || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
is_hashed = FALSE; is_hashed = FALSE;
} else { } else {
is_hashed = block->is_hashed; is_hashed = block->is_hashed;
...@@ -1292,27 +1296,27 @@ This function should be called when we free a file page and want the ...@@ -1292,27 +1296,27 @@ This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless debug version to check that it is not accessed any more unless
reallocated. */ reallocated. */
buf_block_t* buf_page_t*
buf_page_set_file_page_was_freed( buf_page_set_file_page_was_freed(
/*=============================*/ /*=============================*/
/* out: control block if found from page hash table, /* out: control block if found in page hash table,
otherwise NULL */ otherwise NULL */
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint offset) /* in: page number */ ulint offset) /* in: page number */
{ {
buf_block_t* block; buf_page_t* bpage;
mutex_enter_fast(&(buf_pool->mutex)); mutex_enter_fast(&(buf_pool->mutex));
block = buf_page_hash_get(space, offset); bpage = buf_page_hash_get(space, offset);
if (block) { if (bpage) {
block->file_page_was_freed = TRUE; bpage->file_page_was_freed = TRUE;
} }
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
return(block); return(bpage);
} }
/************************************************************************ /************************************************************************
...@@ -1321,27 +1325,27 @@ This function should be called when we free a file page and want the ...@@ -1321,27 +1325,27 @@ This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless debug version to check that it is not accessed any more unless
reallocated. */ reallocated. */
buf_block_t* buf_page_t*
buf_page_reset_file_page_was_freed( buf_page_reset_file_page_was_freed(
/*===============================*/ /*===============================*/
/* out: control block if found from page hash table, /* out: control block if found in page hash table,
otherwise NULL */ otherwise NULL */
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint offset) /* in: page number */ ulint offset) /* in: page number */
{ {
buf_block_t* block; buf_page_t* bpage;
mutex_enter_fast(&(buf_pool->mutex)); mutex_enter_fast(&(buf_pool->mutex));
block = buf_page_hash_get(space, offset); bpage = buf_page_hash_get(space, offset);
if (block) { if (bpage) {
block->file_page_was_freed = FALSE; bpage->file_page_was_freed = FALSE;
} }
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
return(block); return(bpage);
} }
#endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* UNIV_DEBUG_FILE_ACCESSES */
...@@ -1388,18 +1392,19 @@ loop: ...@@ -1388,18 +1392,19 @@ loop:
block = guess; block = guess;
if (offset != block->page.offset if (offset != block->page.offset
|| space != block->page.space || space != block->page.space) {
|| buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
block = NULL; block = NULL;
} }
} }
if (block == NULL) { if (block == NULL) {
block = buf_page_hash_get(space, offset); block = (buf_block_t*) buf_page_hash_get(space, offset);
} }
if (block == NULL) { if (block == NULL
|| UNIV_UNLIKELY(buf_block_get_state(block)
!= BUF_BLOCK_FILE_PAGE)) {
/* Page not in buf_pool: needs to be read from file */ /* Page not in buf_pool: needs to be read from file */
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
...@@ -1454,7 +1459,7 @@ loop: ...@@ -1454,7 +1459,7 @@ loop:
buf_block_make_young(block); buf_block_make_young(block);
#ifdef UNIV_DEBUG_FILE_ACCESSES #ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->file_page_was_freed == FALSE); ut_a(!block->page.file_page_was_freed);
#endif #endif
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
...@@ -1644,7 +1649,7 @@ buf_page_optimistic_get_func( ...@@ -1644,7 +1649,7 @@ buf_page_optimistic_get_func(
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG_FILE_ACCESSES #ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->file_page_was_freed == FALSE); ut_a(block->page.file_page_was_freed == FALSE);
#endif #endif
if (UNIV_UNLIKELY(!accessed)) { if (UNIV_UNLIKELY(!accessed)) {
/* In the case of a first access, try to apply linear /* In the case of a first access, try to apply linear
...@@ -1748,7 +1753,7 @@ buf_page_get_known_nowait( ...@@ -1748,7 +1753,7 @@ buf_page_get_known_nowait(
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG_FILE_ACCESSES #ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->file_page_was_freed == FALSE); ut_a(block->page.file_page_was_freed == FALSE);
#endif #endif
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
...@@ -1850,8 +1855,8 @@ buf_page_init( ...@@ -1850,8 +1855,8 @@ buf_page_init(
ut_error; ut_error;
} }
HASH_INSERT(buf_block_t, hash, buf_pool->page_hash, HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
buf_page_address_fold(space, offset), block); buf_page_address_fold(space, offset), &block->page);
block->freed_page_clock = 0; block->freed_page_clock = 0;
...@@ -1869,7 +1874,7 @@ buf_page_init( ...@@ -1869,7 +1874,7 @@ buf_page_init(
block->left_side = TRUE; block->left_side = TRUE;
#ifdef UNIV_DEBUG_FILE_ACCESSES #ifdef UNIV_DEBUG_FILE_ACCESSES
block->file_page_was_freed = FALSE; block->page.file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* UNIV_DEBUG_FILE_ACCESSES */
} }
...@@ -2014,15 +2019,16 @@ buf_page_create( ...@@ -2014,15 +2019,16 @@ buf_page_create(
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
block = buf_page_hash_get(space, offset); block = (buf_block_t*) buf_page_hash_get(space, offset);
if (block != NULL) { if (block != NULL
&& buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE) {
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
ut_a(ibuf_count_get(buf_block_get_space(block), ut_a(ibuf_count_get(buf_block_get_space(block),
buf_block_get_page_no(block)) == 0); buf_block_get_page_no(block)) == 0);
#endif #endif
#ifdef UNIV_DEBUG_FILE_ACCESSES #ifdef UNIV_DEBUG_FILE_ACCESSES
block->file_page_was_freed = FALSE; block->page.file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* UNIV_DEBUG_FILE_ACCESSES */
/* Page can be found in buf_pool */ /* Page can be found in buf_pool */
...@@ -2393,7 +2399,7 @@ buf_validate(void) ...@@ -2393,7 +2399,7 @@ buf_validate(void)
block), block),
buf_block_get_page_no( buf_block_get_page_no(
block)) block))
== block); == &block->page);
n_page++; n_page++;
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
......
...@@ -640,15 +640,15 @@ buf_flush_try_page( ...@@ -640,15 +640,15 @@ buf_flush_try_page(
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
block = buf_page_hash_get(space, offset); block = (buf_block_t*) buf_page_hash_get(space, offset);
ut_a(!block || buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
if (!block) { if (!block) {
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
return(0); return(0);
} }
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); /* TODO */
mutex_enter(&block->mutex); mutex_enter(&block->mutex);
if (flush_type == BUF_FLUSH_LIST if (flush_type == BUF_FLUSH_LIST
...@@ -814,8 +814,9 @@ buf_flush_try_neighbors( ...@@ -814,8 +814,9 @@ buf_flush_try_neighbors(
for (i = low; i < high; i++) { for (i = low; i < high; i++) {
block = buf_page_hash_get(space, i); block = (buf_block_t*) buf_page_hash_get(space, i);
ut_a(!block || buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(!block
|| buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
if (!block) { if (!block) {
......
...@@ -959,10 +959,10 @@ buf_LRU_block_remove_hashed_page( ...@@ -959,10 +959,10 @@ buf_LRU_block_remove_hashed_page(
ut_error; ut_error;
} }
HASH_DELETE(buf_block_t, hash, buf_pool->page_hash, HASH_DELETE(buf_page_t, hash, buf_pool->page_hash,
buf_page_address_fold(block->page.space, buf_page_address_fold(block->page.space,
block->page.offset), block->page.offset),
block); (&block->page));
memset(block->frame + FIL_PAGE_OFFSET, 0xff, 4); memset(block->frame + FIL_PAGE_OFFSET, 0xff, 4);
memset(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xff, 4); memset(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xff, 4);
......
...@@ -310,10 +310,10 @@ This function should be called when we free a file page and want the ...@@ -310,10 +310,10 @@ This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless debug version to check that it is not accessed any more unless
reallocated. */ reallocated. */
buf_block_t* buf_page_t*
buf_page_set_file_page_was_freed( buf_page_set_file_page_was_freed(
/*=============================*/ /*=============================*/
/* out: control block if found from page hash table, /* out: control block if found in page hash table,
otherwise NULL */ otherwise NULL */
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint offset);/* in: page number */ ulint offset);/* in: page number */
...@@ -323,10 +323,10 @@ This function should be called when we free a file page and want the ...@@ -323,10 +323,10 @@ This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless debug version to check that it is not accessed any more unless
reallocated. */ reallocated. */
buf_block_t* buf_page_t*
buf_page_reset_file_page_was_freed( buf_page_reset_file_page_was_freed(
/*===============================*/ /*===============================*/
/* out: control block if found from page hash table, /* out: control block if found in page hash table,
otherwise NULL */ otherwise NULL */
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint offset); /* in: page number */ ulint offset); /* in: page number */
...@@ -556,6 +556,15 @@ buf_block_set_state( ...@@ -556,6 +556,15 @@ buf_block_set_state(
buf_block_t* block, /* in/out: pointer to control block */ buf_block_t* block, /* in/out: pointer to control block */
enum buf_page_state state); /* in: state */ enum buf_page_state state); /* in: state */
/************************************************************************* /*************************************************************************
Determines if a block is mapped to a tablespace. */
UNIV_INLINE
ibool
buf_page_in_file(
/*=============*/
/* out: TRUE if mapped */
const buf_page_t* bpage) /* in: pointer to control block */
__attribute__((pure));
/*************************************************************************
Get the flush type of a page. */ Get the flush type of a page. */
UNIV_INLINE UNIV_INLINE
enum buf_flush enum buf_flush
...@@ -701,7 +710,7 @@ buf_page_address_fold( ...@@ -701,7 +710,7 @@ buf_page_address_fold(
/********************************************************************** /**********************************************************************
Returns the control block of a file page, NULL if not found. */ Returns the control block of a file page, NULL if not found. */
UNIV_INLINE UNIV_INLINE
buf_block_t* buf_page_t*
buf_page_hash_get( buf_page_hash_get(
/*==============*/ /*==============*/
/* out: block, NULL if not found */ /* out: block, NULL if not found */
...@@ -733,6 +742,8 @@ struct buf_page_struct{ ...@@ -733,6 +742,8 @@ struct buf_page_struct{
page_zip_des_t zip; /* compressed page; zip.state page_zip_des_t zip; /* compressed page; zip.state
and zip.flush_type are relevant and zip.flush_type are relevant
for all pages */ for all pages */
buf_page_t* hash; /* node used in chaining to the page
hash table */
/* 2. Page flushing fields; protected by buf_pool->mutex */ /* 2. Page flushing fields; protected by buf_pool->mutex */
...@@ -749,6 +760,11 @@ struct buf_page_struct{ ...@@ -749,6 +760,11 @@ struct buf_page_struct{
modification to this block which has modification to this block which has
not yet been flushed on disk; zero if not yet been flushed on disk; zero if
all modifications are on disk */ all modifications are on disk */
#ifdef UNIV_DEBUG_FILE_ACCESSES
ibool file_page_was_freed;
/* this is set to TRUE when fsp
frees a page in buffer pool */
#endif /* UNIV_DEBUG_FILE_ACCESSES */
}; };
/* The buffer control block structure */ /* The buffer control block structure */
...@@ -773,8 +789,6 @@ struct buf_block_struct{ ...@@ -773,8 +789,6 @@ struct buf_block_struct{
contention on the buffer pool mutex */ contention on the buffer pool mutex */
rw_lock_t lock; /* read-write lock of the buffer rw_lock_t lock; /* read-write lock of the buffer
frame */ frame */
buf_block_t* hash; /* node used in chaining to the page
hash table */
ulint lock_hash_val:32;/* hashed value of the page address ulint lock_hash_val:32;/* hashed value of the page address
in the record lock hash table */ in the record lock hash table */
ulint check_index_page_at_flush:1; ulint check_index_page_at_flush:1;
...@@ -890,11 +904,6 @@ struct buf_block_struct{ ...@@ -890,11 +904,6 @@ struct buf_block_struct{
an s-latch here; so we can use the an s-latch here; so we can use the
debug utilities in sync0rw */ debug utilities in sync0rw */
#endif #endif
#ifdef UNIV_DEBUG_FILE_ACCESSES
ibool file_page_was_freed;
/* this is set to TRUE when fsp
frees a page in buffer pool */
#endif /* UNIV_DEBUG_FILE_ACCESSES */
}; };
/* Check if a block is in a valid state. */ /* Check if a block is in a valid state. */
......
...@@ -161,6 +161,29 @@ buf_block_set_state( ...@@ -161,6 +161,29 @@ buf_block_set_state(
ut_ad(buf_block_get_state(block) == state); ut_ad(buf_block_get_state(block) == state);
} }
/*************************************************************************
Determines if a block is mapped to a tablespace. */
UNIV_INLINE
ibool
buf_page_in_file(
/*=============*/
/* out: TRUE if mapped */
const buf_page_t* bpage) /* in: pointer to control block */
{
switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_FILE_PAGE:
return(TRUE);
case BUF_BLOCK_NOT_USED:
case BUF_BLOCK_READY_FOR_USE:
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
break;
}
return(FALSE);
}
/************************************************************************* /*************************************************************************
Get the flush type of a page. */ Get the flush type of a page. */
UNIV_INLINE UNIV_INLINE
...@@ -306,8 +329,9 @@ buf_block_align( ...@@ -306,8 +329,9 @@ buf_block_align(
page_no = mach_read_from_4(ptr + FIL_PAGE_OFFSET); page_no = mach_read_from_4(ptr + FIL_PAGE_OFFSET);
space_id = mach_read_from_4(ptr + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); space_id = mach_read_from_4(ptr + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
block = buf_page_hash_get(space_id, page_no); block = (buf_block_t*) buf_page_hash_get(space_id, page_no);
ut_ad(block); ut_ad(block);
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
ut_ad(block->frame == ptr); ut_ad(block->frame == ptr);
return(block); return(block);
} }
...@@ -550,14 +574,14 @@ buf_block_buf_fix_inc( ...@@ -550,14 +574,14 @@ buf_block_buf_fix_inc(
/********************************************************************** /**********************************************************************
Returns the control block of a file page, NULL if not found. */ Returns the control block of a file page, NULL if not found. */
UNIV_INLINE UNIV_INLINE
buf_block_t* buf_page_t*
buf_page_hash_get( buf_page_hash_get(
/*==============*/ /*==============*/
/* out: block, NULL if not found */ /* out: block, NULL if not found */
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint offset) /* in: offset of the page within space */ ulint offset) /* in: offset of the page within space */
{ {
buf_block_t* block; buf_page_t* bpage;
ulint fold; ulint fold;
ut_ad(buf_pool); ut_ad(buf_pool);
...@@ -569,12 +593,11 @@ buf_page_hash_get( ...@@ -569,12 +593,11 @@ buf_page_hash_get(
fold = buf_page_address_fold(space, offset); fold = buf_page_address_fold(space, offset);
HASH_SEARCH(hash, buf_pool->page_hash, fold, block, HASH_SEARCH(hash, buf_pool->page_hash, fold, bpage,
block->page.space == space bpage->space == space && bpage->offset == offset);
&& block->page.offset == offset); ut_a(!bpage || buf_page_in_file(bpage));
ut_a(!block || buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
return(block); return(bpage);
} }
/************************************************************************ /************************************************************************
......
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