Commit 8332c45c authored by marko's avatar marko

branches/zip: Introduce buf_page_t, a common structure for compressed-only

and uncompressed buffer pool pages.

buf_block_t: Replace page_zip, space, and offset with buf_page_t page.
Replace some integers with bit-fields.

enum buf_block_state: Rename to buf_page_state.  Add BUF_BLOCK_ZIP_PAGE.

page_zip_des_t: Add the field "state".  Make the integer fields bit-fields.

page_zip_copy(): Document which fields are copied.
parent c476d38e
...@@ -603,7 +603,7 @@ buf_block_init( ...@@ -603,7 +603,7 @@ buf_block_init(
buf_block_t* block, /* in: pointer to control block */ buf_block_t* block, /* in: pointer to control block */
byte* frame) /* in: pointer to buffer frame */ byte* frame) /* in: pointer to buffer frame */
{ {
block->state = BUF_BLOCK_NOT_USED; block->page.zip.state = BUF_BLOCK_NOT_USED;
block->frame = frame; block->frame = frame;
...@@ -625,7 +625,7 @@ buf_block_init( ...@@ -625,7 +625,7 @@ buf_block_init(
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
block->n_pointers = 0; block->n_pointers = 0;
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
page_zip_des_init(&block->page_zip); page_zip_des_init(&block->page.zip);
mutex_create(&block->mutex, SYNC_BUF_BLOCK); mutex_create(&block->mutex, SYNC_BUF_BLOCK);
...@@ -798,7 +798,7 @@ buf_chunk_free( ...@@ -798,7 +798,7 @@ buf_chunk_free(
for (block = chunk->blocks; block < block_end; block++) { for (block = chunk->blocks; block < block_end; block++) {
ut_a(buf_block_get_state(block) == BUF_BLOCK_NOT_USED); ut_a(buf_block_get_state(block) == BUF_BLOCK_NOT_USED);
ut_a(!block->page_zip.data); ut_a(!block->page.zip.data);
ut_a(!block->in_LRU_list); ut_a(!block->in_LRU_list);
/* Remove the block from the free list. */ /* Remove the block from the free list. */
...@@ -1081,8 +1081,8 @@ buf_pool_page_hash_rebuild(void) ...@@ -1081,8 +1081,8 @@ buf_pool_page_hash_rebuild(void)
== BUF_BLOCK_FILE_PAGE) { == BUF_BLOCK_FILE_PAGE) {
HASH_INSERT(buf_block_t, hash, page_hash, HASH_INSERT(buf_block_t, hash, page_hash,
buf_page_address_fold( buf_page_address_fold(
block->space, block->page.space,
block->offset), block->page.offset),
block); block);
} }
} }
...@@ -1397,7 +1397,8 @@ buf_page_get_gen( ...@@ -1397,7 +1397,8 @@ buf_page_get_gen(
if (guess) { if (guess) {
block = guess; block = guess;
if ((offset != block->offset) || (space != block->space) if (offset != block->page.offset
|| space != block->page.space
|| buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) { || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
block = NULL; block = NULL;
...@@ -1799,12 +1800,12 @@ buf_page_init_for_backup_restore( ...@@ -1799,12 +1800,12 @@ buf_page_init_for_backup_restore(
block->n_fields = 1; block->n_fields = 1;
block->n_bytes = 0; block->n_bytes = 0;
block->left_side = TRUE; block->left_side = TRUE;
page_zip_des_init(&block->page_zip); page_zip_des_init(&block->page);
/* We assume that block->page_zip.data has been allocated /* We assume that block->page.data has been allocated
with zip_size == UNIV_PAGE_SIZE. */ with zip_size == UNIV_PAGE_SIZE. */
ut_ad(zip_size <= UNIV_PAGE_SIZE); ut_ad(zip_size <= UNIV_PAGE_SIZE);
ut_ad(ut_is_2pow(zip_size)); ut_ad(ut_is_2pow(zip_size));
block->page_zip.size = zip_size; block->page.size = zip_size;
#ifdef UNIV_DEBUG_FILE_ACCESSES #ifdef UNIV_DEBUG_FILE_ACCESSES
block->file_page_was_freed = FALSE; block->file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* UNIV_DEBUG_FILE_ACCESSES */
...@@ -2127,16 +2128,16 @@ buf_page_io_complete( ...@@ -2127,16 +2128,16 @@ buf_page_io_complete(
ulint read_space_id; ulint read_space_id;
byte* frame; byte* frame;
if (block->page_zip.size) { if (block->page.zip.size) {
ut_a(buf_block_get_space(block) != 0); ut_a(buf_block_get_space(block) != 0);
frame = block->page_zip.data; frame = block->page.zip.data;
switch (fil_page_get_type(frame)) { switch (fil_page_get_type(frame)) {
case FIL_PAGE_INDEX: case FIL_PAGE_INDEX:
if (block->frame) { if (block->frame) {
if (!page_zip_decompress( if (!page_zip_decompress(
&block->page_zip, &block->page.zip,
block->frame)) { block->frame)) {
goto corrupt; goto corrupt;
} }
...@@ -2150,7 +2151,7 @@ buf_page_io_complete( ...@@ -2150,7 +2151,7 @@ buf_page_io_complete(
case FIL_PAGE_TYPE_ZBLOB: case FIL_PAGE_TYPE_ZBLOB:
/* Copy to uncompressed storage. */ /* Copy to uncompressed storage. */
memcpy(block->frame, frame, memcpy(block->frame, frame,
block->page_zip.size); block->page.zip.size);
break; break;
default: default:
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
...@@ -2183,8 +2184,9 @@ buf_page_io_complete( ...@@ -2183,8 +2184,9 @@ buf_page_io_complete(
(ulong) buf_block_get_page_no(block)); (ulong) buf_block_get_page_no(block));
} else if (!read_space_id && !read_page_no) { } else if (!read_space_id && !read_page_no) {
/* This is likely an uninitialized page. */ /* This is likely an uninitialized page. */
} else if ((block->space && block->space != read_space_id) } else if ((block->page.space
|| block->offset != read_page_no) { && block->page.space != read_space_id)
|| block->page.offset != read_page_no) {
/* We did not compare space_id to read_space_id /* We did not compare space_id to read_space_id
if block->space == 0, because the field on the if block->space == 0, because the field on the
page may contain garbage in MySQL < 4.1.1, page may contain garbage in MySQL < 4.1.1,
...@@ -2197,13 +2199,14 @@ buf_page_io_complete( ...@@ -2197,13 +2199,14 @@ buf_page_io_complete(
"InnoDB: read in are %lu:%lu," "InnoDB: read in are %lu:%lu,"
" should be %lu:%lu!\n", " should be %lu:%lu!\n",
(ulong) read_space_id, (ulong) read_page_no, (ulong) read_space_id, (ulong) read_page_no,
(ulong) block->space, (ulong) block->offset); (ulong) block->page.space,
(ulong) block->page.offset);
} }
/* From version 3.23.38 up we store the page checksum /* From version 3.23.38 up we store the page checksum
to the 4 first bytes of the page end lsn field */ to the 4 first bytes of the page end lsn field */
if (buf_page_is_corrupted(frame, block->page_zip.size)) { if (buf_page_is_corrupted(frame, block->page.zip.size)) {
corrupt: corrupt:
fprintf(stderr, fprintf(stderr,
"InnoDB: Database page corruption on disk" "InnoDB: Database page corruption on disk"
...@@ -2211,15 +2214,15 @@ buf_page_io_complete( ...@@ -2211,15 +2214,15 @@ buf_page_io_complete(
"InnoDB: file read of page %lu.\n" "InnoDB: file read of page %lu.\n"
"InnoDB: You may have to recover" "InnoDB: You may have to recover"
" from a backup.\n", " from a backup.\n",
(ulong) block->offset); (ulong) block->page.offset);
buf_page_print(frame, block->page_zip.size); buf_page_print(frame, block->page.zip.size);
fprintf(stderr, fprintf(stderr,
"InnoDB: Database page corruption on disk" "InnoDB: Database page corruption on disk"
" or a failed\n" " or a failed\n"
"InnoDB: file read of page %lu.\n" "InnoDB: file read of page %lu.\n"
"InnoDB: You may have to recover" "InnoDB: You may have to recover"
" from a backup.\n", " from a backup.\n",
(ulong) block->offset); (ulong) block->page.offset);
fputs("InnoDB: It is also possible that" fputs("InnoDB: It is also possible that"
" your operating\n" " your operating\n"
"InnoDB: system has corrupted its" "InnoDB: system has corrupted its"
...@@ -2255,7 +2258,7 @@ buf_page_io_complete( ...@@ -2255,7 +2258,7 @@ buf_page_io_complete(
if (!recv_no_ibuf_operations) { if (!recv_no_ibuf_operations) {
ibuf_merge_or_delete_for_page( ibuf_merge_or_delete_for_page(
block, block->space, block->offset, block, block->page.space, block->page.offset,
buf_block_get_zip_size(block), TRUE); buf_block_get_zip_size(block), TRUE);
} }
} }
...@@ -2767,8 +2770,8 @@ buf_all_freed(void) ...@@ -2767,8 +2770,8 @@ buf_all_freed(void)
if (UNIV_LIKELY_NULL(block)) { if (UNIV_LIKELY_NULL(block)) {
fprintf(stderr, fprintf(stderr,
"Page %lu %lu still fixed or dirty\n", "Page %lu %lu still fixed or dirty\n",
(ulong) block->space, (ulong) block->page.space,
(ulong) block->offset); (ulong) block->page.offset);
ut_error; ut_error;
} }
} }
......
...@@ -263,7 +263,7 @@ buf_flush_buffered_writes(void) ...@@ -263,7 +263,7 @@ buf_flush_buffered_writes(void)
block = trx_doublewrite->buf_block_arr[i]; block = trx_doublewrite->buf_block_arr[i];
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
if (UNIV_LIKELY_NULL(block->page_zip.data)) { if (UNIV_LIKELY_NULL(block->page.zip.data)) {
/* No simple validate for compressed pages exists. */ /* No simple validate for compressed pages exists. */
continue; continue;
} }
...@@ -328,7 +328,7 @@ buf_flush_buffered_writes(void) ...@@ -328,7 +328,7 @@ buf_flush_buffered_writes(void)
for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len; for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len;
len2 += UNIV_PAGE_SIZE, i++) { len2 += UNIV_PAGE_SIZE, i++) {
block = trx_doublewrite->buf_block_arr[i]; block = trx_doublewrite->buf_block_arr[i];
if (UNIV_LIKELY(!block->page_zip.data) if (UNIV_LIKELY(!block->page.zip.data)
&& UNIV_UNLIKELY && UNIV_UNLIKELY
(memcmp(write_buf + len2 + (FIL_PAGE_LSN + 4), (memcmp(write_buf + len2 + (FIL_PAGE_LSN + 4),
write_buf + len2 write_buf + len2
...@@ -361,7 +361,7 @@ buf_flush_buffered_writes(void) ...@@ -361,7 +361,7 @@ buf_flush_buffered_writes(void)
for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len; for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len;
len2 += UNIV_PAGE_SIZE, i++) { len2 += UNIV_PAGE_SIZE, i++) {
block = trx_doublewrite->buf_block_arr[i]; block = trx_doublewrite->buf_block_arr[i];
if (UNIV_LIKELY(!block->page_zip.data) if (UNIV_LIKELY(!block->page.zip.data)
&& UNIV_UNLIKELY && UNIV_UNLIKELY
(memcmp(write_buf + len2 + (FIL_PAGE_LSN + 4), (memcmp(write_buf + len2 + (FIL_PAGE_LSN + 4),
write_buf + len2 write_buf + len2
...@@ -389,13 +389,13 @@ buf_flush_buffered_writes(void) ...@@ -389,13 +389,13 @@ buf_flush_buffered_writes(void)
for (i = 0; i < trx_doublewrite->first_free; i++) { for (i = 0; i < trx_doublewrite->first_free; i++) {
block = trx_doublewrite->buf_block_arr[i]; block = trx_doublewrite->buf_block_arr[i];
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
if (UNIV_UNLIKELY(block->page_zip.size)) { if (UNIV_UNLIKELY(block->page.zip.size)) {
fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER, fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
FALSE, buf_block_get_space(block), FALSE, buf_block_get_space(block),
block->page_zip.size, block->page.zip.size,
buf_block_get_page_no(block), 0, buf_block_get_page_no(block), 0,
block->page_zip.size, block->page.zip.size,
(void*)block->page_zip.data, (void*)block->page.zip.data,
(void*)block); (void*)block);
continue; continue;
} else if (UNIV_UNLIKELY } else if (UNIV_UNLIKELY
...@@ -471,13 +471,13 @@ buf_flush_post_to_doublewrite_buf( ...@@ -471,13 +471,13 @@ buf_flush_post_to_doublewrite_buf(
goto try_again; goto try_again;
} }
zip_size = block->page_zip.size; zip_size = block->page.zip.size;
if (UNIV_UNLIKELY(zip_size)) { if (UNIV_UNLIKELY(zip_size)) {
/* Copy the compressed page and clear the rest. */ /* Copy the compressed page and clear the rest. */
memcpy(trx_doublewrite->write_buf memcpy(trx_doublewrite->write_buf
+ UNIV_PAGE_SIZE * trx_doublewrite->first_free, + UNIV_PAGE_SIZE * trx_doublewrite->first_free,
block->page_zip.data, zip_size); block->page.zip.data, zip_size);
memset(trx_doublewrite->write_buf memset(trx_doublewrite->write_buf
+ UNIV_PAGE_SIZE * trx_doublewrite->first_free + UNIV_PAGE_SIZE * trx_doublewrite->first_free
+ zip_size, 0, UNIV_PAGE_SIZE - zip_size); + zip_size, 0, UNIV_PAGE_SIZE - zip_size);
...@@ -607,9 +607,9 @@ buf_flush_write_block_low( ...@@ -607,9 +607,9 @@ buf_flush_write_block_low(
block->newest_modification); block->newest_modification);
if (!srv_use_doublewrite_buf || !trx_doublewrite) { if (!srv_use_doublewrite_buf || !trx_doublewrite) {
fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER, fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
FALSE, buf_block_get_space(block), block->page_zip.size, FALSE, buf_block_get_space(block), block->page.zip.size,
buf_block_get_page_no(block), 0, block->page_zip.size buf_block_get_page_no(block), 0, block->page.zip.size
? block->page_zip.size : UNIV_PAGE_SIZE, ? block->page.zip.size : UNIV_PAGE_SIZE,
(void*)block->frame, (void*)block); (void*)block->frame, (void*)block);
} else { } else {
buf_flush_post_to_doublewrite_buf(block); buf_flush_post_to_doublewrite_buf(block);
......
...@@ -444,20 +444,20 @@ buf_LRU_get_free_block( ...@@ -444,20 +444,20 @@ buf_LRU_get_free_block(
ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE); ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
ut_a(!block->in_LRU_list); ut_a(!block->in_LRU_list);
if (block->page_zip.size != zip_size) { if (block->page.zip.size != zip_size) {
block->page_zip.size = zip_size; block->page.zip.size = zip_size;
block->page_zip.n_blobs = 0; block->page.zip.n_blobs = 0;
block->page_zip.m_start = 0; block->page.zip.m_start = 0;
block->page_zip.m_end = 0; block->page.zip.m_end = 0;
if (block->page_zip.data) { if (block->page.zip.data) {
ut_free(block->page_zip.data); ut_free(block->page.zip.data);
} }
if (zip_size) { if (zip_size) {
/* TODO: allocate zip from an aligned pool */ /* TODO: allocate zip from an aligned pool */
block->page_zip.data = ut_malloc(zip_size); block->page.zip.data = ut_malloc(zip_size);
} else { } else {
block->page_zip.data = NULL; block->page.zip.data = NULL;
} }
} }
...@@ -878,11 +878,11 @@ buf_LRU_block_free_non_file_page( ...@@ -878,11 +878,11 @@ buf_LRU_block_free_non_file_page(
memset(block->frame + FIL_PAGE_OFFSET, 0xfe, 4); memset(block->frame + FIL_PAGE_OFFSET, 0xfe, 4);
memset(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xfe, 4); memset(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xfe, 4);
#endif #endif
if (block->page_zip.data) { if (block->page.zip.data) {
/* TODO: return zip to an aligned pool */ /* TODO: return zip to an aligned pool */
ut_free(block->page_zip.data); ut_free(block->page.zip.data);
block->page_zip.data = NULL; block->page.zip.data = NULL;
block->page_zip.size = 0; block->page.zip.size = 0;
} }
UT_LIST_ADD_FIRST(free, buf_pool->free, block); UT_LIST_ADD_FIRST(free, buf_pool->free, block);
...@@ -920,21 +920,22 @@ buf_LRU_block_remove_hashed_page( ...@@ -920,21 +920,22 @@ buf_LRU_block_remove_hashed_page(
buf_block_modify_clock_inc(block); buf_block_modify_clock_inc(block);
hashed_block = buf_page_hash_get(block->space, block->offset); hashed_block = buf_page_hash_get(block->page.space,
block->page.offset);
if (UNIV_UNLIKELY(block != hashed_block)) { if (UNIV_UNLIKELY(block != hashed_block)) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: page %lu %lu not found" "InnoDB: Error: page %lu %lu not found"
" in the hash table\n", " in the hash table\n",
(ulong) block->space, (ulong) block->page.space,
(ulong) block->offset); (ulong) block->page.offset);
if (hashed_block) { if (hashed_block) {
fprintf(stderr, fprintf(stderr,
"InnoDB: In hash table we find block" "InnoDB: In hash table we find block"
" %p of %lu %lu which is not %p\n", " %p of %lu %lu which is not %p\n",
(const void*) hashed_block, (const void*) hashed_block,
(ulong) hashed_block->space, (ulong) hashed_block->page.space,
(ulong) hashed_block->offset, (ulong) hashed_block->page.offset,
(void*) block); (void*) block);
} }
...@@ -948,7 +949,8 @@ buf_LRU_block_remove_hashed_page( ...@@ -948,7 +949,8 @@ buf_LRU_block_remove_hashed_page(
} }
HASH_DELETE(buf_block_t, hash, buf_pool->page_hash, HASH_DELETE(buf_block_t, hash, buf_pool->page_hash,
buf_page_address_fold(block->space, block->offset), buf_page_address_fold(block->page.space,
block->page.offset),
block); block);
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);
......
...@@ -134,7 +134,7 @@ buf_read_page_low( ...@@ -134,7 +134,7 @@ buf_read_page_low(
if (zip_size) { if (zip_size) {
*err = fil_io(OS_FILE_READ | wake_later, *err = fil_io(OS_FILE_READ | wake_later,
sync, space, zip_size, offset, 0, zip_size, sync, space, zip_size, offset, 0, zip_size,
(void*) block->page_zip.data, (void*) block); (void*) block->page.zip.data, (void*) block);
} else { } else {
*err = fil_io(OS_FILE_READ | wake_later, *err = fil_io(OS_FILE_READ | wake_later,
sync, space, 0, offset, 0, UNIV_PAGE_SIZE, sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
......
...@@ -2660,7 +2660,8 @@ fil_create_new_single_table_tablespace( ...@@ -2660,7 +2660,8 @@ fil_create_new_single_table_tablespace(
page_zip_des_t page_zip; page_zip_des_t page_zip;
page_zip.size = zip_size; page_zip.size = zip_size;
page_zip.data = page + UNIV_PAGE_SIZE; page_zip.data = page + UNIV_PAGE_SIZE;
page_zip.n_blobs = page_zip.m_start = page_zip.m_end = 0; page_zip.state = page_zip.n_blobs
= page_zip.m_start = page_zip.m_end = 0;
buf_flush_init_for_writing(page, &page_zip, ut_dulint_zero); buf_flush_init_for_writing(page, &page_zip, ut_dulint_zero);
ret = os_file_write(path, file, page_zip.data, 0, 0, zip_size); ret = os_file_write(path, file, page_zip.data, 0, 0, zip_size);
} }
......
...@@ -66,8 +66,12 @@ extern ulint srv_buf_pool_write_requests; /* variable to count write request ...@@ -66,8 +66,12 @@ extern ulint srv_buf_pool_write_requests; /* variable to count write request
issued */ issued */
/* States of a control block */ /* States of a control block */
enum buf_block_state { enum buf_page_state {
BUF_BLOCK_NOT_USED = 211, /* is in the free list */ BUF_BLOCK_ZIP_PAGE = 1, /* contains a compressed page only;
must be smaller than
BUF_BLOCK_NOT_USED;
cf. buf_block_state_valid() */
BUF_BLOCK_NOT_USED, /* is in the free list */
BUF_BLOCK_READY_FOR_USE, /* when buf_get_free_block returns BUF_BLOCK_READY_FOR_USE, /* when buf_get_free_block returns
a block, it is in this state */ a block, it is in this state */
BUF_BLOCK_FILE_PAGE, /* contains a buffered file page */ BUF_BLOCK_FILE_PAGE, /* contains a buffered file page */
...@@ -536,7 +540,7 @@ buf_block_dbg_add_level( ...@@ -536,7 +540,7 @@ buf_block_dbg_add_level(
/************************************************************************* /*************************************************************************
Gets the state of a block. */ Gets the state of a block. */
UNIV_INLINE UNIV_INLINE
enum buf_block_state enum buf_page_state
buf_block_get_state( buf_block_get_state(
/*================*/ /*================*/
/* out: state */ /* out: state */
...@@ -549,7 +553,7 @@ void ...@@ -549,7 +553,7 @@ void
buf_block_set_state( 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_block_state state); /* in: state */ enum buf_page_state state); /* in: state */
/************************************************************************* /*************************************************************************
Map a block to a file page. */ Map a block to a file page. */
UNIV_INLINE UNIV_INLINE
...@@ -702,25 +706,30 @@ buf_get_free_list_len(void); ...@@ -702,25 +706,30 @@ buf_get_free_list_len(void);
/* The common buffer control block structure
for compressed and uncompressed frames */
struct buf_page_struct{
ulint space:32; /* tablespace id */
ulint offset:32; /* page number */
page_zip_des_t zip; /* compressed page; zip.state
is relevant for all pages */
};
/* The buffer control block structure */ /* The buffer control block structure */
struct buf_block_struct{ struct buf_block_struct{
/* 1. General fields */ /* 1. General fields */
ulint state; /* state of the control block: buf_page_t page; /* page information; this must
BUF_BLOCK_NOT_USED, ...; changing be the first field, so that
this is only allowed when a thread buf_pool->page_hash can point
has BOTH the buffer pool mutex AND to buf_page_t or buf_block_t */
block->mutex locked */
byte* frame; /* pointer to buffer frame which byte* frame; /* pointer to buffer frame which
is of size UNIV_PAGE_SIZE, and is of size UNIV_PAGE_SIZE, and
aligned to an address divisible by aligned to an address divisible by
UNIV_PAGE_SIZE */ UNIV_PAGE_SIZE */
ulint space; /* space id of the page */
ulint offset; /* page number within the space */
ulint lock_hash_val; /* hashed value of the page address
in the record lock hash table */
mutex_t mutex; /* mutex protecting this block: mutex_t mutex; /* mutex protecting this block:
state (also protected by the buffer state (also protected by the buffer
pool mutex), io_fix, buf_fix_count, pool mutex), io_fix, buf_fix_count,
...@@ -731,7 +740,9 @@ struct buf_block_struct{ ...@@ -731,7 +740,9 @@ struct buf_block_struct{
frame */ frame */
buf_block_t* hash; /* node used in chaining to the page buf_block_t* hash; /* node used in chaining to the page
hash table */ hash table */
ibool check_index_page_at_flush; ulint lock_hash_val:32;/* hashed value of the page address
in the record lock hash table */
ulint check_index_page_at_flush:1;
/* TRUE if we know that this is /* TRUE if we know that this is
an index page, and want the database an index page, and want the database
to check its consistency before flush; to check its consistency before flush;
...@@ -785,20 +796,20 @@ struct buf_block_struct{ ...@@ -785,20 +796,20 @@ struct buf_block_struct{
without holding any mutex or latch */ without holding any mutex or latch */
ibool old; /* TRUE if the block is in the old ibool old; /* TRUE if the block is in the old
blocks in the LRU list */ blocks in the LRU list */
ibool accessed; /* TRUE if the page has been accessed ulint accessed:1; /* TRUE if the page has been accessed
while in the buffer pool: read-ahead while in the buffer pool: read-ahead
may read in pages which have not been may read in pages which have not been
accessed yet; this is protected by accessed yet; this is protected by
block->mutex; a thread is allowed to block->mutex; a thread is allowed to
read this for heuristic purposes read this for heuristic purposes
without holding any mutex or latch */ without holding any mutex or latch */
ulint buf_fix_count; /* count of how manyfold this block ulint io_fix:2; /* if a read is pending to the frame,
is currently bufferfixed; this is
protected by block->mutex */
ulint io_fix; /* if a read is pending to the frame,
io_fix is BUF_IO_READ, in the case io_fix is BUF_IO_READ, in the case
of a write BUF_IO_WRITE, otherwise 0; of a write BUF_IO_WRITE, otherwise 0;
this is protected by block->mutex */ this is protected by block->mutex */
ulint buf_fix_count:29;/* count of how manyfold this block
is currently bufferfixed; this is
protected by block->mutex */
/* 4. Optimistic search field */ /* 4. Optimistic search field */
dulint modify_clock; /* this clock is incremented every dulint modify_clock; /* this clock is incremented every
...@@ -835,26 +846,23 @@ struct buf_block_struct{ ...@@ -835,26 +846,23 @@ struct buf_block_struct{
An exception to this is when we init or create a page An exception to this is when we init or create a page
in the buffer pool in buf0buf.c. */ in the buffer pool in buf0buf.c. */
ibool is_hashed; /* TRUE if hash index has already been
built on this page; note that it does
not guarantee that the index is
complete, though: there may have been
hash collisions, record deletions,
etc. */
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
ulint n_pointers; /* used in debugging: the number of ulint n_pointers; /* used in debugging: the number of
pointers in the adaptive hash index pointers in the adaptive hash index
pointing to this frame */ pointing to this frame */
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
ulint curr_n_fields; /* prefix length for hash indexing: ulint is_hashed:1; /* TRUE if hash index has already been
built on this page; note that it does
not guarantee that the index is
complete, though: there may have been
hash collisions, record deletions,
etc. */
ulint curr_n_fields:10;/* prefix length for hash indexing:
number of full fields */ number of full fields */
ulint curr_n_bytes; /* number of bytes in hash indexing */ ulint curr_n_bytes:15;/* number of bytes in hash indexing */
ibool curr_left_side; /* TRUE or FALSE in hash indexing */ ibool curr_left_side:1;/* TRUE or FALSE in hash indexing */
dict_index_t* index; /* Index for which the adaptive dict_index_t* index; /* Index for which the adaptive
hash index has been created. */ hash index has been created. */
/* TODO: how to protect this? */
page_zip_des_t page_zip; /* compressed page info */
/* 6. Debug fields */ /* 6. Debug fields */
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
rw_lock_t debug_latch; /* in the debug version, each thread rw_lock_t debug_latch; /* in the debug version, each thread
...@@ -959,9 +967,9 @@ struct buf_pool_struct{ ...@@ -959,9 +967,9 @@ struct buf_pool_struct{
LRU_old == NULL */ LRU_old == NULL */
}; };
/* Io_fix states of a control block; these must be != 0 */ /* Io_fix states of a control block; these must be 1..3 */
#define BUF_IO_READ 561 #define BUF_IO_READ 1
#define BUF_IO_WRITE 562 #define BUF_IO_WRITE 2
/************************************************************************ /************************************************************************
Let us list the consistency conditions for different control block states. Let us list the consistency conditions for different control block states.
......
...@@ -86,16 +86,17 @@ buf_pool_clock_tic(void) ...@@ -86,16 +86,17 @@ buf_pool_clock_tic(void)
/************************************************************************* /*************************************************************************
Gets the state of a block. */ Gets the state of a block. */
UNIV_INLINE UNIV_INLINE
enum buf_block_state enum buf_page_state
buf_block_get_state( buf_block_get_state(
/*================*/ /*================*/
/* out: state */ /* out: state */
const buf_block_t* block) /* in: pointer to the control block */ const buf_block_t* block) /* in: pointer to the control block */
{ {
enum buf_block_state state = block->state; enum buf_page_state state = block->page.zip.state;
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
switch (state) { switch (state) {
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_NOT_USED: case BUF_BLOCK_NOT_USED:
case BUF_BLOCK_READY_FOR_USE: case BUF_BLOCK_READY_FOR_USE:
case BUF_BLOCK_FILE_PAGE: case BUF_BLOCK_FILE_PAGE:
...@@ -116,12 +117,15 @@ void ...@@ -116,12 +117,15 @@ void
buf_block_set_state( 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_block_state state) /* in: state */ enum buf_page_state state) /* in: state */
{ {
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
enum buf_block_state old_state = buf_block_get_state(block); enum buf_page_state old_state = buf_block_get_state(block);
switch (old_state) { switch (old_state) {
case BUF_BLOCK_ZIP_PAGE:
ut_error;
break;
case BUF_BLOCK_NOT_USED: case BUF_BLOCK_NOT_USED:
ut_a(state == BUF_BLOCK_READY_FOR_USE); ut_a(state == BUF_BLOCK_READY_FOR_USE);
break; break;
...@@ -142,7 +146,7 @@ buf_block_set_state( ...@@ -142,7 +146,7 @@ buf_block_set_state(
break; break;
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
block->state = state; block->page.zip.state = state;
ut_ad(buf_block_get_state(block) == state); ut_ad(buf_block_get_state(block) == state);
} }
/************************************************************************* /*************************************************************************
...@@ -156,8 +160,8 @@ buf_block_set_file_page( ...@@ -156,8 +160,8 @@ buf_block_set_file_page(
ulint page_no)/* in: page number */ ulint page_no)/* in: page number */
{ {
buf_block_set_state(block, BUF_BLOCK_FILE_PAGE); buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
block->space = space; block->page.space = space;
block->offset = page_no; block->page.offset = page_no;
} }
/************************************************************************* /*************************************************************************
...@@ -189,7 +193,7 @@ buf_block_get_space( ...@@ -189,7 +193,7 @@ buf_block_get_space(
ut_ad(block); ut_ad(block);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
return(block->space); return(block->page.space);
} }
/************************************************************************* /*************************************************************************
...@@ -204,7 +208,7 @@ buf_block_get_page_no( ...@@ -204,7 +208,7 @@ buf_block_get_page_no(
ut_ad(block); ut_ad(block);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
return(block->offset); return(block->page.offset);
} }
/************************************************************************* /*************************************************************************
...@@ -216,7 +220,7 @@ buf_block_get_zip_size( ...@@ -216,7 +220,7 @@ buf_block_get_zip_size(
/* out: compressed page size, or 0 */ /* out: compressed page size, or 0 */
const buf_block_t* block) /* in: pointer to the control block */ const buf_block_t* block) /* in: pointer to the control block */
{ {
return(block->page_zip.size); return(block->page.zip.size);
} }
/************************************************************************* /*************************************************************************
...@@ -229,8 +233,8 @@ buf_block_get_page_zip( ...@@ -229,8 +233,8 @@ buf_block_get_page_zip(
/* out: compressed page descriptor, or NULL */ /* out: compressed page descriptor, or NULL */
buf_block_t* block) /* in: pointer to the control block */ buf_block_t* block) /* in: pointer to the control block */
{ {
if (UNIV_LIKELY_NULL(block->page_zip.data)) { if (UNIV_LIKELY_NULL(block->page.zip.data)) {
return(&block->page_zip); return(&block->page.zip);
} }
return(NULL); return(NULL);
...@@ -517,7 +521,8 @@ buf_page_hash_get( ...@@ -517,7 +521,8 @@ 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, block,
(block->space == space) && (block->offset == offset)); block->page.space == space
&& block->page.offset == offset);
ut_a(!block || buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(!block || buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
return(block); return(block);
......
...@@ -9,6 +9,7 @@ Created 11/17/1995 Heikki Tuuri ...@@ -9,6 +9,7 @@ Created 11/17/1995 Heikki Tuuri
#ifndef buf0types_h #ifndef buf0types_h
#define buf0types_h #define buf0types_h
typedef struct buf_page_struct buf_page_t;
typedef struct buf_block_struct buf_block_t; typedef struct buf_block_struct buf_block_t;
typedef struct buf_chunk_struct buf_chunk_t; typedef struct buf_chunk_struct buf_chunk_t;
typedef struct buf_pool_struct buf_pool_t; typedef struct buf_pool_struct buf_pool_t;
......
...@@ -31,11 +31,17 @@ page0*.h includes rem0rec.h and may include rem0rec.ic. */ ...@@ -31,11 +31,17 @@ page0*.h includes rem0rec.h and may include rem0rec.ic. */
struct page_zip_des_struct struct page_zip_des_struct
{ {
page_zip_t* data; /* compressed page data */ page_zip_t* data; /* compressed page data */
ulint size; /* total size of compressed page */ ulint state:3; /* state of the control block
ulint n_blobs; /* number of externally stored (cf. enum buf_page_state) */
columns */ ulint :1; /* reserved */
ulint m_start; /* start offset of modification log */ ulint n_blobs:12; /* number of externally stored
ulint m_end; /* end offset of modification log */ columns on the page; the maximum
is 744 on a 16 KiB page */
ulint size:16; /* compressed page size in bytes;
must be a power of 2 and
at least PAGE_ZIP_MIN_SIZE */
ulint m_start:16; /* start offset of modification log */
ulint m_end:16; /* end offset of modification log */
}; };
#define PAGE_ZIP_MIN_SIZE 1024 /* smallest page_zip_des_struct.size */ #define PAGE_ZIP_MIN_SIZE 1024 /* smallest page_zip_des_struct.size */
......
...@@ -348,7 +348,9 @@ Copy a page byte for byte, except for the file page header and trailer. */ ...@@ -348,7 +348,9 @@ Copy a page byte for byte, except for the file page header and trailer. */
void void
page_zip_copy( page_zip_copy(
/*==========*/ /*==========*/
page_zip_des_t* page_zip, /* out: copy of src_zip */ page_zip_des_t* page_zip, /* out: copy of src_zip
(n_blobs, m_start, m_end,
data[0..size-1]) */
page_t* page, /* out: copy of src */ page_t* page, /* out: copy of src */
const page_zip_des_t* src_zip, /* in: compressed page */ const page_zip_des_t* src_zip, /* in: compressed page */
const page_t* src, /* in: page */ const page_t* src, /* in: page */
......
...@@ -3571,7 +3571,9 @@ Copy a page byte for byte, except for the file page header and trailer. */ ...@@ -3571,7 +3571,9 @@ Copy a page byte for byte, except for the file page header and trailer. */
void void
page_zip_copy( page_zip_copy(
/*==========*/ /*==========*/
page_zip_des_t* page_zip, /* out: copy of src_zip */ page_zip_des_t* page_zip, /* out: copy of src_zip
(n_blobs, m_start, m_end,
data[0..size-1]) */
page_t* page, /* out: copy of src */ page_t* page, /* out: copy of src */
const page_zip_des_t* src_zip, /* in: compressed page */ const page_zip_des_t* src_zip, /* in: compressed page */
const page_t* src, /* in: page */ const page_t* src, /* in: page */
......
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