151
151
#endif /* !UNIV_HOTBACKUP */
153
153
/*************************************************************//**
154
Gets the number of elements in the dense page directory,
155
including deleted records (the free list).
156
@return number of elements in the dense page directory */
161
const page_zip_des_t* page_zip) /*!< in: compressed page */
163
/* Exclude the page infimum and supremum from the record count. */
164
return(page_dir_get_n_heap(page_zip->data) - PAGE_HEAP_NO_USER_LOW);
167
/*************************************************************//**
154
168
Gets the size of the compressed page trailer (the dense page directory),
155
169
including deleted records (the free list).
156
170
@return length of dense page directory, in bytes */
160
174
/*==============*/
161
175
const page_zip_des_t* page_zip) /*!< in: compressed page */
163
/* Exclude the page infimum and supremum from the record count. */
164
ulint size = PAGE_ZIP_DIR_SLOT_SIZE
165
* (page_dir_get_n_heap(page_zip->data)
166
- PAGE_HEAP_NO_USER_LOW);
177
return(PAGE_ZIP_DIR_SLOT_SIZE * page_zip_dir_elems(page_zip));
180
/*************************************************************//**
181
Gets an offset to the compressed page trailer (the dense page directory),
182
including deleted records (the free list).
183
@return offset of the dense page directory */
186
page_zip_dir_start_offs(
187
/*====================*/
188
const page_zip_des_t* page_zip, /*!< in: compressed page */
189
ulint n_dense) /*!< in: directory size */
191
ut_ad(n_dense * PAGE_ZIP_DIR_SLOT_SIZE < page_zip_get_size(page_zip));
193
return(page_zip_get_size(page_zip) - n_dense * PAGE_ZIP_DIR_SLOT_SIZE);
196
/*************************************************************//**
197
Gets a pointer to the compressed page trailer (the dense page directory),
198
including deleted records (the free list).
199
@param[in] page_zip compressed page
200
@param[in] n_dense number of entries in the directory
201
@return pointer to the dense page directory */
202
#define page_zip_dir_start_low(page_zip, n_dense) \
203
((page_zip)->data + page_zip_dir_start_offs(page_zip, n_dense))
204
/*************************************************************//**
205
Gets a pointer to the compressed page trailer (the dense page directory),
206
including deleted records (the free list).
207
@param[in] page_zip compressed page
208
@return pointer to the dense page directory */
209
#define page_zip_dir_start(page_zip) \
210
page_zip_dir_start_low(page_zip, page_zip_dir_elems(page_zip))
170
212
/*************************************************************//**
171
213
Gets the size of the compressed page trailer (the dense page directory),
2913
2953
page_zip_set_alloc(&d_stream, heap);
2915
if (UNIV_UNLIKELY(inflateInit2(&d_stream, UNIV_PAGE_SIZE_SHIFT)
2920
2955
d_stream.next_in = page_zip->data + PAGE_DATA;
2921
2956
/* Subtract the space reserved for
2922
2957
the page header and the end marker of the modification log. */
2923
2958
d_stream.avail_in = page_zip_get_size(page_zip) - (PAGE_DATA + 1);
2925
2959
d_stream.next_out = page + PAGE_ZIP_START;
2926
2960
d_stream.avail_out = UNIV_PAGE_SIZE - PAGE_ZIP_START;
2962
if (UNIV_UNLIKELY(inflateInit2(&d_stream, UNIV_PAGE_SIZE_SHIFT)
2928
2967
/* Decode the zlib header and the index information. */
2929
2968
if (UNIV_UNLIKELY(inflate(&d_stream, Z_BLOCK) != Z_OK)) {
3913
3948
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
3916
#ifdef UNIV_ZIP_DEBUG
3917
/** Set this variable in a debugger to disable page_zip_clear_rec().
3918
The only observable effect should be the compression ratio due to
3919
deleted records not being zeroed out. In rare cases, there can be
3920
page_zip_validate() failures on the node_ptr, trx_id and roll_ptr
3921
columns if the space is reallocated for a smaller record. */
3922
UNIV_INTERN ibool page_zip_clear_rec_disable;
3923
#endif /* UNIV_ZIP_DEBUG */
3925
3951
/**********************************************************************//**
3926
Clear an area on the uncompressed and compressed page, if possible. */
3952
Clear an area on the uncompressed and compressed page.
3953
Do not clear the data payload, as that would grow the modification log. */
3929
3956
page_zip_clear_rec(
3950
3980
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
3951
3981
rec_offs_extra_size(offsets));
3954
#ifdef UNIV_ZIP_DEBUG
3955
!page_zip_clear_rec_disable &&
3956
#endif /* UNIV_ZIP_DEBUG */
3958
+ 1 + ((heap_no - 1) >= 64)/* size of the log entry */
3959
+ page_zip_get_trailer_len(page_zip,
3960
dict_index_is_clust(index), NULL)
3961
< page_zip_get_size(page_zip)) {
3964
/* Clear only the data bytes, because the allocator and
3965
the decompressor depend on the extra bytes. */
3966
memset(rec, 0, rec_offs_data_size(offsets));
3968
if (!page_is_leaf(page)) {
3969
/* Clear node_ptr on the compressed page. */
3970
byte* storage = page_zip->data
3971
+ page_zip_get_size(page_zip)
3972
- (page_dir_get_n_heap(page)
3973
- PAGE_HEAP_NO_USER_LOW)
3974
* PAGE_ZIP_DIR_SLOT_SIZE;
3976
memset(storage - (heap_no - 1) * REC_NODE_PTR_SIZE,
3977
0, REC_NODE_PTR_SIZE);
3978
} else if (dict_index_is_clust(index)) {
3979
/* Clear trx_id and roll_ptr on the compressed page. */
3980
byte* storage = page_zip->data
3981
+ page_zip_get_size(page_zip)
3982
- (page_dir_get_n_heap(page)
3983
- PAGE_HEAP_NO_USER_LOW)
3984
* PAGE_ZIP_DIR_SLOT_SIZE;
3986
memset(storage - (heap_no - 1)
3987
* (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN),
3988
0, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
3991
/* Log that the data was zeroed out. */
3992
data = page_zip->data + page_zip->m_end;
3994
if (UNIV_UNLIKELY(heap_no - 1 >= 64)) {
3995
*data++ = (byte) (0x80 | (heap_no - 1) >> 7);
3998
*data++ = (byte) ((heap_no - 1) << 1 | 1);
4000
ut_ad((ulint) (data - page_zip->data)
4001
< page_zip_get_size(page_zip));
4002
page_zip->m_end = data - page_zip->data;
4003
page_zip->m_nonempty = TRUE;
4004
} else if (page_is_leaf(page) && dict_index_is_clust(index)) {
4005
/* Do not clear the record, because there is not enough space
4006
to log the operation. */
3983
if (!page_is_leaf(page)) {
3984
/* Clear node_ptr. On the compressed page,
3985
there is an array of node_ptr immediately before the
3986
dense page directory, at the very end of the page. */
3987
storage = page_zip_dir_start(page_zip);
3988
ut_ad(dict_index_get_n_unique_in_tree(index) ==
3989
rec_offs_n_fields(offsets) - 1);
3990
field = rec_get_nth_field(rec, offsets,
3991
rec_offs_n_fields(offsets) - 1,
3993
ut_ad(len == REC_NODE_PTR_SIZE);
3995
ut_ad(!rec_offs_any_extern(offsets));
3996
memset(field, 0, REC_NODE_PTR_SIZE);
3997
memset(storage - (heap_no - 1) * REC_NODE_PTR_SIZE,
3998
0, REC_NODE_PTR_SIZE);
3999
} else if (dict_index_is_clust(index)) {
4000
/* Clear trx_id and roll_ptr. On the compressed page,
4001
there is an array of these fields immediately before the
4002
dense page directory, at the very end of the page. */
4003
const ulint trx_id_pos
4004
= dict_col_get_clust_pos(
4005
dict_table_get_sys_col(
4006
index->table, DATA_TRX_ID), index);
4007
storage = page_zip_dir_start(page_zip);
4008
field = rec_get_nth_field(rec, offsets, trx_id_pos, &len);
4009
ut_ad(len == DATA_TRX_ID_LEN);
4011
memset(field, 0, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
4012
memset(storage - (heap_no - 1)
4013
* (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN),
4014
0, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
4008
4016
if (rec_offs_any_extern(offsets)) {