diff options
Diffstat (limited to 'storage/innobase/page/page0zip.cc')
-rw-r--r-- | storage/innobase/page/page0zip.cc | 199 |
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; } |