summaryrefslogtreecommitdiff
path: root/storage/innobase/page/page0zip.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/page/page0zip.cc')
-rw-r--r--storage/innobase/page/page0zip.cc199
1 files changed, 72 insertions, 127 deletions
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 12e75605dc9..36624f43d10 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -2,7 +2,7 @@
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2014, 2021, MariaDB Corporation.
+Copyright (c) 2014, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -411,14 +411,10 @@ static void page_zip_compress_write_log(buf_block_t *block,
{
ut_ad(!index->is_ibuf());
- if (mtr->get_log_mode() != MTR_LOG_ALL)
- {
- ut_ad(mtr->get_log_mode() == MTR_LOG_NONE ||
- mtr->get_log_mode() == MTR_LOG_NO_REDO);
+ if (!mtr->is_logged())
return;
- }
- const page_t *page= block->frame;
+ const page_t *page= block->page.frame;
const page_zip_des_t *page_zip= &block->page.zip;
/* Read the number of user records. */
ulint trailer_size= ulint(page_dir_get_n_heap(page_zip->data)) -
@@ -443,7 +439,6 @@ static void page_zip_compress_write_log(buf_block_t *block,
if (trailer_size)
mtr->zmemcpy(*block, page_zip_get_size(page_zip) - trailer_size,
trailer_size);
- block->page.status = buf_page_t::INIT_ON_FLUSH; /* because of mtr_t::init() */
}
/******************************************************//**
@@ -1280,7 +1275,7 @@ page_zip_compress(
my_bool cmp_per_index_enabled;
cmp_per_index_enabled = srv_cmp_per_index_enabled;
- page_t* page = block->frame;
+ page_t* page = block->page.frame;
page_zip_des_t* page_zip = &block->page.zip;
ut_a(page_is_comp(page));
@@ -1348,9 +1343,9 @@ page_zip_compress(
#endif /* PAGE_ZIP_COMPRESS_DBG */
page_zip_stat[page_zip->ssize - 1].compressed++;
if (cmp_per_index_enabled) {
- mutex_enter(&page_zip_stat_per_index_mutex);
+ mysql_mutex_lock(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index[ind_id].compressed++;
- mutex_exit(&page_zip_stat_per_index_mutex);
+ mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
}
if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE
@@ -1501,10 +1496,10 @@ err_exit:
page_zip_stat[page_zip->ssize - 1].compressed_usec
+= time_diff;
if (cmp_per_index_enabled) {
- mutex_enter(&page_zip_stat_per_index_mutex);
+ mysql_mutex_lock(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index[ind_id].compressed_usec
+= time_diff;
- mutex_exit(&page_zip_stat_per_index_mutex);
+ mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
}
return false;
}
@@ -1568,10 +1563,10 @@ err_exit:
page_zip_stat[page_zip->ssize - 1].compressed_ok++;
page_zip_stat[page_zip->ssize - 1].compressed_usec += time_diff;
if (cmp_per_index_enabled) {
- mutex_enter(&page_zip_stat_per_index_mutex);
+ mysql_mutex_lock(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index[ind_id].compressed_ok++;
page_zip_stat_per_index[ind_id].compressed_usec += time_diff;
- mutex_exit(&page_zip_stat_per_index_mutex);
+ mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
}
if (page_is_leaf(page)) {
@@ -1642,8 +1637,8 @@ page_zip_fields_decode(
return(NULL);
}
- table = dict_mem_table_create("ZIP_DUMMY", NULL, n, 0,
- DICT_TF_COMPACT, 0);
+ table = dict_table_t::create({C_STRING_WITH_LEN("ZIP_DUMMY")},
+ nullptr, n, 0, DICT_TF_COMPACT, 0);
index = dict_mem_index_create(table, "ZIP_DUMMY", 0, n);
index->n_uniq = static_cast<unsigned>(n) & dict_index_t::MAX_N_FIELDS;
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
@@ -3209,10 +3204,10 @@ page_zip_decompress(
index_id_t index_id = btr_page_get_index_id(page);
if (srv_cmp_per_index_enabled) {
- mutex_enter(&page_zip_stat_per_index_mutex);
+ mysql_mutex_lock(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index[index_id].decompressed++;
page_zip_stat_per_index[index_id].decompressed_usec += time_diff;
- mutex_exit(&page_zip_stat_per_index_mutex);
+ mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
}
/* Update the stat counter for LRU policy. */
@@ -3534,7 +3529,7 @@ page_zip_write_rec_ext(
ulint len;
byte* externs = storage;
ulint n_ext = rec_offs_n_extern(offsets);
- const page_t* const page = block->frame;
+ const page_t* const page = block->page.frame;
page_zip_des_t* const page_zip = &block->page.zip;
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -3652,7 +3647,7 @@ void page_zip_write_rec(buf_block_t *block, const byte *rec,
const dict_index_t *index, const rec_offs *offsets,
ulint create, mtr_t *mtr)
{
- const page_t* const page = block->frame;
+ const page_t* const page = block->page.frame;
page_zip_des_t* const page_zip = &block->page.zip;
byte* data;
byte* storage;
@@ -3842,7 +3837,7 @@ page_zip_write_blob_ptr(
{
const byte* field;
byte* externs;
- const page_t* const page = block->frame;
+ const page_t* const page = block->page.frame;
page_zip_des_t* const page_zip = &block->page.zip;
ulint blob_no;
ulint len;
@@ -3906,7 +3901,7 @@ page_zip_write_node_ptr(
byte* storage;
page_zip_des_t* const page_zip = &block->page.zip;
- ut_d(const page_t* const page = block->frame);
+ ut_d(const page_t* const page = block->page.frame);
ut_ad(page_simple_validate_new(page));
ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip_get_size(page_zip)
@@ -3953,7 +3948,7 @@ page_zip_write_trx_id_and_roll_ptr(
{
page_zip_des_t* const page_zip = &block->page.zip;
- ut_d(const page_t* const page = block->frame);
+ ut_d(const page_t* const page = block->page.frame);
ut_ad(page_align(rec) == page);
ut_ad(page_simple_validate_new(page));
ut_ad(page_zip_simple_validate(page_zip));
@@ -4051,7 +4046,7 @@ page_zip_clear_rec(
byte* field;
ulint len;
- ut_ad(page_align(rec) == block->frame);
+ ut_ad(page_align(rec) == block->page.frame);
page_zip_des_t* const page_zip = &block->page.zip;
/* page_zip_validate() would fail here if a record
@@ -4059,7 +4054,7 @@ page_zip_clear_rec(
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!page_zip_dir_find(page_zip, page_offset(rec)));
ut_ad(page_zip_dir_find_free(page_zip, page_offset(rec)));
- ut_ad(page_zip_header_cmp(page_zip, block->frame));
+ ut_ad(page_zip_header_cmp(page_zip, block->page.frame));
heap_no = rec_get_heap_no_new(rec);
ut_ad(heap_no >= PAGE_HEAP_NO_USER_LOW);
@@ -4069,7 +4064,7 @@ page_zip_clear_rec(
MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
- if (!page_is_leaf(block->frame)) {
+ if (!page_is_leaf(block->page.frame)) {
/* Clear node_ptr. On the compressed page,
there is an array of node_ptr immediately before the
dense page directory, at the very end of the page. */
@@ -4135,7 +4130,7 @@ clear_page_zip:
void page_zip_rec_set_deleted(buf_block_t *block, rec_t *rec, bool flag,
mtr_t *mtr)
{
- ut_ad(page_align(rec) == block->frame);
+ ut_ad(page_align(rec) == block->page.frame);
byte *slot= page_zip_dir_find(&block->page.zip, page_offset(rec));
byte b= *slot;
if (flag)
@@ -4144,7 +4139,7 @@ void page_zip_rec_set_deleted(buf_block_t *block, rec_t *rec, bool flag,
b&= byte(~(PAGE_ZIP_DIR_SLOT_DEL >> 8));
mtr->zmemcpy<mtr_t::MAYBE_NOP>(*block, slot, &b, 1);
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(&block->page.zip, block->frame, nullptr));
+ ut_a(page_zip_validate(&block->page.zip, block->page.frame, nullptr));
#endif /* UNIV_ZIP_DEBUG */
}
@@ -4159,7 +4154,7 @@ page_zip_rec_set_owned(
ulint flag, /*!< in: the owned flag (nonzero=TRUE) */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
- ut_ad(page_align(rec) == block->frame);
+ ut_ad(page_align(rec) == block->page.frame);
page_zip_des_t *const page_zip= &block->page.zip;
byte *slot= page_zip_dir_find(page_zip, page_offset(rec));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
@@ -4182,8 +4177,8 @@ page_zip_dir_insert(
byte* rec, /*!< in: record to insert */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
- ut_ad(page_align(cursor->rec) == cursor->block->frame);
- ut_ad(page_align(rec) == cursor->block->frame);
+ ut_ad(page_align(cursor->rec) == cursor->block->page.frame);
+ ut_ad(page_align(rec) == cursor->block->page.frame);
page_zip_des_t *const page_zip= &cursor->block->page.zip;
ulint n_dense;
@@ -4276,7 +4271,7 @@ void page_zip_dir_delete(buf_block_t *block, byte *rec,
const dict_index_t *index, const rec_offs *offsets,
const byte *free, mtr_t *mtr)
{
- ut_ad(page_align(rec) == block->frame);
+ ut_ad(page_align(rec) == block->page.frame);
page_zip_des_t *const page_zip= &block->page.zip;
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -4290,22 +4285,22 @@ void page_zip_dir_delete(buf_block_t *block, byte *rec,
mach_write_to_2(rec - REC_NEXT,
free ? static_cast<uint16_t>(free - rec) : 0);
byte *page_free= my_assume_aligned<2>(PAGE_FREE + PAGE_HEADER +
- block->frame);
+ block->page.frame);
mtr->write<2>(*block, page_free, page_offset(rec));
byte *garbage= my_assume_aligned<2>(PAGE_GARBAGE + PAGE_HEADER +
- block->frame);
+ block->page.frame);
mtr->write<2>(*block, garbage, rec_offs_size(offsets) +
mach_read_from_2(garbage));
compile_time_assert(PAGE_GARBAGE == PAGE_FREE + 2);
memcpy_aligned<4>(PAGE_FREE + PAGE_HEADER + page_zip->data, page_free, 4);
byte *slot_rec= page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot_rec);
- uint16_t n_recs= page_get_n_recs(block->frame);
+ uint16_t n_recs= page_get_n_recs(block->page.frame);
ut_ad(n_recs);
- ut_ad(n_recs > 1 || page_get_page_no(block->frame) == index->page);
+ ut_ad(n_recs > 1 || page_get_page_no(block->page.frame) == index->page);
/* This could not be done before page_zip_dir_find(). */
byte *page_n_recs= my_assume_aligned<2>(PAGE_N_RECS + PAGE_HEADER +
- block->frame);
+ block->page.frame);
mtr->write<2>(*block, page_n_recs, n_recs - 1U);
memcpy_aligned<2>(PAGE_N_RECS + PAGE_HEADER + page_zip->data, page_n_recs,
2);
@@ -4342,14 +4337,14 @@ void page_zip_dir_delete(buf_block_t *block, byte *rec,
if (const ulint n_ext= rec_offs_n_extern(offsets))
{
ut_ad(index->is_primary());
- ut_ad(page_is_leaf(block->frame));
+ ut_ad(page_is_leaf(block->page.frame));
/* Shift and zero fill the array of BLOB pointers. */
ulint blob_no = page_zip_get_n_prev_extern(page_zip, rec, index);
ut_a(blob_no + n_ext <= page_zip->n_blobs);
byte *externs= page_zip->data + page_zip_get_size(page_zip) -
- (page_dir_get_n_heap(block->frame) - PAGE_HEAP_NO_USER_LOW) *
+ (page_dir_get_n_heap(block->page.frame) - PAGE_HEAP_NO_USER_LOW) *
PAGE_ZIP_CLUST_LEAF_SLOT_SIZE;
byte *ext_end= externs - page_zip->n_blobs * FIELD_REF_SIZE;
@@ -4382,9 +4377,9 @@ IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
non-clustered index, the caller must update the insert buffer free
bits in the same mini-transaction in such a way that the modification
will be redo-logged.
-@retval true on success
-@retval false on failure; the block will be left intact */
-bool
+@return error code
+@retval DB_FAIL on overflow; the block_zip will be left intact */
+dberr_t
page_zip_reorganize(
buf_block_t* block, /*!< in/out: page with compressed page;
on the compressed page, in: size;
@@ -4414,10 +4409,10 @@ page_zip_reorganize(
temp_block = buf_block_alloc();
btr_search_drop_page_hash_index(block, false);
- temp_page = temp_block->frame;
+ temp_page = temp_block->page.frame;
/* Copy the old page to temporary space */
- memcpy_aligned<UNIV_PAGE_SIZE_MIN>(temp_block->frame, block->frame,
+ memcpy_aligned<UNIV_PAGE_SIZE_MIN>(temp_page, block->page.frame,
srv_page_size);
/* Recreate the page: note that global data on page (possible
@@ -4435,20 +4430,22 @@ page_zip_reorganize(
/* Copy the records from the temporary space to the recreated page;
do not copy the lock bits yet */
- page_copy_rec_list_end_no_locks(block, temp_block,
- page_get_infimum_rec(temp_page),
- index, mtr);
+ dberr_t err = page_copy_rec_list_end_no_locks(
+ block, temp_block, page_get_infimum_rec(temp_page),
+ index, mtr);
/* Copy the PAGE_MAX_TRX_ID or PAGE_ROOT_AUTO_INC. */
memcpy_aligned<8>(page + (PAGE_HEADER + PAGE_MAX_TRX_ID),
temp_page + (PAGE_HEADER + PAGE_MAX_TRX_ID), 8);
/* PAGE_MAX_TRX_ID must be set on secondary index leaf pages. */
- ut_ad(dict_index_is_clust(index) || !page_is_leaf(temp_page)
+ ut_ad(err != DB_SUCCESS
+ || index->is_clust() || !page_is_leaf(temp_page)
|| page_get_max_trx_id(page) != 0);
/* PAGE_MAX_TRX_ID must be zero on non-leaf pages other than
clustered index root pages. */
- ut_ad(page_get_max_trx_id(page) == 0
- || (dict_index_is_clust(index)
+ ut_ad(err != DB_SUCCESS
+ || page_get_max_trx_id(page) == 0
+ || (index->is_clust()
? !page_has_siblings(temp_page)
: page_is_leaf(temp_page)));
@@ -4480,14 +4477,13 @@ page_zip_reorganize(
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
}
- buf_block_free(temp_block);
- return false;
+ err = DB_FAIL;
+ } else {
+ lock_move_reorganize_page(block, temp_block);
}
- lock_move_reorganize_page(block, temp_block);
-
buf_block_free(temp_block);
- return true;
+ return err;
}
/**********************************************************************//**
@@ -4503,7 +4499,7 @@ page_zip_copy_recs(
dict_index_t* index, /*!< in: index of the B-tree */
mtr_t* mtr) /*!< in: mini-transaction */
{
- page_t* page = block->frame;
+ page_t* page = block->page.frame;
page_zip_des_t* page_zip = &block->page.zip;
ut_ad(mtr->memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX));
@@ -4561,7 +4557,7 @@ page_zip_copy_recs(
to the compressed data page. */
{
page_zip_t* data = page_zip->data;
- memcpy(page_zip, src_zip, sizeof *page_zip);
+ new (page_zip) page_zip_des_t(*src_zip, false);
page_zip->data = data;
}
ut_ad(page_zip_get_trailer_len(page_zip, dict_index_is_clust(index))
@@ -4590,37 +4586,26 @@ page_zip_copy_recs(
#endif /* !UNIV_INNOCHECKSUM */
/** Calculate the compressed page checksum.
-@param[in] data compressed page
-@param[in] size size of compressed page
-@param[in] algo algorithm to use
+@param data compressed page
+@param size size of compressed page
+@param use_adler whether to use Adler32 instead of a XOR of 3 CRC-32C
@return page checksum */
-uint32_t
-page_zip_calc_checksum(
- const void* data,
- ulint size,
- srv_checksum_algorithm_t algo)
+uint32_t page_zip_calc_checksum(const void *data, size_t size, bool use_adler)
{
uLong adler;
const Bytef* s = static_cast<const byte*>(data);
/* Exclude FIL_PAGE_SPACE_OR_CHKSUM, FIL_PAGE_LSN,
and FIL_PAGE_FILE_FLUSH_LSN from the checksum. */
+ ut_ad(size > FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
- switch (algo) {
- case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
- case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
- case SRV_CHECKSUM_ALGORITHM_CRC32:
- case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
- ut_ad(size > FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+ if (!use_adler) {
return ut_crc32(s + FIL_PAGE_OFFSET,
FIL_PAGE_LSN - FIL_PAGE_OFFSET)
^ ut_crc32(s + FIL_PAGE_TYPE, 2)
^ ut_crc32(s + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
size - FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
- case SRV_CHECKSUM_ALGORITHM_INNODB:
- case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
- ut_ad(size > FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
-
+ } else {
adler = adler32(0L, s + FIL_PAGE_OFFSET,
FIL_PAGE_LSN - FIL_PAGE_OFFSET);
adler = adler32(adler, s + FIL_PAGE_TYPE, 2);
@@ -4630,15 +4615,7 @@ page_zip_calc_checksum(
- FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
return(uint32_t(adler));
- case SRV_CHECKSUM_ALGORITHM_NONE:
- case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
- return(BUF_NO_CHECKSUM_MAGIC);
- /* no default so the compiler will emit a warning if new enum
- is added and not handled here */
}
-
- ut_error;
- return(0);
}
/** Validate the checksum on a ROW_FORMAT=COMPRESSED page.
@@ -4647,13 +4624,6 @@ page_zip_calc_checksum(
@return whether the stored checksum matches innodb_checksum_algorithm */
bool page_zip_verify_checksum(const byte *data, size_t size)
{
- const srv_checksum_algorithm_t curr_algo =
- static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-
- if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
- return true;
- }
-
if (buf_is_zeroes(span<const byte>(data, size))) {
return true;
}
@@ -4661,62 +4631,37 @@ bool page_zip_verify_checksum(const byte *data, size_t size)
const uint32_t stored = mach_read_from_4(
data + FIL_PAGE_SPACE_OR_CHKSUM);
- uint32_t calc = page_zip_calc_checksum(data, size, curr_algo);
+ uint32_t calc = page_zip_calc_checksum(data, size, false);
#ifdef UNIV_INNOCHECKSUM
+ extern FILE* log_file;
+ extern uint32_t cur_page_num;
+
if (log_file) {
fprintf(log_file, "page::" UINT32PF ";"
- " %s checksum: calculated = " UINT32PF ";"
+ " checksum: calculated = " UINT32PF ";"
" recorded = " UINT32PF "\n", cur_page_num,
- buf_checksum_algorithm_name(
- static_cast<srv_checksum_algorithm_t>(
- srv_checksum_algorithm)),
calc, stored);
}
-
- if (!strict_verify) {
- const uint32_t crc32 = page_zip_calc_checksum(
- data, size, SRV_CHECKSUM_ALGORITHM_CRC32);
-
- if (log_file) {
- fprintf(log_file, "page::" UINT32PF ": crc32 checksum:"
- " calculated = " UINT32PF "; recorded = " UINT32PF "\n",
- cur_page_num, crc32, stored);
- fprintf(log_file, "page::" UINT32PF ": none checksum:"
- " calculated = %lu; recorded = " UINT32PF "\n",
- cur_page_num, BUF_NO_CHECKSUM_MAGIC, stored);
- }
- }
#endif /* UNIV_INNOCHECKSUM */
if (stored == calc) {
return(TRUE);
}
- switch (curr_algo) {
+#ifndef UNIV_INNOCHECKSUM
+ switch (srv_checksum_algorithm) {
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
- case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
- case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
- return FALSE;
- case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
- case SRV_CHECKSUM_ALGORITHM_CRC32:
+ break;
+ default:
if (stored == BUF_NO_CHECKSUM_MAGIC) {
return(TRUE);
}
- return stored == page_zip_calc_checksum(
- data, size, SRV_CHECKSUM_ALGORITHM_INNODB);
- case SRV_CHECKSUM_ALGORITHM_INNODB:
- if (stored == BUF_NO_CHECKSUM_MAGIC) {
- return TRUE;
- }
-
- return stored == page_zip_calc_checksum(
- data, size, SRV_CHECKSUM_ALGORITHM_CRC32);
- case SRV_CHECKSUM_ALGORITHM_NONE:
- return TRUE;
+ return stored == page_zip_calc_checksum(data, size, true);
}
+#endif /* !UNIV_INNOCHECKSUM */
return FALSE;
}