diff options
Diffstat (limited to 'storage/innobase/btr/btr0btr.cc')
-rw-r--r-- | storage/innobase/btr/btr0btr.cc | 142 |
1 files changed, 49 insertions, 93 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 7e2436a6356..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); @@ -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); @@ -2017,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)); @@ -3935,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)) { @@ -4065,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( @@ -4305,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 @@ -4413,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); @@ -4429,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); @@ -4478,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 @@ -4647,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 */ @@ -5068,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); @@ -5105,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); @@ -5134,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())) { @@ -5177,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); @@ -5354,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); @@ -5438,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); @@ -5453,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); @@ -5468,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 */ @@ -5526,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); @@ -5547,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)) { @@ -5564,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); } @@ -5599,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); |