mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 05:52:27 +01:00
branches/zip: Fix the decompression of deleted records containing externally
stored columns. page_zip_decompress(): We indeed need to clear the BLOB pointers of deleted records twice. This implies that we also need to invoke rec_get_offsets() twice for each record on a leaf page. Add clarifying comments. page_zip_clear_rec(): Add the flag page_zip_clear_rec_disable for disabling the clearing of deleted records.
This commit is contained in:
parent
8ebc271948
commit
bbcdac2c13
1 changed files with 34 additions and 21 deletions
|
@ -1762,12 +1762,19 @@ page_zip_decompress_low(
|
|||
goto zlib_error;
|
||||
}
|
||||
|
||||
/* Skip the BLOB pointer in case
|
||||
the record was deleted. The BLOB
|
||||
pointers will be initialized
|
||||
(copied from "externs" or cleared)
|
||||
/* Clear the BLOB pointer in case
|
||||
the record will be deleted and the
|
||||
space will not be reused. Note that
|
||||
the final initialization of the BLOB
|
||||
pointers (copying from "externs"
|
||||
or clearing) will have to take place
|
||||
only after the page modification log
|
||||
has been applied. */
|
||||
has been applied. Otherwise, we
|
||||
could end up with an uninitialized
|
||||
BLOB pointer when a record is deleted,
|
||||
reallocated and deleted. */
|
||||
memset(d_stream.next_out, 0,
|
||||
BTR_EXTERN_FIELD_REF_SIZE);
|
||||
d_stream.next_out
|
||||
+= BTR_EXTERN_FIELD_REF_SIZE;
|
||||
}
|
||||
|
@ -1905,10 +1912,10 @@ err_exit:
|
|||
ibool exists = !page_zip_dir_find_free(
|
||||
page_zip, ut_align_offset(
|
||||
rec, UNIV_PAGE_SIZE));
|
||||
if (UNIV_UNLIKELY(trx_id_col != ULINT_UNDEFINED)) {
|
||||
offsets = rec_get_offsets(rec, index, offsets,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
offsets = rec_get_offsets(rec, index, offsets,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
|
||||
if (UNIV_UNLIKELY(trx_id_col != ULINT_UNDEFINED)) {
|
||||
dst = rec_get_nth_field(rec, offsets,
|
||||
trx_id_col, &len);
|
||||
ut_ad(len >= DATA_TRX_ID_LEN
|
||||
|
@ -1916,21 +1923,12 @@ err_exit:
|
|||
storage -= DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN;
|
||||
memcpy(dst, storage,
|
||||
DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
|
||||
|
||||
if (UNIV_UNLIKELY(!exists)) {
|
||||
continue;
|
||||
}
|
||||
} else if (UNIV_LIKELY(exists)) {
|
||||
offsets = rec_get_offsets(rec, index, offsets,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if there are any externally stored
|
||||
columns in this existing (not deleted)
|
||||
record. For each externally stored column,
|
||||
restore or clear the BTR_EXTERN_FIELD_REF. */
|
||||
columns in this record. For each externally
|
||||
stored column, restore or clear the
|
||||
BTR_EXTERN_FIELD_REF. */
|
||||
|
||||
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
|
||||
if (!rec_offs_nth_extern(offsets, i)) {
|
||||
|
@ -1941,6 +1939,8 @@ err_exit:
|
|||
dst += len - BTR_EXTERN_FIELD_REF_SIZE;
|
||||
|
||||
if (UNIV_LIKELY(exists)) {
|
||||
/* Existing record:
|
||||
restore the BLOB pointer */
|
||||
externs -= BTR_EXTERN_FIELD_REF_SIZE;
|
||||
|
||||
memcpy(dst, externs,
|
||||
|
@ -1948,6 +1948,8 @@ err_exit:
|
|||
|
||||
page_zip->n_blobs++;
|
||||
} else {
|
||||
/* Deleted record:
|
||||
clear the BLOB pointer */
|
||||
memset(dst, 0,
|
||||
BTR_EXTERN_FIELD_REF_SIZE);
|
||||
}
|
||||
|
@ -2672,6 +2674,13 @@ page_zip_write_trx_id_and_roll_ptr(
|
|||
memcpy(storage, field, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
|
||||
}
|
||||
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
/* Set this variable in a debugger to disable page_zip_clear_rec().
|
||||
The only observable effect should be the compression ratio due to
|
||||
deleted records not being zeroed out. */
|
||||
ibool page_zip_clear_rec_disable;
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
|
||||
/**************************************************************************
|
||||
Clear an area on the uncompressed and compressed page, if possible. */
|
||||
static
|
||||
|
@ -2697,7 +2706,11 @@ page_zip_clear_rec(
|
|||
heap_no = rec_get_heap_no_new(rec);
|
||||
ut_ad(heap_no >= 2); /* exclude infimum and supremum */
|
||||
|
||||
if (page_zip->m_end
|
||||
if (
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
!page_zip_clear_rec_disable &&
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
page_zip->m_end
|
||||
+ 1 + ((heap_no - 1) >= 64)/* size of the log entry */
|
||||
+ page_zip_get_trailer_len(page_zip, index, NULL)
|
||||
< page_zip->size) {
|
||||
|
|
Loading…
Reference in a new issue