Commit a9792eeb authored by marko's avatar marko

branches/zip: Bug fixes.

buf_page_io_complete(): On FIL_PAGE_TYPE_ZBLOB (compressed BLOB pages),
read the space_id from a different location.

page_zip_compress(), page_zip_write_rec(), page_zip_write_blob_ptr():
Replace page_simple_validate_new() with page_validate().

page_zip_clear_rec(): When running out of log space, do not attempt to
recompress the page, because the directory slots might be unbalanced and
the page_validate() assertion in page_zip_compress() would fail.
Instead, clear the BLOB pointers of the deleted record on the
uncompressed page, so that page_zip_validate() will succeed.

page_zip_validate(): Remove the comment about page_zip_clear_rec().
A mismatch always indicates a serious inconsistency.
parent 6e2fa8bc
...@@ -2004,8 +2004,15 @@ buf_page_io_complete( ...@@ -2004,8 +2004,15 @@ buf_page_io_complete(
should be the same as in block. */ should be the same as in block. */
read_page_no = mach_read_from_4((block->frame) read_page_no = mach_read_from_4((block->frame)
+ FIL_PAGE_OFFSET); + FIL_PAGE_OFFSET);
read_space_id = mach_read_from_4((block->frame) switch (fil_page_get_type(frame)) {
case FIL_PAGE_TYPE_ZBLOB:
read_space_id = mach_read_from_4(block->frame
+ FIL_PAGE_ZBLOB_SPACE_ID);
break;
default:
read_space_id = mach_read_from_4(block->frame
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
}
if (!block->space && trx_doublewrite_page_inside( if (!block->space && trx_doublewrite_page_inside(
block->offset)) { block->offset)) {
......
...@@ -652,7 +652,7 @@ page_zip_compress( ...@@ -652,7 +652,7 @@ page_zip_compress(
ut_a(page_is_comp((page_t*) page)); ut_a(page_is_comp((page_t*) page));
ut_a(fil_page_get_type((page_t*) page) == FIL_PAGE_INDEX); ut_a(fil_page_get_type((page_t*) page) == FIL_PAGE_INDEX);
ut_ad(page_simple_validate_new((page_t*) page)); ut_ad(page_validate((page_t*) page, index));
ut_ad(page_zip_simple_validate(page_zip)); ut_ad(page_zip_simple_validate(page_zip));
/* Check the data that will be omitted. */ /* Check the data that will be omitted. */
...@@ -2047,10 +2047,6 @@ page_zip_validate( ...@@ -2047,10 +2047,6 @@ page_zip_validate(
} }
if (memcmp(page + PAGE_HEADER, temp_page + PAGE_HEADER, if (memcmp(page + PAGE_HEADER, temp_page + PAGE_HEADER,
UNIV_PAGE_SIZE - PAGE_HEADER - FIL_PAGE_DATA_END)) { UNIV_PAGE_SIZE - PAGE_HEADER - FIL_PAGE_DATA_END)) {
/* This can happen if a record containing externally
stored columns was deleted and page_zip_clear_rec() failed
to clear the record. However, page_zip_validate() will
only be invoked in debug builds. */
fputs("page_zip_validate(): content mismatch\n", stderr); fputs("page_zip_validate(): content mismatch\n", stderr);
valid = FALSE; valid = FALSE;
} }
...@@ -2111,7 +2107,7 @@ page_zip_write_rec( ...@@ -2111,7 +2107,7 @@ page_zip_write_rec(
page = ut_align_down((rec_t*) rec, UNIV_PAGE_SIZE); page = ut_align_down((rec_t*) rec, UNIV_PAGE_SIZE);
ut_ad(page_zip_header_cmp(page_zip, page)); ut_ad(page_zip_header_cmp(page_zip, page));
ut_ad(page_simple_validate_new(page)); ut_ad(page_validate(page, index));
slot = page_zip_dir_find(page_zip, slot = page_zip_dir_find(page_zip,
ut_align_offset(rec, UNIV_PAGE_SIZE)); ut_align_offset(rec, UNIV_PAGE_SIZE));
...@@ -2403,7 +2399,7 @@ page_zip_write_blob_ptr( ...@@ -2403,7 +2399,7 @@ page_zip_write_blob_ptr(
ulint len; ulint len;
ut_ad(buf_block_get_page_zip(buf_block_align((byte*)rec)) == page_zip); ut_ad(buf_block_get_page_zip(buf_block_align((byte*)rec)) == page_zip);
ut_ad(page_simple_validate_new(page)); ut_ad(page_validate(page, index));
ut_ad(page_zip_simple_validate(page_zip)); ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip->size > PAGE_DATA + page_zip_dir_size(page_zip)); ut_ad(page_zip->size > PAGE_DATA + page_zip_dir_size(page_zip));
ut_ad(rec_offs_comp(offsets)); ut_ad(rec_offs_comp(offsets));
...@@ -2726,32 +2722,27 @@ page_zip_clear_rec( ...@@ -2726,32 +2722,27 @@ page_zip_clear_rec(
ut_ad(!*data); ut_ad(!*data);
ut_ad((ulint) (data - page_zip->data) < page_zip->size); ut_ad((ulint) (data - page_zip->data) < page_zip->size);
page_zip->m_end = data - page_zip->data; page_zip->m_end = data - page_zip->data;
#ifdef UNIV_ZIP_DEBUG
ut_a(page_zip_validate(page_zip, page));
#endif /* UNIV_ZIP_DEBUG */
} else { } else {
/* There is not enough space to log the clearing. /* Do not clear the record, because there is not enough space
Try to clear the block and to recompress the page. */ to log the operation. */
byte* buf = mem_alloc(rec_offs_data_size(offsets)); ulint i;
memcpy(buf, rec, rec_offs_data_size(offsets)); for (i = rec_offs_n_fields(offsets); i--; ) {
/* Clear all BLOB pointers in order to make
/* Do not touch the extra bytes, because the page_zip_validate() pass. */
decompressor depends on them. */ if (rec_offs_nth_extern(offsets, i)) {
memset(rec, 0, rec_offs_data_size(offsets)); ulint len;
if (UNIV_UNLIKELY(!page_zip_compress( byte* field = rec_get_nth_field(
page_zip, page, index, NULL))) { rec, offsets, i, &len);
/* Compression failed. Restore the block. */ memset(field + len - BTR_EXTERN_FIELD_REF_SIZE,
memcpy(rec, buf, rec_offs_data_size(offsets)); 0, BTR_EXTERN_FIELD_REF_SIZE);
/* From now on, page_zip_validate() would fail }
if a record containing externally stored columns
is being deleted. However, page_zip_validate()
will only be invoked in debug builds. Should
this be an issue, we could here zero out the
BLOB pointers contained in rec. */
} }
mem_free(buf);
} }
#ifdef UNIV_ZIP_DEBUG
ut_a(page_zip_validate(page_zip, page));
#endif /* UNIV_ZIP_DEBUG */
} }
/************************************************************************** /**************************************************************************
......
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