diff options
Diffstat (limited to 'storage/innobase/btr/btr0btr.cc')
-rw-r--r-- | storage/innobase/btr/btr0btr.cc | 345 |
1 files changed, 214 insertions, 131 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 606ab114b2f..1b3ea2eb487 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -26,9 +26,7 @@ Created 6/2/1994 Heikki Tuuri *******************************************************/ #include "btr0btr.h" -#include "ha_prototypes.h" -#include "fsp0sysspace.h" #include "page0page.h" #include "page0zip.h" #include "gis0rtree.h" @@ -43,10 +41,11 @@ Created 6/2/1994 Heikki Tuuri #include "trx0trx.h" #include "srv0mon.h" #include "gis0geo.h" -#include "ut0new.h" #include "dict0boot.h" #include "row0sel.h" /* row_search_max_autoinc() */ +Atomic_counter<uint32_t> btr_validate_index_running; + /**************************************************************//** Checks if the page in the cursor can be merged with given page. If necessary, re-organize the merge_page. @@ -60,15 +59,12 @@ btr_can_merge_with_page( buf_block_t** merge_block, /*!< out: the merge block */ mtr_t* mtr); /*!< in: mini-transaction */ -/**************************************************************//** -Report that an index page is corrupted. */ -void -btr_corruption_report( -/*==================*/ - const buf_block_t* block, /*!< in: corrupted block */ - const dict_index_t* index) /*!< in: index tree */ +/** Report that an index page is corrupted. +@param[in] buffer block +@param[in] index tree */ +void btr_corruption_report(const buf_block_t* block, const dict_index_t* index) { - ib::error() + ib::fatal() << "Flag mismatch in page " << block->page.id << " index " << index->name << " of table " << index->table->name; @@ -228,7 +224,7 @@ btr_root_block_get( } buf_block_t* block = btr_block_get( - page_id_t(index->table->space->id, index->page), + page_id_t(index->table->space_id, index->page), page_size_t(index->table->space->flags), mode, index, mtr); @@ -253,9 +249,9 @@ btr_root_block_get( const page_t* root = buf_block_get_frame(block); ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF - + root, index->table->space->id)); + + root, index->table->space_id)); ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP - + root, index->table->space->id)); + + root, index->table->space_id)); } #endif /* UNIV_BTR_DEBUG */ @@ -366,7 +362,7 @@ btr_root_adjust_on_import( buf_block_t* block; page_zip_des_t* page_zip; dict_table_t* table = index->table; - const page_id_t page_id(table->space->id, index->page); + const page_id_t page_id(table->space_id, index->page); const page_size_t page_size(table->space->flags); DBUG_EXECUTE_IF("ib_import_trigger_corruption_3", @@ -408,10 +404,10 @@ btr_root_adjust_on_import( if (err == DB_SUCCESS && (!btr_root_fseg_adjust_on_import( FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF - + page, page_zip, table->space->id, &mtr) + + page, page_zip, table->space_id, &mtr) || !btr_root_fseg_adjust_on_import( FIL_PAGE_DATA + PAGE_BTR_SEG_TOP - + page, page_zip, table->space->id, &mtr))) { + + page, page_zip, table->space_id, &mtr))) { err = DB_CORRUPTION; } @@ -477,7 +473,7 @@ btr_page_alloc_for_ibuf( ut_a(node_addr.page != FIL_NULL); new_block = buf_page_get( - page_id_t(index->table->space->id, node_addr.page), + page_id_t(index->table->space_id, node_addr.page), page_size_t(index->table->space->flags), RW_X_LATCH, mtr); @@ -926,11 +922,11 @@ btr_node_ptr_get_child( mtr_t* mtr) /*!< in: mtr */ { ut_ad(rec_offs_validate(node_ptr, index, offsets)); - ut_ad(index->table->space->id + ut_ad(index->table->space_id == page_get_space_id(page_align(node_ptr))); return btr_block_get( - page_id_t(index->table->space->id, + page_id_t(index->table->space_id, btr_node_ptr_get_child_page_no(node_ptr, offsets)), page_size_t(index->table->space->flags), RW_SX_LATCH, index, mtr); @@ -1149,7 +1145,7 @@ btr_free_root_invalidate( static MY_ATTRIBUTE((warn_unused_result)) buf_block_t* btr_free_root_check( - const page_id_t& page_id, + const page_id_t page_id, const page_size_t& page_size, index_id_t index_id, mtr_t* mtr) @@ -1377,7 +1373,7 @@ top_loop: @param[in,out] mtr mini-transaction */ void btr_free_if_exists( - const page_id_t& page_id, + const page_id_t page_id, const page_size_t& page_size, index_id_t index_id, mtr_t* mtr) @@ -1401,7 +1397,7 @@ btr_free_if_exists( @param[in] page_size page size */ void btr_free( - const page_id_t& page_id, + const page_id_t page_id, const page_size_t& page_size) { mtr_t mtr; @@ -1434,7 +1430,7 @@ btr_read_autoinc(dict_index_t* index) mtr.start(); ib_uint64_t autoinc; if (buf_block_t* block = buf_page_get( - page_id_t(index->table->space->id, index->page), + page_id_t(index->table->space_id, index->page), page_size_t(index->table->space->flags), RW_S_LATCH, &mtr)) { autoinc = page_get_autoinc(block->frame); @@ -1466,7 +1462,7 @@ btr_read_autoinc_with_fallback(const dict_table_t* table, unsigned col_no) mtr_t mtr; mtr.start(); buf_block_t* block = buf_page_get( - page_id_t(index->table->space->id, index->page), + page_id_t(index->table->space_id, index->page), page_size_t(index->table->space->flags), RW_S_LATCH, &mtr); @@ -1660,11 +1656,6 @@ btr_page_reorganize_low( goto func_exit; } - if (!recovery && !dict_table_is_locking_disabled(index->table)) { - /* Update the record lock bitmaps */ - lock_move_reorganize_page(block, temp_block); - } - data_size2 = page_get_data_size(page); max_ins_size2 = page_get_max_insert_size_after_reorganize(page, 1); @@ -1688,21 +1679,41 @@ btr_page_reorganize_low( ut_ad(cursor->rec == page_get_infimum_rec(page)); } -func_exit: #ifdef UNIV_ZIP_DEBUG ut_a(!page_zip || page_zip_validate(page_zip, page, index)); #endif /* UNIV_ZIP_DEBUG */ - if (!recovery && page_is_root(temp_page) - && fil_page_get_type(temp_page) == FIL_PAGE_TYPE_INSTANT) { - /* Preserve the PAGE_INSTANT information. */ - ut_ad(!page_zip); - ut_ad(index->is_instant()); - memcpy(FIL_PAGE_TYPE + page, FIL_PAGE_TYPE + temp_page, 2); - memcpy(PAGE_HEADER + PAGE_INSTANT + page, - PAGE_HEADER + PAGE_INSTANT + temp_page, 2); + if (!recovery) { + if (page_is_root(temp_page) + && fil_page_get_type(temp_page) == FIL_PAGE_TYPE_INSTANT) { + /* Preserve the PAGE_INSTANT information. */ + ut_ad(!page_zip); + ut_ad(index->is_instant()); + memcpy(FIL_PAGE_TYPE + page, + FIL_PAGE_TYPE + temp_page, 2); + memcpy(PAGE_HEADER + PAGE_INSTANT + page, + PAGE_HEADER + PAGE_INSTANT + temp_page, 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 { + memcpy(PAGE_OLD_INFIMUM + page, + PAGE_OLD_INFIMUM + temp_page, 8); + memcpy(PAGE_OLD_SUPREMUM + page, + PAGE_OLD_SUPREMUM + temp_page, 8); + } + } + + if (!dict_table_is_locking_disabled(index->table)) { + /* Update the record lock bitmaps */ + lock_move_reorganize_page(block, temp_block); + } } +func_exit: buf_block_free(temp_block); /* Restore logging mode */ @@ -1748,6 +1759,14 @@ func_exit: mach_read_from_2(PAGE_HEADER + PAGE_INSTANT + page), MLOG_2BYTES, mtr); + 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 { + mlog_log_string(PAGE_OLD_INFIMUM + page, 8, mtr); + mlog_log_string(PAGE_OLD_SUPREMUM + page, 8, mtr); + } } return(success); @@ -1895,6 +1914,59 @@ btr_page_empty( } } +/** Write instant ALTER TABLE metadata to a root page. +@param[in,out] root clustered index root page +@param[in] index clustered index with instant ALTER TABLE +@param[in,out] mtr mini-transaction */ +void btr_set_instant(buf_block_t* root, const dict_index_t& index, mtr_t* mtr) +{ + ut_ad(index.n_core_fields > 0); + ut_ad(index.n_core_fields < REC_MAX_N_FIELDS); + ut_ad(index.is_instant()); + ut_ad(page_is_root(root->frame)); + + rec_t* infimum = page_get_infimum_rec(root->frame); + rec_t* supremum = page_get_supremum_rec(root->frame); + byte* page_type = root->frame + FIL_PAGE_TYPE; + uint16_t i = page_header_get_field(root->frame, PAGE_INSTANT); + + switch (mach_read_from_2(page_type)) { + case FIL_PAGE_TYPE_INSTANT: + ut_ad(page_get_instant(root->frame) == index.n_core_fields); + if (memcmp(infimum, "infimum", 8) + || memcmp(supremum, "supremum", 8)) { + ut_ad(index.table->instant); + ut_ad(!memcmp(infimum, field_ref_zero, 8)); + ut_ad(!memcmp(supremum, field_ref_zero, 7)); + ut_ad(supremum[7] == index.n_core_null_bytes); + return; + } + break; + default: + ut_ad(!"wrong page type"); + /* fall through */ + case FIL_PAGE_INDEX: + ut_ad(!page_is_comp(root->frame) + || !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); + 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); + 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); + } +} + /*************************************************************//** Makes tree one level higher by splitting the root, and inserts the tuple. It is assumed that mtr contains an x-latch on the tree. @@ -1941,7 +2013,7 @@ btr_root_raise_and_insert( #endif /* UNIV_ZIP_DEBUG */ #ifdef UNIV_BTR_DEBUG if (!dict_index_is_ibuf(index)) { - ulint space = index->table->space->id; + ulint space = index->table->space_id; ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + root, space)); @@ -2080,11 +2152,7 @@ btr_root_raise_and_insert( if (index->is_instant()) { ut_ad(!root_page_zip); - byte* page_type = root_block->frame + FIL_PAGE_TYPE; - ut_ad(mach_read_from_2(page_type) == FIL_PAGE_INDEX); - mlog_write_ulint(page_type, FIL_PAGE_TYPE_INSTANT, - MLOG_2BYTES, mtr); - page_set_instant(root_block->frame, index->n_core_fields, mtr); + btr_set_instant(root_block, *index, mtr); } /* Set the next node and previous node fields, although @@ -3569,12 +3637,7 @@ btr_lift_page_up( if (page_level == 0 && index->is_instant()) { ut_ad(!father_page_zip); - byte* page_type = father_block->frame + FIL_PAGE_TYPE; - ut_ad(mach_read_from_2(page_type) == FIL_PAGE_INDEX); - mlog_write_ulint(page_type, FIL_PAGE_TYPE_INSTANT, - MLOG_2BYTES, mtr); - page_set_instant(father_block->frame, - index->n_core_fields, mtr); + btr_set_instant(father_block, *index, mtr); } page_level++; @@ -3868,7 +3931,7 @@ retry: btr_search_drop_page_hash_index(block); /* Remove the page from the level list */ - btr_level_list_remove(index->table->space->id, + btr_level_list_remove(index->table->space_id, page_size, page, index, mtr); if (dict_index_is_spatial(index)) { @@ -3998,7 +4061,7 @@ retry: #endif /* UNIV_BTR_DEBUG */ /* Remove the page from the level list */ - btr_level_list_remove(index->table->space->id, + btr_level_list_remove(index->table->space_id, page_size, page, index, mtr); ut_ad(btr_node_ptr_get_child_page_no( @@ -4238,7 +4301,7 @@ btr_discard_only_page_on_level( #ifdef UNIV_BTR_DEBUG if (!dict_index_is_ibuf(index)) { const page_t* root = buf_block_get_frame(block); - const ulint space = index->table->space->id; + const ulint space = index->table->space_id; ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + root, space)); ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP @@ -4246,15 +4309,42 @@ btr_discard_only_page_on_level( } #endif /* UNIV_BTR_DEBUG */ + mem_heap_t* heap = NULL; + const rec_t* rec = NULL; + ulint* offsets = NULL; + if (index->table->instant) { + const rec_t* r = page_rec_get_next(page_get_infimum_rec( + block->frame)); + ut_ad(rec_is_metadata(r, *index) == index->is_instant()); + if (rec_is_alter_metadata(r, *index)) { + heap = mem_heap_create(srv_page_size); + offsets = rec_get_offsets(r, index, NULL, true, + ULINT_UNDEFINED, &heap); + rec = rec_copy(mem_heap_alloc(heap, + rec_offs_size(offsets)), + r, offsets); + rec_offs_make_valid(rec, index, true, offsets); + } + } + btr_page_empty(block, buf_block_get_page_zip(block), index, 0, mtr); ut_ad(page_is_leaf(buf_block_get_frame(block))); /* btr_page_empty() is supposed to zero-initialize the field. */ ut_ad(!page_get_instant(block->frame)); if (index->is_primary()) { - /* Concurrent access is prevented by the root_block->lock - X-latch, so this should be safe. */ - index->remove_instant(); + if (rec) { + DBUG_ASSERT(index->table->instant); + DBUG_ASSERT(rec_is_alter_metadata(rec, *index)); + btr_set_instant(block, *index, mtr); + rec = page_cur_insert_rec_low( + page_get_infimum_rec(block->frame), + index, rec, offsets, mtr); + ut_ad(rec); + mem_heap_free(heap); + } else if (index->is_instant()) { + index->clear_instant_add(); + } } else if (!index->table->is_temporary()) { /* We play it safe and reset the free bits for the root */ ibuf_reset_free_bits(block); @@ -4319,7 +4409,7 @@ btr_discard_page( if (left_page_no != FIL_NULL) { merge_block = btr_block_get( - page_id_t(index->table->space->id, left_page_no), + page_id_t(index->table->space_id, left_page_no), page_size, RW_X_LATCH, index, mtr); merge_page = buf_block_get_frame(merge_block); @@ -4335,7 +4425,7 @@ btr_discard_page( == btr_cur_get_rec(&parent_cursor))); } else if (right_page_no != FIL_NULL) { merge_block = btr_block_get( - page_id_t(index->table->space->id, right_page_no), + page_id_t(index->table->space_id, right_page_no), page_size, RW_X_LATCH, index, mtr); merge_page = buf_block_get_frame(merge_block); @@ -4384,7 +4474,7 @@ btr_discard_page( } /* Remove the page from the level list */ - btr_level_list_remove(index->table->space->id, page_size, + btr_level_list_remove(index->table->space_id, page_size, page, index, mtr); #ifdef UNIV_ZIP_DEBUG @@ -4553,7 +4643,7 @@ btr_print_index( mtr_commit(&mtr); - ut_ad(btr_validate_index(index, 0, false)); + ut_ad(btr_validate_index(index, 0)); } #endif /* UNIV_BTR_PRINT */ @@ -4678,14 +4768,32 @@ btr_index_rec_validate( return(FALSE); } + const bool is_alter_metadata = page_is_leaf(page) + && !page_has_prev(page) + && index->is_primary() && index->table->instant + && rec == page_rec_get_next_const(page_get_infimum_rec(page)); + + if (is_alter_metadata + && !rec_is_alter_metadata(rec, page_is_comp(page))) { + btr_index_rec_validate_report(page, rec, index); + + ib::error() << "First record is not ALTER TABLE metadata"; + return FALSE; + } + if (!page_is_comp(page)) { const ulint n_rec_fields = rec_get_n_fields_old(rec); if (n_rec_fields == DICT_FLD__SYS_INDEXES__MERGE_THRESHOLD && index->id == DICT_INDEXES_ID) { /* A record for older SYS_INDEXES table (missing merge_threshold column) is acceptable. */ + } else if (is_alter_metadata) { + if (n_rec_fields != ulint(index->n_fields) + 1) { + goto n_field_mismatch; + } } else if (n_rec_fields < index->n_core_fields || n_rec_fields > index->n_fields) { +n_field_mismatch: btr_index_rec_validate_report(page, rec, index); ib::error() << "Has " << rec_get_n_fields_old(rec) @@ -4704,15 +4812,28 @@ btr_index_rec_validate( offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page), ULINT_UNDEFINED, &heap); + const dict_field_t* field = index->fields; + ut_ad(rec_offs_n_fields(offsets) + == ulint(index->n_fields) + is_alter_metadata); - for (unsigned i = 0; i < index->n_fields; i++) { - dict_field_t* field = dict_index_get_nth_field(index, i); - ulint fixed_size = dict_col_get_fixed_size( - dict_field_get_col(field), - page_is_comp(page)); - + for (unsigned i = 0; i < rec_offs_n_fields(offsets); i++) { rec_get_nth_field_offs(offsets, i, &len); + ulint fixed_size; + + if (is_alter_metadata && i == index->first_user_field()) { + fixed_size = FIELD_REF_SIZE; + if (len != FIELD_REF_SIZE + || !rec_offs_nth_extern(offsets, i)) { + goto len_mismatch; + } + + continue; + } else { + fixed_size = dict_col_get_fixed_size( + field->col, page_is_comp(page)); + } + /* Note that if fixed_size != 0, it equals the length of a fixed-size column in the clustered index. We should adjust it here. @@ -4724,8 +4845,8 @@ btr_index_rec_validate( && (field->prefix_len ? len > field->prefix_len : (fixed_size && len != fixed_size))) { +len_mismatch: btr_index_rec_validate_report(page, rec, index); - ib::error error; error << "Field " << i << " len is " << len @@ -4743,6 +4864,8 @@ btr_index_rec_validate( } return(FALSE); } + + field++; } #ifdef VIRTUAL_INDEX_DEBUG @@ -4941,7 +5064,7 @@ btr_validate_level( ret = false; } - ut_a(index->table->space->id == block->page.id.space()); + ut_a(index->table->space_id == block->page.id.space()); ut_a(block->page.id.space() == page_get_space_id(page)); #ifdef UNIV_ZIP_DEBUG page_zip = buf_block_get_page_zip(block); @@ -4978,7 +5101,7 @@ btr_validate_level( savepoint2 = mtr_set_savepoint(&mtr); block = btr_block_get( - page_id_t(index->table->space->id, + page_id_t(index->table->space_id, left_page_no), table_page_size, RW_SX_LATCH, index, &mtr); @@ -5007,7 +5130,7 @@ loop: ut_a(!page_zip || page_zip_validate(page_zip, page, index)); #endif /* UNIV_ZIP_DEBUG */ - ut_a(block->page.id.space() == index->table->space->id); + ut_a(block->page.id.space() == index->table->space_id); if (fseg_page_is_free(space, block->page.id.page_no())) { @@ -5050,7 +5173,7 @@ loop: savepoint = mtr_set_savepoint(&mtr); right_block = btr_block_get( - page_id_t(index->table->space->id, right_page_no), + page_id_t(index->table->space_id, right_page_no), table_page_size, RW_SX_LATCH, index, &mtr); @@ -5227,13 +5350,13 @@ loop: &mtr, savepoint, right_block); btr_block_get( - page_id_t(index->table->space->id, + page_id_t(index->table->space_id, parent_right_page_no), table_page_size, RW_SX_LATCH, index, &mtr); right_block = btr_block_get( - page_id_t(index->table->space->id, + page_id_t(index->table->space_id, right_page_no), table_page_size, RW_SX_LATCH, index, &mtr); @@ -5311,14 +5434,14 @@ node_ptr_fails: if (parent_right_page_no != FIL_NULL) { btr_block_get( page_id_t( - index->table->space->id, + index->table->space_id, parent_right_page_no), table_page_size, RW_SX_LATCH, index, &mtr); } } else if (parent_page_no != FIL_NULL) { btr_block_get( - page_id_t(index->table->space->id, + page_id_t(index->table->space_id, parent_page_no), table_page_size, RW_SX_LATCH, index, &mtr); @@ -5326,7 +5449,7 @@ node_ptr_fails: } block = btr_block_get( - page_id_t(index->table->space->id, right_page_no), + page_id_t(index->table->space_id, right_page_no), table_page_size, RW_SX_LATCH, index, &mtr); @@ -5341,57 +5464,16 @@ node_ptr_fails: } /**************************************************************//** -Do an index level validation of spaital index tree. -@return true if no error found */ -static -bool -btr_validate_spatial_index( -/*=======================*/ - dict_index_t* index, /*!< in: index */ - const trx_t* trx) /*!< in: transaction or NULL */ -{ - - mtr_t mtr; - bool ok = true; - - mtr_start(&mtr); - - mtr_x_lock(dict_index_get_lock(index), &mtr); - - page_t* root = btr_root_get(index, &mtr); - ulint n = btr_page_get_level(root); - -#ifdef UNIV_RTR_DEBUG - fprintf(stderr, "R-tree level is %lu\n", n); -#endif /* UNIV_RTR_DEBUG */ - - for (ulint i = 0; i <= n; ++i) { -#ifdef UNIV_RTR_DEBUG - fprintf(stderr, "Level %lu:\n", n - i); -#endif /* UNIV_RTR_DEBUG */ - - if (!btr_validate_level(index, trx, n - i, true)) { - ok = false; - break; - } - } - - mtr_commit(&mtr); - - return(ok); -} - -/**************************************************************//** Checks the consistency of an index tree. @return DB_SUCCESS if ok, error code if not */ dberr_t btr_validate_index( /*===============*/ dict_index_t* index, /*!< in: index */ - const trx_t* trx, /*!< in: transaction or NULL */ - bool lockout)/*!< in: true if X-latch index is intended */ + const trx_t* trx) /*!< in: transaction or NULL */ { dberr_t err = DB_SUCCESS; + bool lockout = dict_index_is_spatial(index); /* Full Text index are implemented by auxiliary tables, not the B-tree */ @@ -5399,13 +5481,6 @@ btr_validate_index( return(err); } - if (dict_index_is_spatial(index)) { - if(!btr_validate_spatial_index(index, trx)) { - err = DB_ERROR; - } - return(err); - } - mtr_t mtr; mtr_start(&mtr); @@ -5420,14 +5495,14 @@ btr_validate_index( page_t* root = btr_root_get(index, &mtr); - if (root == NULL && !index->is_readable()) { - err = DB_DECRYPTION_FAILED; + if (!root) { mtr_commit(&mtr); - return err; + return DB_CORRUPTION; } ulint n = btr_page_get_level(root); + btr_validate_index_running++; for (ulint i = 0; i <= n; ++i) { if (!btr_validate_level(index, trx, n - i, lockout)) { @@ -5437,6 +5512,14 @@ btr_validate_index( } mtr_commit(&mtr); + /* In theory we need release barrier here, so that + btr_validate_index_running decrement is guaranteed to + happen after latches are released. + + Original code issued SEQ_CST on update and non-atomic + access on load. Which means it had broken synchronisation + as well. */ + btr_validate_index_running--; return(err); } @@ -5472,7 +5555,7 @@ btr_can_merge_with_page( index = btr_cur_get_index(cursor); page = btr_cur_get_page(cursor); - const page_id_t page_id(index->table->space->id, page_no); + const page_id_t page_id(index->table->space_id, page_no); const page_size_t page_size(index->table->space->flags); mblock = btr_block_get(page_id, page_size, RW_X_LATCH, index, mtr); |