Commit e8d77f6d authored by marko's avatar marko

branches/zip: Maintain a valid checksum for compressed-only pages kept in

the buffer pool.

buf_LRU_free_block(): When preserving the compressed page, compute the
checksum.  Also assert page_zip_validate().

buf_zip_decompress(): Add parameter "check" for enabling checksum tests.
Before decompressing a compressed-only page from the buffer pool, verify
the compressed page checksum.
parent 13faf3d3
......@@ -1982,13 +1982,31 @@ ibool
buf_zip_decompress(
/*===============*/
/* out: TRUE if successful */
buf_block_t* block) /* in/out: block */
buf_block_t* block, /* in/out: block */
ibool check) /* in: TRUE=verify the page checksum */
{
const byte* frame = block->page.zip.data;
ut_ad(buf_block_get_zip_size(block));
ut_a(buf_block_get_space(block) != 0);
if (UNIV_LIKELY(check)) {
ulint stamp_checksum = mach_read_from_4(
frame + FIL_PAGE_SPACE_OR_CHKSUM);
ulint calc_checksum = page_zip_calc_checksum(
frame, page_zip_get_size(&block->page.zip));
if (UNIV_UNLIKELY(stamp_checksum != calc_checksum)) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: compressed page checksum mismatch"
" (space %u page %u): %lu != %lu\n",
block->page.space, block->page.offset,
stamp_checksum, calc_checksum);
return(FALSE);
}
}
switch (fil_page_get_type(frame)) {
case FIL_PAGE_INDEX:
if (page_zip_decompress(&block->page.zip,
......@@ -2016,7 +2034,7 @@ buf_zip_decompress(
ut_print_timestamp(stderr);
fprintf(stderr,
"InnoDB: unknown compressed page"
" InnoDB: unknown compressed page"
" type %lu\n",
fil_page_get_type(frame));
return(FALSE);
......@@ -2146,7 +2164,7 @@ buf_page_init_for_read(
mtr_commit(&mtr);
}
buf_zip_decompress(block);
buf_zip_decompress(block, srv_use_checksums);
return(NULL);
case BUF_BLOCK_FILE_PAGE:
......@@ -2361,7 +2379,7 @@ buf_page_io_complete(
if (buf_block_get_zip_size(block)) {
frame = block->page.zip.data;
if (!buf_zip_decompress(block)) {
if (!buf_zip_decompress(block, FALSE)) {
goto corrupt;
}
......
......@@ -922,6 +922,25 @@ buf_LRU_free_block(
btr_search_drop_page_hash_index((buf_block_t*) bpage);
ut_a(bpage->buf_fix_count == 0);
if (bpage->zip.data && UNIV_LIKELY(srv_use_checksums)) {
/* Compute and stamp the compressed page
checksum while not holding any mutex. The
block is already half-freed
(BUF_BLOCK_REMOVE_HASH) and removed from
buf_pool->page_hash, thus inaccessible by any
other thread. */
#ifdef UNIV_ZIP_DEBUG
ut_a(page_zip_validate(&bpage->zip,
((buf_block_t*) bpage)->frame));
#endif /* UNIV_ZIP_DEBUG */
mach_write_to_4(
bpage->zip.data + FIL_PAGE_SPACE_OR_CHKSUM,
page_zip_calc_checksum(
bpage->zip.data,
page_zip_get_size(&bpage->zip)));
}
mutex_enter(&(buf_pool->mutex));
if (bpage->zip.data) {
......
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