diff options
Diffstat (limited to 'storage/innobase/btr')
-rw-r--r-- | storage/innobase/btr/btr0btr.cc | 561 | ||||
-rw-r--r-- | storage/innobase/btr/btr0bulk.cc | 142 | ||||
-rw-r--r-- | storage/innobase/btr/btr0cur.cc | 334 |
3 files changed, 501 insertions, 536 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index dea97787a88..4fb0fe6cd4c 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -268,8 +268,7 @@ btr_root_get( /* Intended to be used for segment list access. SX lock doesn't block reading user data by other threads. And block the segment list access by others.*/ - buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH, - mtr); + buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH, mtr); return(root ? buf_block_get_frame(root) : NULL); } @@ -442,22 +441,25 @@ btr_page_create( page_t* page = buf_block_get_frame(block); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); + byte *index_id= &page[PAGE_HEADER + PAGE_INDEX_ID]; - if (page_zip) { + if (UNIV_LIKELY_NULL(page_zip)) { page_create_zip(block, index, level, 0, mtr); + mach_write_to_8(index_id, index->id); + page_zip_write_header(page_zip, index_id, 8, mtr); } else { page_create(block, mtr, dict_table_is_comp(index->table), dict_index_is_spatial(index)); /* Set the level of the new index page */ - btr_page_set_level(page, NULL, level, mtr); + mtr->write<2,mtr_t::OPT>(*block, PAGE_HEADER + PAGE_LEVEL + + block->frame, level); + mtr->write<8,mtr_t::OPT>(*block, index_id, index->id); } /* For Spatial Index, initialize the Split Sequence Number */ if (dict_index_is_spatial(index)) { page_set_ssn_id(block, page_zip, 0, mtr); } - - btr_page_set_index_id(page, page_zip, index->id, mtr); } /**************************************************************//** @@ -471,15 +473,13 @@ btr_page_alloc_for_ibuf( dict_index_t* index, /*!< in: index tree */ mtr_t* mtr) /*!< in: mtr */ { - fil_addr_t node_addr; - page_t* root; - page_t* new_page; buf_block_t* new_block; - root = btr_root_get(index, mtr); + buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH, mtr); - node_addr = flst_get_first(PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST - + root); + fil_addr_t node_addr = flst_get_first(PAGE_HEADER + + PAGE_BTR_IBUF_FREE_LIST + + root->frame); ut_a(node_addr.page != FIL_NULL); new_block = buf_page_get( @@ -487,14 +487,12 @@ btr_page_alloc_for_ibuf( index->table->space->zip_size(), RW_X_LATCH, mtr); - new_page = buf_block_get_frame(new_block); buf_block_dbg_add_level(new_block, SYNC_IBUF_TREE_NODE_NEW); - flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, - new_page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, + flst_remove(root, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, + new_block, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, mtr); - ut_ad(flst_validate(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, - mtr)); + ut_d(flst_validate(root, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr)); return(new_block); } @@ -525,16 +523,12 @@ btr_page_alloc_low( is already X-latched in mtr, do not initialize the page. */ { - fseg_header_t* seg_header; - page_t* root; - - root = btr_root_get(index, mtr); + page_t* root = btr_root_get(index, mtr); - if (level == 0) { - seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF; - } else { - seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP; - } + fseg_header_t* seg_header = (level + ? PAGE_HEADER + PAGE_BTR_SEG_TOP + : PAGE_HEADER + PAGE_BTR_SEG_LEAF) + + root; /* Parameter TRUE below states that the caller has made the reservation for free extents, and thus we know that a page can @@ -716,17 +710,14 @@ btr_page_free_for_ibuf( buf_block_t* block, /*!< in: block to be freed, x-latched */ mtr_t* mtr) /*!< in: mtr */ { - page_t* root; - ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); - root = btr_root_get(index, mtr); - flst_add_first(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, - buf_block_get_frame(block) - + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, mtr); + buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH, mtr); + + flst_add_first(root, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, + block, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, mtr); - ut_ad(flst_validate(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, - mtr)); + ut_d(flst_validate(root, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr)); } /** Free an index page. @@ -779,39 +770,29 @@ void btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr, srv_immediate_scrub_data_uncompressed is set. */ } -/**************************************************************//** +/** Set the child page number in a node pointer record. +@param[in,out] block non-leaf index page +@param[in,out] rec node pointer record in the page +@param[in] offsets rec_get_offsets(rec) +@param[in] page_no child page number +@param[in,out] mtr mini-transaction Sets the child node file address in a node pointer. */ -UNIV_INLINE -void -btr_node_ptr_set_child_page_no( -/*===========================*/ - rec_t* rec, /*!< in: node pointer record */ - page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed - part will be updated, or NULL */ - const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ - ulint page_no,/*!< in: child node address */ - mtr_t* mtr) /*!< in: mtr */ +inline void btr_node_ptr_set_child_page_no(buf_block_t *block, + rec_t *rec, const ulint *offsets, + ulint page_no, mtr_t *mtr) { - byte* field; - ulint len; - - ut_ad(rec_offs_validate(rec, NULL, offsets)); - ut_ad(!page_rec_is_leaf(rec)); - ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec)); - - /* The child address is in the last field */ - field = rec_get_nth_field(rec, offsets, - rec_offs_n_fields(offsets) - 1, &len); - - ut_ad(len == REC_NODE_PTR_SIZE); - - if (page_zip) { - page_zip_write_node_ptr(page_zip, rec, - rec_offs_data_size(offsets), - page_no, mtr); - } else { - mlog_write_ulint(field, page_no, MLOG_4BYTES, mtr); - } + ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!page_rec_is_leaf(rec)); + ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec)); + + const ulint offs= rec_offs_data_size(offsets); + ut_ad(rec_offs_nth_size(offsets, rec_offs_n_fields(offsets) - 1) == + REC_NODE_PTR_SIZE); + + if (UNIV_LIKELY_NULL(block->page.zip.data)) + page_zip_write_node_ptr(&block->page.zip, rec, offs, page_no, mtr); + else + mtr->write<4>(*block, rec + offs - REC_NODE_PTR_SIZE, page_no); } /************************************************************//** @@ -986,7 +967,7 @@ void btr_page_get_father(dict_index_t* index, buf_block_t* block, mtr_t* mtr, } /** PAGE_INDEX_ID value for freed index B-trees */ -static const index_id_t BTR_FREED_INDEX_ID = 0; +constexpr index_id_t BTR_FREED_INDEX_ID = 0; /** Free a B-tree root page. btr_free_but_not_root() must already have been called. @@ -995,30 +976,33 @@ before mtr.commit(). @param[in,out] block index root page @param[in,out] mtr mini-transaction @param[in] invalidate whether to invalidate PAGE_INDEX_ID */ -static void btr_free_root(buf_block_t* block, mtr_t* mtr, bool invalidate) +static void btr_free_root(buf_block_t *block, mtr_t *mtr, bool invalidate) { - fseg_header_t* header; + ut_ad(mtr_memo_contains_flagged(mtr, block, + MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX)); + ut_ad(mtr->is_named_space(block->page.id.space())); - ut_ad(mtr_memo_contains_flagged(mtr, block, MTR_MEMO_PAGE_X_FIX - | MTR_MEMO_PAGE_SX_FIX)); - ut_ad(mtr->is_named_space(block->page.id.space())); - - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block); - header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP; #ifdef UNIV_BTR_DEBUG - ut_a(btr_root_fseg_validate(header, block->page.id.space())); + ut_a(btr_root_fseg_validate(PAGE_HEADER + PAGE_BTR_SEG_TOP + block->frame, + block->page.id.space())); #endif /* UNIV_BTR_DEBUG */ - if (invalidate) { - btr_page_set_index_id( - buf_block_get_frame(block), - buf_block_get_page_zip(block), - BTR_FREED_INDEX_ID, mtr); - } - - while (!fseg_free_step(header, true, mtr)) { - /* Free the entire segment in small steps. */ - } + if (invalidate) + { + byte *page_index_id= PAGE_HEADER + PAGE_INDEX_ID + block->frame; + if (UNIV_LIKELY_NULL(block->page.zip.data)) + { + mach_write_to_8(page_index_id, BTR_FREED_INDEX_ID); + page_zip_write_header(&block->page.zip, page_index_id, 8, mtr); + } + else + mtr->write<8,mtr_t::OPT>(*block, page_index_id, BTR_FREED_INDEX_ID); + } + + /* Free the entire segment in small steps. */ + while (!fseg_free_step(PAGE_HEADER + PAGE_BTR_SEG_TOP + block->frame, + true, mtr)); } /** Prepare to free a B-tree. @@ -1076,8 +1060,6 @@ btr_create( mtr_t* mtr) { buf_block_t* block; - page_t* page; - page_zip_des_t* page_zip; ut_ad(mtr->is_named_space(space)); ut_ad(index_id != BTR_FREED_INDEX_ID); @@ -1144,30 +1126,29 @@ btr_create( buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW); } - /* Create a new index page on the allocated segment page */ - page_zip = buf_block_get_page_zip(block); + byte* page_index_id = PAGE_HEADER + PAGE_INDEX_ID + block->frame; - if (page_zip) { - page = page_create_zip(block, index, 0, 0, mtr); + /* Create a new index page on the allocated segment page */ + if (UNIV_LIKELY_NULL(block->page.zip.data)) { + page_create_zip(block, index, 0, 0, mtr); + mach_write_to_8(page_index_id, index_id); + page_zip_write_header(&block->page.zip, page_index_id, 8, mtr); + static_assert(FIL_PAGE_PREV % 8 == 0, "alignment"); + memset_aligned<8>(FIL_PAGE_PREV + block->page.zip.data, + 0xff, 8); } else { - page = page_create(block, mtr, - dict_table_is_comp(index->table), - dict_index_is_spatial(index)); + page_create(block, mtr, index->table->not_redundant(), + index->is_spatial()); /* Set the level of the new index page */ - btr_page_set_level(page, NULL, 0, mtr); + mtr->write<2,mtr_t::OPT>(*block, PAGE_HEADER + PAGE_LEVEL + + block->frame, 0U); + mtr->write<8,mtr_t::OPT>(*block, page_index_id, index_id); } - /* Set the index id of the page */ - btr_page_set_index_id(page, page_zip, index_id, mtr); - /* Set the next node and previous node fields */ compile_time_assert(FIL_PAGE_NEXT == FIL_PAGE_PREV + 4); compile_time_assert(FIL_NULL == 0xffffffff); mlog_memset(block, FIL_PAGE_PREV, 8, 0xff, mtr); - if (UNIV_LIKELY_NULL(page_zip)) { - static_assert(FIL_PAGE_PREV % 8 == 0, "alignment"); - memset_aligned<8>(FIL_PAGE_PREV + page_zip->data, 0xff, 8); - } /* We reset the free bits for the page in a separate mini-transaction to allow creation of several trees in the @@ -1184,7 +1165,8 @@ btr_create( allowed size fit on the root page: this fact is needed to ensure correctness of split algorithms */ - ut_ad(page_get_max_insert_size(page, 2) > 2 * BTR_PAGE_MAX_REC_SIZE); + ut_ad(page_get_max_insert_size(block->frame, 2) + > 2 * BTR_PAGE_MAX_REC_SIZE); return(block->page.id.page_no()); } @@ -1199,7 +1181,6 @@ btr_free_but_not_root( buf_block_t* block, mtr_log_t log_mode) { - ibool finished; mtr_t mtr; ut_ad(fil_page_index_page_check(block->frame)); @@ -1226,8 +1207,8 @@ leaf_loop: /* NOTE: page hash indexes are dropped when a page is freed inside fsp0fsp. */ - finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF, - true, &mtr); + bool finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF, + true, &mtr); mtr_commit(&mtr); if (!finished) { @@ -1390,7 +1371,7 @@ btr_write_autoinc(dict_index_t* index, ib_uint64_t autoinc, bool reset) page_set_autoinc(buf_page_get(page_id_t(space->id, index->page), space->zip_size(), RW_SX_LATCH, &mtr), - index, autoinc, &mtr, reset); + autoinc, &mtr, reset); mtr.commit(); } @@ -1424,7 +1405,6 @@ btr_page_reorganize_low( page_t* page = buf_block_get_frame(block); page_zip_des_t* page_zip = buf_block_get_page_zip(block); buf_block_t* temp_block; - page_t* temp_page; ulint data_size1; ulint data_size2; ulint max_ins_size1; @@ -1451,7 +1431,6 @@ btr_page_reorganize_low( mtr_log_t log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE); temp_block = buf_block_alloc(buf_pool); - temp_page = temp_block->frame; MONITOR_INC(MONITOR_INDEX_REORG_ATTEMPTS); @@ -1480,12 +1459,14 @@ btr_page_reorganize_low( do not copy the lock bits yet */ page_copy_rec_list_end_no_locks(block, temp_block, - page_get_infimum_rec(temp_page), + page_get_infimum_rec(temp_block->frame), index, mtr); /* Copy the PAGE_MAX_TRX_ID or PAGE_ROOT_AUTO_INC. */ - memcpy(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), - temp_page + (PAGE_HEADER + PAGE_MAX_TRX_ID), 8); + static_assert((PAGE_HEADER + PAGE_MAX_TRX_ID) % 8 == 0, "alignment"); + memcpy_aligned<8>(&block->frame[PAGE_HEADER + PAGE_MAX_TRX_ID], + &temp_block->frame[PAGE_HEADER + PAGE_MAX_TRX_ID], + 8); /* PAGE_MAX_TRX_ID is unused in clustered index pages (other than the root where it is repurposed as PAGE_ROOT_AUTO_INC), non-leaf pages, and in temporary tables. It was always @@ -1496,15 +1477,15 @@ btr_page_reorganize_low( During redo log apply, dict_index_is_sec_or_ibuf() always holds, even for clustered indexes. */ ut_ad(recovery || index->table->is_temporary() - || !page_is_leaf(temp_page) + || !page_is_leaf(temp_block->frame) || !dict_index_is_sec_or_ibuf(index) - || page_get_max_trx_id(page) != 0); + || page_get_max_trx_id(block->frame) != 0); /* PAGE_MAX_TRX_ID must be zero on non-leaf pages other than clustered index root pages. */ ut_ad(recovery - || page_get_max_trx_id(page) == 0 + || page_get_max_trx_id(block->frame) == 0 || (dict_index_is_sec_or_ibuf(index) - ? page_is_leaf(temp_page) + ? page_is_leaf(temp_block->frame) : block->page.id.page_no() == index->page)); /* If innodb_log_compressed_pages is ON, page reorganize should log the @@ -1521,29 +1502,32 @@ btr_page_reorganize_low( /* Restore the old page and exit. */ #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG /* Check that the bytes that we skip are identical. */ - ut_a(!memcmp(page, temp_page, PAGE_HEADER)); - ut_a(!memcmp(PAGE_HEADER + PAGE_N_RECS + page, - PAGE_HEADER + PAGE_N_RECS + temp_page, + ut_a(!memcmp(page, temp_block->frame, PAGE_HEADER)); + ut_a(!memcmp(PAGE_HEADER + PAGE_N_RECS + block->frame, + PAGE_HEADER + PAGE_N_RECS + temp_block->frame, PAGE_DATA - (PAGE_HEADER + PAGE_N_RECS))); - ut_a(!memcmp(srv_page_size - FIL_PAGE_DATA_END + page, - srv_page_size - FIL_PAGE_DATA_END + temp_page, - FIL_PAGE_DATA_END)); + ut_a(!memcmp(srv_page_size - FIL_PAGE_DATA_END + + block->frame, + srv_page_size - FIL_PAGE_DATA_END + + temp_block->frame, FIL_PAGE_DATA_END)); #endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */ - memcpy(PAGE_HEADER + page, PAGE_HEADER + temp_page, - PAGE_N_RECS - PAGE_N_DIR_SLOTS); - memcpy(PAGE_DATA + page, PAGE_DATA + temp_page, + memcpy_aligned<2>(PAGE_HEADER + block->frame, + PAGE_HEADER + temp_block->frame, + PAGE_N_RECS - PAGE_N_DIR_SLOTS); + memcpy(PAGE_DATA + block->frame, PAGE_DATA + temp_block->frame, srv_page_size - PAGE_DATA - FIL_PAGE_DATA_END); #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG - ut_a(!memcmp(page, temp_page, srv_page_size)); + ut_a(!memcmp(block->frame, temp_block->frame, srv_page_size)); #endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */ goto func_exit; } - data_size2 = page_get_data_size(page); - max_ins_size2 = page_get_max_insert_size_after_reorganize(page, 1); + data_size2 = page_get_data_size(block->frame); + max_ins_size2 = page_get_max_insert_size_after_reorganize(block->frame, + 1); if (data_size1 != data_size2 || max_ins_size1 != max_ins_size2) { ib::error() @@ -1560,39 +1544,41 @@ btr_page_reorganize_low( /* Restore the cursor position. */ if (pos > 0) { - cursor->rec = page_rec_get_nth(page, pos); + cursor->rec = page_rec_get_nth(block->frame, pos); } else { - ut_ad(cursor->rec == page_get_infimum_rec(page)); + ut_ad(cursor->rec == page_get_infimum_rec(block->frame)); } #ifdef UNIV_ZIP_DEBUG - ut_a(!page_zip || page_zip_validate(page_zip, page, index)); + ut_a(!page_zip || page_zip_validate(page_zip, block->frame, index)); #endif /* UNIV_ZIP_DEBUG */ if (!recovery) { if (block->page.id.page_no() == index->page - && fil_page_get_type(temp_page) == FIL_PAGE_TYPE_INSTANT) { + && fil_page_get_type(temp_block->frame) + == FIL_PAGE_TYPE_INSTANT) { /* Preserve the PAGE_INSTANT information. */ ut_ad(!page_zip); ut_ad(index->is_instant()); static_assert(!(FIL_PAGE_TYPE % 2), "alignment"); - memcpy_aligned<2>(FIL_PAGE_TYPE + page, - FIL_PAGE_TYPE + temp_page, 2); + memcpy_aligned<2>(FIL_PAGE_TYPE + block->frame, + FIL_PAGE_TYPE + temp_block->frame, 2); static_assert(!((PAGE_HEADER+PAGE_INSTANT) % 2), ""); - memcpy_aligned<2>(PAGE_HEADER + PAGE_INSTANT + page, + memcpy_aligned<2>(PAGE_HEADER + PAGE_INSTANT + + block->frame, PAGE_HEADER + PAGE_INSTANT - + temp_page, 2); + + temp_block->frame, 2); if (!index->table->instant) { - } else if (page_is_comp(page)) { - memcpy(PAGE_NEW_INFIMUM + page, - PAGE_NEW_INFIMUM + temp_page, 8); - memcpy(PAGE_NEW_SUPREMUM + page, - PAGE_NEW_SUPREMUM + temp_page, 8); + } else if (page_is_comp(block->frame)) { + memcpy(PAGE_NEW_INFIMUM + block->frame, + PAGE_NEW_INFIMUM + temp_block->frame, 8); + memcpy(PAGE_NEW_SUPREMUM + block->frame, + PAGE_NEW_SUPREMUM + temp_block->frame, 8); } else { - memcpy(PAGE_OLD_INFIMUM + page, - PAGE_OLD_INFIMUM + temp_page, 8); - memcpy(PAGE_OLD_SUPREMUM + page, - PAGE_OLD_SUPREMUM + temp_page, 8); + memcpy(PAGE_OLD_INFIMUM + block->frame, + PAGE_OLD_INFIMUM + temp_block->frame, 8); + memcpy(PAGE_OLD_SUPREMUM + block->frame, + PAGE_OLD_SUPREMUM + temp_block->frame, 8); } } @@ -1637,24 +1623,29 @@ func_exit: MONITOR_INC(MONITOR_INDEX_REORG_SUCCESSFUL); } - if (UNIV_UNLIKELY(fil_page_get_type(page) == FIL_PAGE_TYPE_INSTANT)) { + if (UNIV_UNLIKELY(fil_page_get_type(block->frame) + == FIL_PAGE_TYPE_INSTANT)) { /* Log the PAGE_INSTANT information. */ ut_ad(!page_zip); ut_ad(index->is_instant()); ut_ad(!recovery); - mlog_write_ulint(FIL_PAGE_TYPE + page, FIL_PAGE_TYPE_INSTANT, - MLOG_2BYTES, mtr); - mlog_write_ulint(PAGE_HEADER + PAGE_INSTANT + page, - mach_read_from_2(PAGE_HEADER + PAGE_INSTANT - + page), - MLOG_2BYTES, mtr); + mtr->write<2,mtr_t::FORCED>(*block, FIL_PAGE_TYPE + + block->frame, + FIL_PAGE_TYPE_INSTANT); + byte* instant = PAGE_HEADER + PAGE_INSTANT + block->frame; + mtr->write<2,mtr_t::FORCED>(*block, instant, + mach_read_from_2(instant)); if (!index->table->instant) { - } else if (page_is_comp(page)) { - mlog_log_string(PAGE_NEW_INFIMUM + page, 8, mtr); - mlog_log_string(PAGE_NEW_SUPREMUM + page, 8, mtr); + } else if (page_is_comp(block->frame)) { + mlog_log_string(PAGE_NEW_INFIMUM + block->frame, 8, + mtr); + mlog_log_string(PAGE_NEW_SUPREMUM + block->frame, 8, + mtr); } else { - mlog_log_string(PAGE_OLD_INFIMUM + page, 8, mtr); - mlog_log_string(PAGE_OLD_SUPREMUM + page, 8, mtr); + mlog_log_string(PAGE_OLD_INFIMUM + block->frame, 8, + mtr); + mlog_log_string(PAGE_OLD_SUPREMUM + block->frame, 8, + mtr); } } @@ -1770,14 +1761,12 @@ btr_page_empty( ulint level, mtr_t* mtr) { - page_t* page = buf_block_get_frame(block); - ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); ut_ad(page_zip == buf_block_get_page_zip(block)); ut_ad(!index->is_dummy); ut_ad(index->table->space->id == block->page.id.space()); #ifdef UNIV_ZIP_DEBUG - ut_a(!page_zip || page_zip_validate(page_zip, page, index)); + ut_a(!page_zip || page_zip_validate(page_zip, block->frame, index)); #endif /* UNIV_ZIP_DEBUG */ btr_search_drop_page_hash_index(block); @@ -1790,7 +1779,7 @@ btr_page_empty( const ib_uint64_t autoinc = dict_index_is_clust(index) && index->page == block->page.id.page_no() - ? page_get_autoinc(page) + ? page_get_autoinc(block->frame) : 0; if (page_zip) { @@ -1798,10 +1787,11 @@ btr_page_empty( } else { page_create(block, mtr, dict_table_is_comp(index->table), dict_index_is_spatial(index)); - btr_page_set_level(page, NULL, level, mtr); + mtr->write<2,mtr_t::OPT>(*block, PAGE_HEADER + PAGE_LEVEL + + block->frame, level); if (autoinc) { - mlog_write_ull(PAGE_HEADER + PAGE_MAX_TRX_ID + page, - autoinc, mtr); + mtr->write<8>(*block, PAGE_HEADER + PAGE_MAX_TRX_ID + + block->frame, autoinc); } } } @@ -1848,20 +1838,19 @@ void btr_set_instant(buf_block_t* root, const dict_index_t& index, mtr_t* mtr) || !page_get_instant(root->frame)); ut_ad(!memcmp(infimum, "infimum", 8)); ut_ad(!memcmp(supremum, "supremum", 8)); - mlog_write_ulint(page_type, FIL_PAGE_TYPE_INSTANT, - MLOG_2BYTES, mtr); + mtr->write<2>(*root, page_type, FIL_PAGE_TYPE_INSTANT); ut_ad(i <= PAGE_NO_DIRECTION); i |= index.n_core_fields << 3; - mlog_write_ulint(PAGE_HEADER + PAGE_INSTANT + root->frame, i, - MLOG_2BYTES, mtr); + mtr->write<2>(*root, PAGE_HEADER + PAGE_INSTANT + root->frame, + i); break; } if (index.table->instant) { mlog_memset(root, infimum - root->frame, 8, 0, mtr); mlog_memset(root, supremum - root->frame, 7, 0, mtr); - mlog_write_ulint(&supremum[7], index.n_core_null_bytes, - MLOG_1BYTE, mtr); + mtr->write<1,mtr_t::OPT>(*root, &supremum[7], + index.n_core_null_bytes); } } @@ -1887,8 +1876,6 @@ btr_root_raise_and_insert( mtr_t* mtr) /*!< in: mtr */ { dict_index_t* index; - page_t* root; - page_t* new_page; ulint new_page_no; rec_t* rec; dtuple_t* node_ptr; @@ -1897,40 +1884,40 @@ btr_root_raise_and_insert( page_cur_t* page_cursor; page_zip_des_t* root_page_zip; page_zip_des_t* new_page_zip; - buf_block_t* root_block; + buf_block_t* root; buf_block_t* new_block; - root = btr_cur_get_page(cursor); - root_block = btr_cur_get_block(cursor); - root_page_zip = buf_block_get_page_zip(root_block); - ut_ad(!page_is_empty(root)); + root = btr_cur_get_block(cursor); + root_page_zip = buf_block_get_page_zip(root); + ut_ad(!page_is_empty(root->frame)); index = btr_cur_get_index(cursor); ut_ad(index->n_core_null_bytes <= UT_BITS_IN_BYTES(index->n_nullable)); #ifdef UNIV_ZIP_DEBUG - ut_a(!root_page_zip || page_zip_validate(root_page_zip, root, index)); + ut_a(!root_page_zip || page_zip_validate(root_page_zip, root->frame, + index)); #endif /* UNIV_ZIP_DEBUG */ #ifdef UNIV_BTR_DEBUG if (!dict_index_is_ibuf(index)) { ulint space = index->table->space_id; ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF - + root, space)); + + root->frame, space)); ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP - + root, space)); + + root->frame, space)); } - ut_a(dict_index_get_page(index) == page_get_page_no(root)); + ut_a(dict_index_get_page(index) == page_get_page_no(root->frame)); #endif /* UNIV_BTR_DEBUG */ ut_ad(mtr_memo_contains_flagged(mtr, dict_index_get_lock(index), MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); - ut_ad(mtr_memo_contains(mtr, root_block, MTR_MEMO_PAGE_X_FIX)); + ut_ad(mtr_memo_contains(mtr, root, MTR_MEMO_PAGE_X_FIX)); /* Allocate a new page to the tree. Root splitting is done by first moving the root records to the new page, emptying the root, putting a node pointer to the new page, and then splitting the new page. */ - level = btr_page_get_level(root); + level = btr_page_get_level(root->frame); new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, mtr, mtr); @@ -1938,7 +1925,6 @@ btr_root_raise_and_insert( return(NULL); } - new_page = buf_block_get_frame(new_block); new_page_zip = buf_block_get_page_zip(new_block); ut_a(!new_page_zip == !root_page_zip); ut_a(!new_page_zip @@ -1948,12 +1934,17 @@ btr_root_raise_and_insert( btr_page_create(new_block, new_page_zip, index, level, mtr); /* Set the next node and previous node fields of new page */ - compile_time_assert(FIL_PAGE_NEXT == FIL_PAGE_PREV + 4); - compile_time_assert(FIL_NULL == 0xffffffff); - mlog_memset(new_block, FIL_PAGE_PREV, 8, 0xff, mtr); - if (UNIV_LIKELY_NULL(new_page_zip)) { - static_assert(FIL_PAGE_PREV % 8 == 0, "alignment"); - memset_aligned<8>(new_page_zip->data + FIL_PAGE_PREV, 0xff, 8); + if (!page_has_siblings(new_block->frame)) { + ut_ad(index->is_ibuf()); + } else { + compile_time_assert(FIL_PAGE_NEXT == FIL_PAGE_PREV + 4); + compile_time_assert(FIL_NULL == 0xffffffff); + mlog_memset(new_block, FIL_PAGE_PREV, 8, 0xff, mtr); + if (UNIV_LIKELY_NULL(new_page_zip)) { + static_assert(FIL_PAGE_PREV % 8 == 0, "alignment"); + memset_aligned<8>(new_page_zip->data + FIL_PAGE_PREV, + 0xff, 8); + } } /* Copy the records from root to the new page one by one. */ @@ -1962,25 +1953,25 @@ btr_root_raise_and_insert( #ifdef UNIV_ZIP_COPY || new_page_zip #endif /* UNIV_ZIP_COPY */ - || !page_copy_rec_list_end(new_block, root_block, - page_get_infimum_rec(root), + || !page_copy_rec_list_end(new_block, root, + page_get_infimum_rec(root->frame), index, mtr)) { ut_a(new_page_zip); /* Copy the page byte for byte. */ page_zip_copy_recs(new_block, - root_page_zip, root, index, mtr); + root_page_zip, root->frame, index, mtr); /* Update the lock table and possible hash index. */ - lock_move_rec_list_end(new_block, root_block, - page_get_infimum_rec(root)); + lock_move_rec_list_end(new_block, root, + page_get_infimum_rec(root->frame)); /* Move any existing predicate locks */ if (dict_index_is_spatial(index)) { - lock_prdt_rec_move(new_block, root_block); + lock_prdt_rec_move(new_block, root); } else { btr_search_move_or_delete_hash_entries( - new_block, root_block); + new_block, root); } } @@ -1990,25 +1981,29 @@ btr_root_raise_and_insert( the field only matters on leaf pages, and the root no longer is a leaf page. (Older versions of InnoDB did set PAGE_MAX_TRX_ID on all secondary index pages.) */ - if (root_page_zip) { - byte* p = PAGE_HEADER + PAGE_MAX_TRX_ID + root; - memset(p, 0, 8); + byte* p = static_cast<byte*>( + MY_ASSUME_ALIGNED(PAGE_HEADER + PAGE_MAX_TRX_ID + + root->frame, 8)); + if (UNIV_LIKELY_NULL(root_page_zip)) { + memset_aligned<8>(p, 0, 8); page_zip_write_header(root_page_zip, p, 8, mtr); - } else { - mlog_write_ull(PAGE_HEADER + PAGE_MAX_TRX_ID - + root, 0, mtr); + } else if (mach_read_from_8(p)) { + mlog_memset(root, PAGE_HEADER + PAGE_MAX_TRX_ID, 8, 0, + mtr); } } else { /* PAGE_ROOT_AUTO_INC is only present in the clustered index root page; on other clustered index pages, we want to reserve the field PAGE_MAX_TRX_ID for future use. */ - if (new_page_zip) { - byte* p = PAGE_HEADER + PAGE_MAX_TRX_ID + new_page; - memset(p, 0, 8); + byte* p = static_cast<byte*>( + MY_ASSUME_ALIGNED(PAGE_HEADER + PAGE_MAX_TRX_ID + + new_block->frame, 8)); + if (UNIV_LIKELY_NULL(new_page_zip)) { + memset_aligned<8>(p, 0, 8); page_zip_write_header(new_page_zip, p, 8, mtr); - } else { - mlog_write_ull(PAGE_HEADER + PAGE_MAX_TRX_ID - + new_page, 0, mtr); + } else if (mach_read_from_8(p)) { + mlog_memset(new_block, PAGE_HEADER + PAGE_MAX_TRX_ID, + 8, 0, mtr); } } @@ -2018,7 +2013,7 @@ btr_root_raise_and_insert( root page: we cannot discard the lock structs on the root page */ if (!dict_table_is_locking_disabled(index->table)) { - lock_update_root_raise(new_block, root_block); + lock_update_root_raise(new_block, root); } /* Create a memory heap where the node pointer is stored */ @@ -2026,7 +2021,7 @@ btr_root_raise_and_insert( *heap = mem_heap_create(1000); } - rec = page_rec_get_next(page_get_infimum_rec(new_page)); + rec = page_rec_get_next(page_get_infimum_rec(new_block->frame)); new_page_no = new_block->page.id.page_no(); /* Build the node pointer (= node key and page address) for the @@ -2049,28 +2044,28 @@ btr_root_raise_and_insert( | REC_INFO_MIN_REC_FLAG); /* Rebuild the root page to get free space */ - btr_page_empty(root_block, root_page_zip, index, level + 1, mtr); + btr_page_empty(root, root_page_zip, index, level + 1, mtr); /* btr_page_empty() is supposed to zero-initialize the field. */ - ut_ad(!page_get_instant(root_block->frame)); + ut_ad(!page_get_instant(root->frame)); if (index->is_instant()) { ut_ad(!root_page_zip); - btr_set_instant(root_block, *index, mtr); + btr_set_instant(root, *index, mtr); } - ut_ad(!page_has_siblings(root)); + ut_ad(!page_has_siblings(root->frame)); page_cursor = btr_cur_get_page_cur(cursor); /* Insert node pointer to the root */ - page_cur_set_before_first(root_block, page_cursor); + page_cur_set_before_first(root, page_cursor); node_ptr_rec = page_cur_tuple_insert(page_cursor, node_ptr, index, offsets, heap, 0, mtr); /* The root page should only contain the node pointer - to new_page at this point. Thus, the data should fit. */ + to new_block at this point. Thus, the data should fit. */ ut_a(node_ptr_rec); /* We play safe and reset the free bits for the new page */ @@ -2504,19 +2499,12 @@ btr_attach_half_pages( ulint direction, /*!< in: FSP_UP or FSP_DOWN */ mtr_t* mtr) /*!< in: mtr */ { - ulint prev_page_no; - ulint next_page_no; - page_t* page = buf_block_get_frame(block); - page_t* lower_page; - page_t* upper_page; - ulint lower_page_no; - ulint upper_page_no; - page_zip_des_t* lower_page_zip; - page_zip_des_t* upper_page_zip; dtuple_t* node_ptr_upper; mem_heap_t* heap; buf_block_t* prev_block = NULL; buf_block_t* next_block = NULL; + buf_block_t* lower_block; + buf_block_t* upper_block; ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); ut_ad(mtr_memo_contains(mtr, new_block, MTR_MEMO_PAGE_X_FIX)); @@ -2530,12 +2518,8 @@ btr_attach_half_pages( btr_cur_t cursor; ulint* offsets; - lower_page = buf_block_get_frame(new_block); - lower_page_no = new_block->page.id.page_no(); - lower_page_zip = buf_block_get_page_zip(new_block); - upper_page = buf_block_get_frame(block); - upper_page_no = block->page.id.page_no(); - upper_page_zip = buf_block_get_page_zip(block); + lower_block = new_block; + upper_block = block; /* Look up the index for the node pointer to page */ offsets = btr_page_get_father_block(NULL, heap, index, @@ -2545,17 +2529,13 @@ btr_attach_half_pages( address of the new lower half */ btr_node_ptr_set_child_page_no( + btr_cur_get_block(&cursor), btr_cur_get_rec(&cursor), - btr_cur_get_page_zip(&cursor), - offsets, lower_page_no, mtr); + offsets, lower_block->page.id.page_no(), mtr); mem_heap_empty(heap); } else { - lower_page = buf_block_get_frame(block); - lower_page_no = block->page.id.page_no(); - lower_page_zip = buf_block_get_page_zip(block); - upper_page = buf_block_get_frame(new_block); - upper_page_no = new_block->page.id.page_no(); - upper_page_zip = buf_block_get_page_zip(new_block); + lower_block = block; + upper_block = new_block; } /* Get the level of the split pages */ @@ -2563,8 +2543,8 @@ btr_attach_half_pages( ut_ad(level == btr_page_get_level(buf_block_get_frame(new_block))); /* Get the previous and next pages of page */ - prev_page_no = btr_page_get_prev(page); - next_page_no = btr_page_get_next(page); + const uint32_t prev_page_no = btr_page_get_prev(block->frame); + const uint32_t next_page_no = btr_page_get_next(block->frame); /* for consistency, both blocks should be locked, before change */ if (prev_page_no != FIL_NULL && direction == FSP_DOWN) { @@ -2579,8 +2559,8 @@ btr_attach_half_pages( /* Build the node pointer (= node key and page address) for the upper half */ - node_ptr_upper = dict_index_build_node_ptr(index, split_rec, - upper_page_no, heap, level); + node_ptr_upper = dict_index_build_node_ptr( + index, split_rec, upper_block->page.id.page_no(), heap, level); /* Insert it next to the pointer to the lower half. Note that this may generate recursion leading to a split on the higher level. */ @@ -2595,45 +2575,59 @@ btr_attach_half_pages( if (prev_block) { #ifdef UNIV_BTR_DEBUG - ut_a(page_is_comp(prev_block->frame) == page_is_comp(page)); + ut_a(page_is_comp(prev_block->frame) + == page_is_comp(block->frame)); ut_a(btr_page_get_next(prev_block->frame) == block->page.id.page_no()); #endif /* UNIV_BTR_DEBUG */ - - btr_page_set_next(buf_block_get_frame(prev_block), - buf_block_get_page_zip(prev_block), - lower_page_no, mtr); + btr_page_set_next(prev_block, lower_block->page.id.page_no(), + mtr); } if (next_block) { #ifdef UNIV_BTR_DEBUG - ut_a(page_is_comp(next_block->frame) == page_is_comp(page)); + ut_a(page_is_comp(next_block->frame) + == page_is_comp(block->frame)); ut_a(btr_page_get_prev(next_block->frame) - == page_get_page_no(page)); + == block->page.id.page_no()); #endif /* UNIV_BTR_DEBUG */ - - btr_page_set_prev(buf_block_get_frame(next_block), - buf_block_get_page_zip(next_block), - upper_page_no, mtr); + btr_page_set_prev(next_block, upper_block->page.id.page_no(), + mtr); } if (direction == FSP_DOWN) { - /* lower_page is new */ - btr_page_set_prev(lower_page, lower_page_zip, - prev_page_no, mtr); + ut_ad(lower_block == new_block); + ut_ad(btr_page_get_next(upper_block->frame) == next_page_no); + if (UNIV_UNLIKELY(btr_page_get_prev(lower_block->frame) + == prev_page_no)) { + ut_ad(index->is_ibuf()); + } else { + btr_page_set_prev(lower_block, prev_page_no, mtr); + } } else { - ut_ad(btr_page_get_prev(lower_page) == prev_page_no); + ut_ad(upper_block == new_block); + ut_ad(btr_page_get_prev(lower_block->frame) == prev_page_no); + if (UNIV_UNLIKELY(btr_page_get_next(upper_block->frame) + == next_page_no)) { + ut_ad(index->is_ibuf()); + } else { + btr_page_set_next(upper_block, next_page_no, mtr); + } } - btr_page_set_next(lower_page, lower_page_zip, upper_page_no, mtr); - btr_page_set_prev(upper_page, upper_page_zip, lower_page_no, mtr); - - if (direction != FSP_DOWN) { - /* upper_page is new */ - btr_page_set_next(upper_page, upper_page_zip, - next_page_no, mtr); + if (UNIV_UNLIKELY(btr_page_get_next(lower_block->frame) + == upper_block->page.id.page_no())) { + ut_ad(index->is_ibuf()); + } else { + btr_page_set_next(lower_block, upper_block->page.id.page_no(), + mtr); + } + if (UNIV_UNLIKELY(btr_page_get_prev(upper_block->frame) + == lower_block->page.id.page_no())) { + ut_ad(index->is_ibuf()); } else { - ut_ad(btr_page_get_next(upper_page) == next_page_no); + btr_page_set_prev(upper_block, lower_block->page.id.page_no(), + mtr); } } @@ -3227,38 +3221,30 @@ void btr_level_list_remove(const buf_block_t& block, const dict_index_t& index, buf_block_t* prev_block = btr_block_get( index, prev_page_no, RW_X_LATCH, page_is_leaf(page), mtr); - page_t* prev_page - = buf_block_get_frame(prev_block); #ifdef UNIV_BTR_DEBUG - ut_a(page_is_comp(prev_page) == page_is_comp(page)); + ut_a(page_is_comp(prev_block->frame) == page_is_comp(page)); static_assert(FIL_PAGE_NEXT % 4 == 0, "alignment"); static_assert(FIL_PAGE_OFFSET % 4 == 0, "alignment"); - ut_a(!memcmp_aligned<4>(prev_page + FIL_PAGE_NEXT, + ut_a(!memcmp_aligned<4>(prev_block->frame + FIL_PAGE_NEXT, page + FIL_PAGE_OFFSET, 4)); #endif /* UNIV_BTR_DEBUG */ - btr_page_set_next(prev_page, - buf_block_get_page_zip(prev_block), - next_page_no, mtr); + btr_page_set_next(prev_block, next_page_no, mtr); } if (next_page_no != FIL_NULL) { buf_block_t* next_block = btr_block_get( index, next_page_no, RW_X_LATCH, page_is_leaf(page), mtr); - page_t* next_page - = buf_block_get_frame(next_block); #ifdef UNIV_BTR_DEBUG - ut_a(page_is_comp(next_page) == page_is_comp(page)); + ut_a(page_is_comp(next_block->frame) == page_is_comp(page)); static_assert(FIL_PAGE_PREV % 4 == 0, "alignment"); static_assert(FIL_PAGE_OFFSET % 4 == 0, "alignment"); - ut_a(!memcmp_aligned<4>(next_page + FIL_PAGE_PREV, + ut_a(!memcmp_aligned<4>(next_block->frame + FIL_PAGE_PREV, page + FIL_PAGE_OFFSET, 4)); #endif /* UNIV_BTR_DEBUG */ - btr_page_set_prev(next_page, - buf_block_get_page_zip(next_block), - prev_page_no, mtr); + btr_page_set_prev(next_block, prev_page_no, mtr); } } @@ -3456,15 +3442,8 @@ btr_lift_page_up( /* Go upward to root page, decrementing levels by one. */ for (i = lift_father_up ? 1 : 0; i < n_blocks; i++, page_level++) { - page_t* page = buf_block_get_frame(blocks[i]); - page_zip_des_t* page_zip= buf_block_get_page_zip(blocks[i]); - - ut_ad(btr_page_get_level(page) == page_level + 1); - - btr_page_set_level(page, page_zip, page_level, mtr); -#ifdef UNIV_ZIP_DEBUG - ut_a(!page_zip || page_zip_validate(page_zip, page, index)); -#endif /* UNIV_ZIP_DEBUG */ + ut_ad(btr_page_get_level(blocks[i]->frame) == page_level + 1); + btr_page_set_level(blocks[i], page_level, mtr); } if (dict_index_is_spatial(index)) { @@ -3838,8 +3817,8 @@ retry: /* Replace the address of the old child node (= page) with the address of the merge page to the right */ btr_node_ptr_set_child_page_no( + btr_cur_get_block(&father_cursor), btr_cur_get_rec(&father_cursor), - btr_cur_get_page_zip(&father_cursor), offsets, right_page_no, mtr); #ifdef UNIV_DEBUG diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc index c64a64466d8..8be3d6d4b01 100644 --- a/storage/innobase/btr/btr0bulk.cc +++ b/storage/innobase/btr/btr0bulk.cc @@ -92,6 +92,8 @@ PageBulk::init() new_page_zip = buf_block_get_page_zip(new_block); new_page_no = page_get_page_no(new_page); + byte* index_id = PAGE_HEADER + PAGE_INDEX_ID + new_page; + if (new_page_zip) { page_create_zip(new_block, m_index, m_level, 0, &m_mtr); @@ -100,11 +102,9 @@ PageBulk::init() page_zip_write_header(new_page_zip, FIL_PAGE_PREV + new_page, 8, &m_mtr); - mach_write_to_8(PAGE_HEADER + PAGE_INDEX_ID + new_page, - m_index->id); - page_zip_write_header(new_page_zip, - PAGE_HEADER + PAGE_INDEX_ID - + new_page, 8, &m_mtr); + mach_write_to_8(index_id, m_index->id); + page_zip_write_header(new_page_zip, index_id, + 8, &m_mtr); } else { ut_ad(!dict_index_is_spatial(m_index)); page_create(new_block, &m_mtr, @@ -114,10 +114,10 @@ PageBulk::init() == FIL_PAGE_PREV + 4); compile_time_assert(FIL_NULL == 0xffffffff); mlog_memset(new_block, FIL_PAGE_PREV, 8, 0xff, &m_mtr); - mlog_write_ulint(PAGE_HEADER + PAGE_LEVEL + new_page, - m_level, MLOG_2BYTES, &m_mtr); - mlog_write_ull(PAGE_HEADER + PAGE_INDEX_ID + new_page, - m_index->id, &m_mtr); + m_mtr.write<2,mtr_t::OPT>(*new_block, + PAGE_HEADER + PAGE_LEVEL + + new_page, m_level); + m_mtr.write<8>(*new_block, index_id, m_index->id); } } else { new_block = btr_block_get(*m_index, m_page_no, RW_X_LATCH, @@ -130,7 +130,7 @@ PageBulk::init() ut_ad(page_dir_get_n_heap(new_page) == PAGE_HEAP_NO_USER_LOW); - btr_page_set_level(new_page, new_page_zip, m_level, &m_mtr); + btr_page_set_level(new_block, m_level, &m_mtr); } if (!m_level && dict_index_is_sec_or_ibuf(m_index)) { @@ -169,13 +169,14 @@ PageBulk::init() } /** Insert a record in the page. +@tparam fmt the page format @param[in] rec record @param[in] offsets record offsets */ -void -PageBulk::insert( - const rec_t* rec, - ulint* offsets) +template<PageBulk::format fmt> +inline void PageBulk::insertPage(const rec_t *rec, ulint *offsets) { + ut_ad((m_page_zip != nullptr) == (fmt == COMPRESSED)); + ut_ad((fmt != REDUNDANT) == m_is_comp); ulint rec_size; ut_ad(m_heap != NULL); @@ -210,7 +211,7 @@ PageBulk::insert( /* 3. Set the n_owned field in the inserted record to zero, and set the heap_no field. */ - if (m_is_comp) { + if (fmt != REDUNDANT) { rec_set_n_owned_new(insert_rec, NULL, 0); rec_set_heap_no_new(insert_rec, PAGE_HEAP_NO_USER_LOW + m_rec_no); @@ -242,15 +243,30 @@ PageBulk::insert( m_cur_rec = insert_rec; } +/** Insert a record in the page. +@param[in] rec record +@param[in] offsets record offsets */ +inline void PageBulk::insert(const rec_t *rec, ulint *offsets) +{ + if (UNIV_LIKELY_NULL(m_page_zip)) + insertPage<COMPRESSED>(rec, offsets); + else if (m_is_comp) + insertPage<DYNAMIC>(rec, offsets); + else + insertPage<REDUNDANT>(rec, offsets); +} + /** Mark end of insertion to the page. Scan all records to set page dirs, and set page header members. -Note: we refer to page_copy_rec_list_end_to_created_page. */ -void -PageBulk::finish() +@tparam fmt the page format */ +template<PageBulk::format fmt> +inline void PageBulk::finishPage() { ut_ad(m_rec_no > 0); + ut_ad((m_page_zip != nullptr) == (fmt == COMPRESSED)); + ut_ad((fmt != REDUNDANT) == m_is_comp); ut_ad(m_total_data + page_dir_calc_reserved_space(m_rec_no) - <= page_get_free_space_of_empty(m_is_comp)); + <= page_get_free_space_of_empty(fmt != REDUNDANT)); /* See page_copy_rec_list_end_to_created_page() */ ut_d(page_dir_set_n_slots(m_page, NULL, srv_page_size / 2)); @@ -304,26 +320,26 @@ PageBulk::finish() ut_ad(!dict_index_is_spatial(m_index)); ut_ad(!page_get_instant(m_page)); - - if (!m_flush_observer && !m_page_zip) { - mlog_write_ulint(PAGE_HEADER + PAGE_N_DIR_SLOTS + m_page, - 2 + slot_index, MLOG_2BYTES, &m_mtr); - mlog_write_ulint(PAGE_HEADER + PAGE_HEAP_TOP + m_page, - ulint(m_heap_top - m_page), - MLOG_2BYTES, &m_mtr); - mlog_write_ulint(PAGE_HEADER + PAGE_N_HEAP + m_page, - (PAGE_HEAP_NO_USER_LOW + m_rec_no) - | ulint(m_is_comp) << 15, - MLOG_2BYTES, &m_mtr); - mlog_write_ulint(PAGE_HEADER + PAGE_N_RECS + m_page, m_rec_no, - MLOG_2BYTES, &m_mtr); - mlog_write_ulint(PAGE_HEADER + PAGE_LAST_INSERT + m_page, - ulint(m_cur_rec - m_page), - MLOG_2BYTES, &m_mtr); - mlog_write_ulint(PAGE_HEADER + PAGE_DIRECTION_B - 1 + m_page, - PAGE_RIGHT, MLOG_2BYTES, &m_mtr); - mlog_write_ulint(PAGE_HEADER + PAGE_N_DIRECTION + m_page, 0, - MLOG_2BYTES, &m_mtr); + ut_ad(!mach_read_from_2(PAGE_HEADER + PAGE_N_DIRECTION + m_page)); + + if (fmt != COMPRESSED && !m_flush_observer) { + m_mtr.write<2,mtr_t::OPT>(*m_block, + PAGE_HEADER + PAGE_N_DIR_SLOTS + + m_page, 2 + slot_index); + m_mtr.write<2>(*m_block, PAGE_HEADER + PAGE_HEAP_TOP + m_page, + ulint(m_heap_top - m_page)); + m_mtr.write<2>(*m_block, + PAGE_HEADER + PAGE_N_HEAP + m_page, + (PAGE_HEAP_NO_USER_LOW + m_rec_no) + | uint16_t{fmt != REDUNDANT} << 15); + m_mtr.write<2>(*m_block, + PAGE_HEADER + PAGE_N_RECS + m_page, m_rec_no); + m_mtr.write<2>(*m_block, + PAGE_HEADER + PAGE_LAST_INSERT + m_page, + ulint(m_cur_rec - m_page)); + m_mtr.write<2>(*m_block, + PAGE_HEADER + PAGE_DIRECTION_B - 1 + m_page, + PAGE_RIGHT); } else { /* For ROW_FORMAT=COMPRESSED, redo log may be written in PageBulk::compress(). */ @@ -333,18 +349,29 @@ PageBulk::finish() ulint(m_heap_top - m_page)); mach_write_to_2(PAGE_HEADER + PAGE_N_HEAP + m_page, (PAGE_HEAP_NO_USER_LOW + m_rec_no) - | ulint(m_is_comp) << 15); + | uint16_t{fmt != REDUNDANT} << 15); mach_write_to_2(PAGE_HEADER + PAGE_N_RECS + m_page, m_rec_no); mach_write_to_2(PAGE_HEADER + PAGE_LAST_INSERT + m_page, ulint(m_cur_rec - m_page)); mach_write_to_2(PAGE_HEADER + PAGE_DIRECTION_B - 1 + m_page, PAGE_RIGHT); - mach_write_to_2(PAGE_HEADER + PAGE_N_DIRECTION + m_page, 0); } m_block->skip_flush_check = false; } +/** Mark end of insertion to the page. Scan all records to set page dirs, +and set page header members. */ +inline void PageBulk::finish() +{ + if (UNIV_LIKELY_NULL(m_page_zip)) + finishPage<COMPRESSED>(); + else if (m_is_comp) + finishPage<DYNAMIC>(); + else + finishPage<REDUNDANT>(); +} + /** Commit inserts done to the page @param[in] success Flag whether all inserts succeed. */ void @@ -521,28 +548,24 @@ PageBulk::copyOut( @param[in] next_page_no next page no */ inline void PageBulk::setNext(ulint next_page_no) { - if (UNIV_LIKELY_NULL(m_page_zip)) { - /* For ROW_FORMAT=COMPRESSED, redo log may be written - in PageBulk::compress(). */ - mach_write_to_4(m_page + FIL_PAGE_NEXT, next_page_no); - } else { - mlog_write_ulint(m_page + FIL_PAGE_NEXT, next_page_no, - MLOG_4BYTES, &m_mtr); - } + if (UNIV_LIKELY_NULL(m_page_zip)) + /* For ROW_FORMAT=COMPRESSED, redo log may be written + in PageBulk::compress(). */ + mach_write_to_4(m_page + FIL_PAGE_NEXT, next_page_no); + else + m_mtr.write<4>(*m_block, m_page + FIL_PAGE_NEXT, next_page_no); } /** Set previous page @param[in] prev_page_no previous page no */ inline void PageBulk::setPrev(ulint prev_page_no) { - if (UNIV_LIKELY_NULL(m_page_zip)) { - /* For ROW_FORMAT=COMPRESSED, redo log may be written - in PageBulk::compress(). */ - mach_write_to_4(m_page + FIL_PAGE_PREV, prev_page_no); - } else { - mlog_write_ulint(m_page + FIL_PAGE_PREV, prev_page_no, - MLOG_4BYTES, &m_mtr); - } + if (UNIV_LIKELY_NULL(m_page_zip)) + /* For ROW_FORMAT=COMPRESSED, redo log may be written + in PageBulk::compress(). */ + mach_write_to_4(m_page + FIL_PAGE_PREV, prev_page_no); + else + m_mtr.write<4>(*m_block, m_page + FIL_PAGE_PREV, prev_page_no); } /** Check if required space is available in the page for the rec to be inserted. @@ -748,9 +771,10 @@ BtrBulk::pageCommit( page_bulk->setNext(next_page_bulk->getPageNo()); next_page_bulk->setPrev(page_bulk->getPageNo()); } else { - /** Suppose a page is released and latched again, we need to + ut_ad(!page_has_next(page_bulk->getPage())); + /* If a page is released and latched again, we need to mark it modified in mini-transaction. */ - page_bulk->setNext(FIL_NULL); + page_bulk->set_modified(); } ut_ad(!rw_lock_own_flagged(&m_index->lock, diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index f3609b3fa96..c181a5af058 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -154,8 +154,7 @@ static void btr_cur_unmark_extern_fields( /*=========================*/ - page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed - part will be updated, or NULL */ + buf_block_t* block, /*!< in/out: index page */ rec_t* rec, /*!< in/out: record in a clustered index */ dict_index_t* index, /*!< in: index of the page */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ @@ -181,8 +180,7 @@ btr_rec_free_updated_extern_fields( dict_index_t* index, /*!< in: index of rec; the index tree MUST be X-latched */ rec_t* rec, /*!< in: record */ - page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed - part will be updated, or NULL */ + buf_block_t* block, /*!< in: index page of rec */ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ const upd_t* update, /*!< in: update vector */ bool rollback,/*!< in: performing rollback? */ @@ -198,8 +196,7 @@ btr_rec_free_externally_stored_fields( tree MUST be X-latched */ rec_t* rec, /*!< in: record */ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ - page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed - part will be updated, or NULL */ + buf_block_t* block, /*!< in: index page of rec */ bool rollback,/*!< in: performing rollback? */ mtr_t* mtr); /*!< in: mini-transaction handle which contains an X-latch to record page and to the index @@ -224,7 +221,6 @@ btr_cur_latch_leaves( uint32_t left_page_no; uint32_t right_page_no; buf_block_t* get_block; - page_t* page = buf_block_get_frame(block); bool spatial; btr_latch_leaves_t latch_leaves = {{NULL, NULL, NULL}, {0, 0, 0}}; @@ -252,7 +248,8 @@ btr_cur_latch_leaves( true, mtr); latch_leaves.blocks[1] = get_block; #ifdef UNIV_BTR_DEBUG - ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); + ut_a(page_is_comp(get_block->frame) + == page_is_comp(block->frame)); #endif /* UNIV_BTR_DEBUG */ if (spatial) { cursor->rtr_info->tree_blocks[RTR_MAX_LEVELS] @@ -268,7 +265,7 @@ btr_cur_latch_leaves( dict_index_get_lock(cursor->index), MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); /* x-latch also siblings from left to right */ - left_page_no = btr_page_get_prev(page); + left_page_no = btr_page_get_prev(block->frame); if (left_page_no != FIL_NULL) { @@ -304,11 +301,12 @@ btr_cur_latch_leaves( /* Sanity check only after both the blocks are latched. */ if (latch_leaves.blocks[0] != NULL) { ut_a(page_is_comp(latch_leaves.blocks[0]->frame) - == page_is_comp(page)); + == page_is_comp(block->frame)); ut_a(btr_page_get_next(latch_leaves.blocks[0]->frame) - == page_get_page_no(page)); + == block->page.id.page_no()); } - ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); + ut_a(page_is_comp(get_block->frame) + == page_is_comp(block->frame)); #endif /* UNIV_BTR_DEBUG */ if (spatial) { @@ -316,7 +314,7 @@ btr_cur_latch_leaves( = get_block; } - right_page_no = btr_page_get_next(page); + right_page_no = btr_page_get_next(block->frame); if (right_page_no != FIL_NULL) { if (spatial) { @@ -331,9 +329,9 @@ btr_cur_latch_leaves( latch_leaves.blocks[2] = get_block; #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) - == page_is_comp(page)); + == page_is_comp(block->frame)); ut_a(btr_page_get_prev(get_block->frame) - == page_get_page_no(page)); + == block->page.id.page_no()); #endif /* UNIV_BTR_DEBUG */ if (spatial) { cursor->rtr_info->tree_blocks[ @@ -348,7 +346,7 @@ btr_cur_latch_leaves( mode = latch_mode == BTR_SEARCH_PREV ? RW_S_LATCH : RW_X_LATCH; /* latch also left sibling */ rw_lock_s_lock(&block->lock); - left_page_no = btr_page_get_prev(page); + left_page_no = btr_page_get_prev(block->frame); rw_lock_s_unlock(&block->lock); if (left_page_no != FIL_NULL) { @@ -360,9 +358,9 @@ btr_cur_latch_leaves( cursor->left_block = get_block; #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) - == page_is_comp(page)); + == page_is_comp(block->frame)); ut_a(btr_page_get_next(get_block->frame) - == page_get_page_no(page)); + == block->page.id.page_no()); #endif /* UNIV_BTR_DEBUG */ } @@ -372,7 +370,8 @@ btr_cur_latch_leaves( true, mtr); latch_leaves.blocks[1] = get_block; #ifdef UNIV_BTR_DEBUG - ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); + ut_a(page_is_comp(get_block->frame) + == page_is_comp(block->frame)); #endif /* UNIV_BTR_DEBUG */ return(latch_leaves); case BTR_CONT_MODIFY_TREE: @@ -2424,8 +2423,7 @@ need_opposite_intention: cursor->up_bytes = up_bytes; if (autoinc) { - page_set_autoinc(tree_blocks[0], - index, autoinc, mtr, false); + page_set_autoinc(tree_blocks[0], autoinc, mtr, false); } #ifdef BTR_CUR_HASH_ADAPT @@ -4160,8 +4158,6 @@ btr_cur_update_in_place( further pages */ { dict_index_t* index; - buf_block_t* block; - page_zip_des_t* page_zip; dberr_t err; rec_t* rec; roll_ptr_t roll_ptr = 0; @@ -4190,11 +4186,11 @@ btr_cur_update_in_place( << ") by " << ib::hex(trx_id) << ": " << rec_printer(rec, offsets).str()); - block = btr_cur_get_block(cursor); - page_zip = buf_block_get_page_zip(block); + buf_block_t* block = btr_cur_get_block(cursor); + page_zip_des_t* page_zip = buf_block_get_page_zip(block); /* Check that enough space is available on the compressed page. */ - if (page_zip) { + if (UNIV_LIKELY_NULL(page_zip)) { ut_ad(!index->table->is_temporary()); if (!btr_cur_update_alloc_zip( @@ -4277,8 +4273,7 @@ btr_cur_update_in_place( /* The new updated record owns its possible externally stored fields */ - btr_cur_unmark_extern_fields(page_zip, - rec, index, offsets, mtr); + btr_cur_unmark_extern_fields(block, rec, index, offsets, mtr); } ut_ad(err == DB_SUCCESS); @@ -4803,7 +4798,6 @@ btr_cur_pessimistic_update( big_rec_t* dummy_big_rec; dict_index_t* index; buf_block_t* block; - page_t* page; page_zip_des_t* page_zip; rec_t* rec; page_cur_t* page_cursor; @@ -4813,13 +4807,11 @@ btr_cur_pessimistic_update( ibool was_first; ulint n_reserved = 0; ulint n_ext; - ulint max_ins_size = 0; *offsets = NULL; *big_rec = NULL; block = btr_cur_get_block(cursor); - page = buf_block_get_frame(block); page_zip = buf_block_get_page_zip(block); index = cursor->index; @@ -4828,7 +4820,7 @@ btr_cur_pessimistic_update( MTR_MEMO_SX_LOCK)); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); #ifdef UNIV_ZIP_DEBUG - ut_a(!page_zip || page_zip_validate(page_zip, page, index)); + ut_a(!page_zip || page_zip_validate(page_zip, block->frame, index)); #endif /* UNIV_ZIP_DEBUG */ ut_ad(!page_zip || !index->table->is_temporary()); /* The insert buffer tree should never be updated in place. */ @@ -4861,7 +4853,7 @@ btr_cur_pessimistic_update( if (page_zip && optim_err != DB_ZIP_OVERFLOW && !dict_index_is_clust(index) - && page_is_leaf(page)) { + && page_is_leaf(block->frame)) { ut_ad(!index->table->is_temporary()); ibuf_update_free_bits_zip(block, mtr); } @@ -4910,7 +4902,7 @@ btr_cur_pessimistic_update( /* We have to set appropriate extern storage bits in the new record to be inserted: we have to remember which fields were such */ - ut_ad(!page_is_comp(page) || !rec_get_node_ptr_flag(rec)); + ut_ad(!page_is_comp(block->frame) || !rec_get_node_ptr_flag(rec)); ut_ad(rec_offs_validate(rec, index, *offsets)); if (index->is_primary()) { n_ext += btr_push_update_extern_fields( @@ -4933,12 +4925,12 @@ btr_cur_pessimistic_update( DEBUG_SYNC_C("blob_rollback_middle"); btr_rec_free_updated_extern_fields( - index, rec, page_zip, *offsets, update, true, mtr); + index, rec, block, *offsets, update, true, mtr); } if (page_zip_rec_needs_ext( rec_get_converted_size(index, new_entry, n_ext), - page_is_comp(page), + page_is_comp(block->frame), dict_index_get_n_fields(index), block->zip_size()) || (UNIV_UNLIKELY(update->is_alter_metadata()) @@ -4954,14 +4946,15 @@ btr_cur_pessimistic_update( BTR_KEEP_IBUF_BITMAP. */ #ifdef UNIV_ZIP_DEBUG ut_a(!page_zip - || page_zip_validate(page_zip, page, index)); + || page_zip_validate(page_zip, block->frame, + index)); #endif /* UNIV_ZIP_DEBUG */ index->table->space->release_free_extents(n_reserved); err = DB_TOO_BIG_RECORD; goto err_exit; } - ut_ad(page_is_leaf(page)); + ut_ad(page_is_leaf(block->frame)); ut_ad(dict_index_is_clust(index)); ut_ad(flags & BTR_KEEP_POS_FLAG); } @@ -4996,10 +4989,9 @@ btr_cur_pessimistic_update( btr_cur_write_sys(new_entry, index, trx_id, roll_ptr); } - if (!page_zip) { - max_ins_size = page_get_max_insert_size_after_reorganize( - page, 1); - } + const ulint max_ins_size = page_zip + ? 0 : page_get_max_insert_size_after_reorganize(block->frame, + 1); if (UNIV_UNLIKELY(is_metadata)) { ut_ad(new_entry->is_metadata()); @@ -5027,7 +5019,7 @@ btr_cur_pessimistic_update( } #ifdef UNIV_ZIP_DEBUG - ut_a(!page_zip || page_zip_validate(page_zip, page, index)); + ut_a(!page_zip || page_zip_validate(page_zip, block->frame, index)); #endif /* UNIV_ZIP_DEBUG */ page_cursor = btr_cur_get_page_cur(cursor); @@ -5058,8 +5050,8 @@ btr_cur_pessimistic_update( || rec_is_alter_metadata(rec, *index)) { /* The new inserted record owns its possible externally stored fields */ - btr_cur_unmark_extern_fields( - page_zip, rec, index, *offsets, mtr); + btr_cur_unmark_extern_fields(btr_cur_get_block(cursor), + rec, index, *offsets, mtr); } else { /* In delete-marked records, DB_TRX_ID must always refer to an existing undo log record. */ @@ -5067,7 +5059,7 @@ btr_cur_pessimistic_update( } bool adjust = big_rec_vec && (flags & BTR_KEEP_POS_FLAG); - ut_ad(!adjust || page_is_leaf(page)); + ut_ad(!adjust || page_is_leaf(block->frame)); if (btr_cur_compress_if_useful(cursor, adjust, mtr)) { if (adjust) { @@ -5075,7 +5067,7 @@ btr_cur_pessimistic_update( true, *offsets); } } else if (!dict_index_is_clust(index) - && page_is_leaf(page)) { + && page_is_leaf(block->frame)) { /* Update the free bits in the insert buffer. This is the same block which was skipped by BTR_KEEP_IBUF_BITMAP. */ @@ -5090,7 +5082,7 @@ btr_cur_pessimistic_update( if (!srv_read_only_mode && !big_rec_vec - && page_is_leaf(page) + && page_is_leaf(block->frame) && !dict_index_is_online_ddl(index)) { mtr_memo_release(mtr, dict_index_get_lock(index), @@ -5115,13 +5107,13 @@ btr_cur_pessimistic_update( BTR_KEEP_IBUF_BITMAP. */ if (!dict_index_is_clust(index) && !index->table->is_temporary() - && page_is_leaf(page)) { + && page_is_leaf(block->frame)) { ibuf_reset_free_bits(block); } } if (big_rec_vec != NULL) { - ut_ad(page_is_leaf(page)); + ut_ad(page_is_leaf(block->frame)); ut_ad(dict_index_is_clust(index)); ut_ad(flags & BTR_KEEP_POS_FLAG); @@ -5170,28 +5162,20 @@ btr_cur_pessimistic_update( /* Update PAGE_MAX_TRX_ID in the index page header. It was not updated by btr_cur_pessimistic_insert() because of BTR_NO_LOCKING_FLAG. */ - buf_block_t* rec_block; - - rec_block = btr_cur_get_block(cursor); - - page_update_max_trx_id(rec_block, - buf_block_get_page_zip(rec_block), + page_update_max_trx_id(btr_cur_get_block(cursor), + btr_cur_get_page_zip(cursor), trx_id, mtr); } if (!rec_get_deleted_flag(rec, rec_offs_comp(*offsets))) { /* The new inserted record owns its possible externally stored fields */ - buf_block_t* rec_block = btr_cur_get_block(cursor); - #ifdef UNIV_ZIP_DEBUG - ut_a(!page_zip || page_zip_validate(page_zip, page, index)); - page = buf_block_get_frame(rec_block); + ut_a(!page_zip || page_zip_validate(page_zip, block->frame, + index)); #endif /* UNIV_ZIP_DEBUG */ - page_zip = buf_block_get_page_zip(rec_block); - - btr_cur_unmark_extern_fields(page_zip, - rec, index, *offsets, mtr); + btr_cur_unmark_extern_fields(btr_cur_get_block(cursor), rec, + index, *offsets, mtr); } else { /* In delete-marked records, DB_TRX_ID must always refer to an existing undo log record. */ @@ -5222,7 +5206,8 @@ btr_cur_pessimistic_update( return_after_reservations: #ifdef UNIV_ZIP_DEBUG - ut_a(!page_zip || page_zip_validate(page_zip, page, index)); + ut_a(!page_zip || page_zip_validate(btr_cur_get_page_zip(cursor), + btr_cur_get_page(cursor), index)); #endif /* UNIV_ZIP_DEBUG */ index->table->space->release_free_extents(n_reserved); @@ -5393,7 +5378,6 @@ btr_cur_del_mark_set_clust_rec( { roll_ptr_t roll_ptr; dberr_t err; - page_zip_des_t* page_zip; trx_t* trx; ut_ad(dict_index_is_clust(index)); @@ -5431,7 +5415,7 @@ btr_cur_del_mark_set_clust_rec( the adaptive hash index does not depend on the delete-mark and the delete-mark is being updated in place. */ - page_zip = buf_block_get_page_zip(block); + page_zip_des_t* page_zip = buf_block_get_page_zip(block); btr_rec_set_deleted_flag(rec, page_zip, TRUE); @@ -5905,7 +5889,7 @@ btr_cur_pessimistic_delete( if (rec_offs_any_extern(offsets)) { btr_rec_free_externally_stored_fields(index, - rec, offsets, page_zip, + rec, offsets, block, rollback, mtr); #ifdef UNIV_ZIP_DEBUG ut_a(!page_zip || page_zip_validate(page_zip, page, index)); @@ -7144,13 +7128,12 @@ static void btr_cur_set_ownership_of_extern_field( /*==================================*/ - page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed - part will be updated, or NULL */ + buf_block_t* block, /*!< in/out: index page */ rec_t* rec, /*!< in/out: clustered index record */ dict_index_t* index, /*!< in: index of the page */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ ulint i, /*!< in: field number */ - ibool val, /*!< in: value to set */ + bool val, /*!< in: value to set */ mtr_t* mtr) /*!< in: mtr, or NULL if not logged */ { byte* data; @@ -7174,15 +7157,14 @@ btr_cur_set_ownership_of_extern_field( byte_val |= BTR_EXTERN_OWNER_FLAG; } - if (page_zip) { + if (UNIV_LIKELY_NULL(block->page.zip.data)) { mach_write_to_1(data + local_len + BTR_EXTERN_LEN, byte_val); - page_zip_write_blob_ptr(page_zip, rec, index, offsets, i, mtr); - } else if (mtr != NULL) { - - mlog_write_ulint(data + local_len + BTR_EXTERN_LEN, byte_val, - MLOG_1BYTE, mtr); + page_zip_write_blob_ptr(&block->page.zip, rec, index, offsets, + i, mtr); } else { - mach_write_to_1(data + local_len + BTR_EXTERN_LEN, byte_val); + mtr->write<1,mtr_t::OPT>(*block, + data + local_len + BTR_EXTERN_LEN, + byte_val); } } @@ -7194,8 +7176,7 @@ to free the field. */ void btr_cur_disown_inherited_fields( /*============================*/ - page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed - part will be updated, or NULL */ + buf_block_t* block, /*!< in/out: index page */ rec_t* rec, /*!< in/out: record in a clustered index */ dict_index_t* index, /*!< in: index of the page */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ @@ -7212,7 +7193,7 @@ btr_cur_disown_inherited_fields( if (rec_offs_nth_extern(offsets, i) && !upd_get_field_by_field_no(update, i, false)) { btr_cur_set_ownership_of_extern_field( - page_zip, rec, index, offsets, i, FALSE, mtr); + block, rec, index, offsets, i, false, mtr); } } } @@ -7225,29 +7206,23 @@ static void btr_cur_unmark_extern_fields( /*=========================*/ - page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed - part will be updated, or NULL */ + buf_block_t* block, /*!< in/out: index page */ rec_t* rec, /*!< in/out: record in a clustered index */ dict_index_t* index, /*!< in: index of the page */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ mtr_t* mtr) /*!< in: mtr, or NULL if not logged */ { - ulint n; - ulint i; - ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec)); - n = rec_offs_n_fields(offsets); - if (!rec_offs_any_extern(offsets)) { - return; } - for (i = 0; i < n; i++) { - if (rec_offs_nth_extern(offsets, i)) { + const ulint n = rec_offs_n_fields(offsets); + for (ulint i = 0; i < n; i++) { + if (rec_offs_nth_extern(offsets, i)) { btr_cur_set_ownership_of_extern_field( - page_zip, rec, index, offsets, i, TRUE, mtr); + block, rec, index, offsets, i, true, mtr); } } } @@ -7648,7 +7623,6 @@ btr_store_big_rec_extern_fields( for (ulint blob_npages = 0;; ++blob_npages) { buf_block_t* block; - page_t* page; const ulint commit_freq = 4; ulint r_extents; @@ -7711,11 +7685,9 @@ btr_store_big_rec_extern_fields( ut_a(block != NULL); page_no = block->page.id.page_no(); - page = buf_block_get_frame(block); if (prev_page_no != FIL_NULL) { buf_block_t* prev_block; - page_t* prev_page; prev_block = buf_page_get( page_id_t(space_id, prev_page_no), @@ -7724,23 +7696,25 @@ btr_store_big_rec_extern_fields( buf_block_dbg_add_level(prev_block, SYNC_EXTERN_STORAGE); - prev_page = buf_block_get_frame(prev_block); if (page_zip) { - mlog_write_ulint( - prev_page + FIL_PAGE_NEXT, - page_no, MLOG_4BYTES, &mtr); - memcpy(buf_block_get_page_zip( - prev_block) - ->data + FIL_PAGE_NEXT, - prev_page + FIL_PAGE_NEXT, 4); + mtr.write<4>(*prev_block, + prev_block->frame + + FIL_PAGE_NEXT, + page_no); + memcpy_aligned<4>( + buf_block_get_page_zip( + prev_block) + ->data + FIL_PAGE_NEXT, + prev_block->frame + + FIL_PAGE_NEXT, 4); } else { - mlog_write_ulint( - prev_page + FIL_PAGE_DATA - + BTR_BLOB_HDR_NEXT_PAGE_NO, - page_no, MLOG_4BYTES, &mtr); + mtr.write<4>(*prev_block, + BTR_BLOB_HDR_NEXT_PAGE_NO + + FIL_PAGE_DATA + + prev_block->frame, + page_no); } - } else if (dict_index_is_online_ddl(index)) { row_log_table_blob_alloc(index, page_no); } @@ -7751,7 +7725,7 @@ btr_store_big_rec_extern_fields( /* Write FIL_PAGE_TYPE to the redo log separately, before logging any other - changes to the page, so that the debug + changes to the block, so that the debug assertions in recv_parse_or_apply_log_rec_body() can be made simpler. Before InnoDB Plugin @@ -7759,13 +7733,13 @@ btr_store_big_rec_extern_fields( FIL_PAGE_TYPE was logged as part of the mlog_log_string() below. */ - mlog_write_ulint(page + FIL_PAGE_TYPE, - prev_page_no == FIL_NULL - ? FIL_PAGE_TYPE_ZBLOB - : FIL_PAGE_TYPE_ZBLOB2, - MLOG_2BYTES, &mtr); + mtr.write<2>(*block, + block->frame + FIL_PAGE_TYPE, + prev_page_no == FIL_NULL + ? FIL_PAGE_TYPE_ZBLOB + : FIL_PAGE_TYPE_ZBLOB2); - c_stream.next_out = page + c_stream.next_out = block->frame + FIL_PAGE_DATA; c_stream.avail_out = static_cast<uInt>( payload_size_zip); @@ -7799,15 +7773,13 @@ btr_store_big_rec_extern_fields( Number */ ut_ad(!dict_index_is_spatial(index)); - mlog_write_ulint(page - + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, - space_id, - MLOG_4BYTES, &mtr); - mlog_write_ulint(page - + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, - rec_page_no, - MLOG_4BYTES, &mtr); - mlog_log_string(page + mtr.write<4>(*block, block->frame + + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, + space_id); + mtr.write<4>(*block, block->frame + + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, + rec_page_no); + mlog_log_string(block->frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, page_zip_get_size(page_zip) - FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION @@ -7828,7 +7800,7 @@ btr_store_big_rec_extern_fields( ut_ad(blob_page_zip); ut_ad(page_zip_get_size(blob_page_zip) == page_zip_get_size(page_zip)); - memcpy(blob_page_zip->data, page, + memcpy(blob_page_zip->data, block->frame, page_zip_get_size(page_zip)); if (err == Z_OK && prev_page_no != FIL_NULL) { @@ -7880,9 +7852,9 @@ next_zip_page: break; } } else { - mlog_write_ulint(page + FIL_PAGE_TYPE, - FIL_PAGE_TYPE_BLOB, - MLOG_2BYTES, &mtr); + mtr.write<2>(*block, FIL_PAGE_TYPE + + block->frame, + FIL_PAGE_TYPE_BLOB); if (extern_len > payload_size) { store_len = payload_size; @@ -7890,47 +7862,44 @@ next_zip_page: store_len = extern_len; } - mlog_write_string(page + FIL_PAGE_DATA - + BTR_BLOB_HDR_SIZE, + mlog_write_string(FIL_PAGE_DATA + + BTR_BLOB_HDR_SIZE + + block->frame, (const byte*) big_rec_vec->fields[i].data + big_rec_vec->fields[i].len - extern_len, store_len, &mtr); - mlog_write_ulint(page + FIL_PAGE_DATA - + BTR_BLOB_HDR_PART_LEN, - store_len, MLOG_4BYTES, &mtr); - mlog_write_ulint(page + FIL_PAGE_DATA - + BTR_BLOB_HDR_NEXT_PAGE_NO, - FIL_NULL, MLOG_4BYTES, &mtr); + mtr.write<4>(*block, BTR_BLOB_HDR_PART_LEN + + FIL_PAGE_DATA + block->frame, + store_len); + compile_time_assert(FIL_NULL == 0xffffffff); + mlog_memset(block, BTR_BLOB_HDR_NEXT_PAGE_NO + + FIL_PAGE_DATA, 4, 0xff, &mtr); extern_len -= store_len; ut_ad(!mach_read_from_4(BTR_EXTERN_LEN + field_ref)); - mlog_write_ulint(field_ref - + BTR_EXTERN_LEN + 4, - big_rec_vec->fields[i].len - - extern_len, - MLOG_4BYTES, &mtr); + mtr.write<4>(*rec_block, + BTR_EXTERN_LEN + 4 + field_ref, + big_rec_vec->fields[i].len + - extern_len); if (prev_page_no == FIL_NULL) { ut_ad(blob_npages == 0); - mlog_write_ulint(field_ref - + BTR_EXTERN_SPACE_ID, - space_id, MLOG_4BYTES, - &mtr); - - mlog_write_ulint(field_ref - + BTR_EXTERN_PAGE_NO, - page_no, MLOG_4BYTES, - &mtr); - - mlog_write_ulint(field_ref - + BTR_EXTERN_OFFSET, - FIL_PAGE_DATA, - MLOG_4BYTES, - &mtr); + mtr.write<4,mtr_t::OPT>( + *rec_block, + field_ref + BTR_EXTERN_SPACE_ID, + space_id); + + mtr.write<4>(*rec_block, field_ref + + BTR_EXTERN_PAGE_NO, + page_no); + + mtr.write<4>(*rec_block, field_ref + + BTR_EXTERN_OFFSET, + FIL_PAGE_DATA); } prev_page_no = page_no; @@ -8038,8 +8007,7 @@ btr_free_externally_stored_field( page_zip_write_blob_ptr(), or NULL */ const ulint* offsets, /*!< in: rec_get_offsets(rec, index), or NULL */ - page_zip_des_t* page_zip, /*!< in: compressed page corresponding - to rec, or NULL if rec == NULL */ + buf_block_t* block, /*!< in/out: page of field_ref */ ulint i, /*!< in: field number of field_ref; ignored if rec == NULL */ bool rollback, /*!< in: performing rollback? */ @@ -8084,10 +8052,8 @@ btr_free_externally_stored_field( const ulint ext_zip_size = index->table->space->zip_size(); const ulint rec_zip_size = rec ? ext_zip_size : 0; - if (rec == NULL) { - /* This is a call from row_purge_upd_exist_or_extern(). */ - ut_ad(!page_zip); - } + /* !rec holds in a call from purge when field_ref is in an undo page */ + ut_ad(rec || !block->page.zip.data); for (;;) { #ifdef UNIV_DEBUG @@ -8156,24 +8122,23 @@ btr_free_externally_stored_field( btr_page_free(index, ext_block, &mtr, true); - if (page_zip != NULL) { + if (UNIV_LIKELY_NULL(block->page.zip.data)) { mach_write_to_4(field_ref + BTR_EXTERN_PAGE_NO, next_page_no); - mach_write_to_4(field_ref + BTR_EXTERN_LEN + 4, - 0); - page_zip_write_blob_ptr(page_zip, rec, index, + memset(field_ref + BTR_EXTERN_LEN, 0, 4); + page_zip_write_blob_ptr(&block->page.zip, + rec, index, offsets, i, &mtr); } else { - mlog_write_ulint(field_ref - + BTR_EXTERN_PAGE_NO, - next_page_no, - MLOG_4BYTES, &mtr); - mlog_write_ulint(field_ref - + BTR_EXTERN_LEN + 4, 0, - MLOG_4BYTES, &mtr); + mtr.write<4>(*block, + BTR_EXTERN_PAGE_NO + field_ref, + next_page_no); + mtr.write<4>(*block, + BTR_EXTERN_LEN + 4 + field_ref, + 0U); } } else { - ut_a(!page_zip); + ut_ad(!block->page.zip.data); btr_check_blob_fil_page_type(space_id, page_no, page, FALSE); @@ -8182,17 +8147,16 @@ btr_free_externally_stored_field( + BTR_BLOB_HDR_NEXT_PAGE_NO); btr_page_free(index, ext_block, &mtr, true); - mlog_write_ulint(field_ref + BTR_EXTERN_PAGE_NO, - next_page_no, - MLOG_4BYTES, &mtr); + mtr.write<4>(*block, BTR_EXTERN_PAGE_NO + field_ref, + next_page_no); /* Zero out the BLOB length. If the server crashes during the execution of this function, trx_rollback_all_recovered() could dereference the half-deleted BLOB, fetching a wrong prefix for the BLOB. */ - mlog_write_ulint(field_ref + BTR_EXTERN_LEN + 4, - 0, - MLOG_4BYTES, &mtr); + mtr.write<4,mtr_t::OPT>(*block, + BTR_EXTERN_LEN + 4 + field_ref, + 0U); } /* Commit mtr and release the BLOB block to save memory. */ @@ -8210,8 +8174,7 @@ btr_rec_free_externally_stored_fields( tree MUST be X-latched */ rec_t* rec, /*!< in/out: record */ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ - page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed - part will be updated, or NULL */ + buf_block_t* block, /*!< in: index page of rec */ bool rollback,/*!< in: performing rollback? */ mtr_t* mtr) /*!< in: mini-transaction handle which contains an X-latch to record page and to the index @@ -8233,7 +8196,7 @@ btr_rec_free_externally_stored_fields( if (rec_offs_nth_extern(offsets, i)) { btr_free_externally_stored_field( index, btr_rec_get_field_ref(rec, offsets, i), - rec, offsets, page_zip, i, rollback, mtr); + rec, offsets, block, i, rollback, mtr); } } } @@ -8248,8 +8211,7 @@ btr_rec_free_updated_extern_fields( dict_index_t* index, /*!< in: index of rec; the index tree MUST be X-latched */ rec_t* rec, /*!< in/out: record */ - page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed - part will be updated, or NULL */ + buf_block_t* block, /*!< in: index page of rec */ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ const upd_t* update, /*!< in: update vector */ bool rollback,/*!< in: performing rollback? */ @@ -8277,7 +8239,7 @@ btr_rec_free_updated_extern_fields( btr_free_externally_stored_field( index, data + len - BTR_EXTERN_FIELD_REF_SIZE, - rec, offsets, page_zip, + rec, offsets, block, ufield->field_no, rollback, mtr); } } |