Commit d2660362 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-12266: Remove lookups when dropping indexes

btr_free_root_check(), btr_free_if_exists():
Replace page_id, page_size with fil_space_t* and the
root page number.

btr_free_but_not_root(): Take fil_space_t* as a parameter,
or NULL if the operation is not going to be redo-logged.

btr_free(): Pass space=NULL to btr_free_but_not_root().
parent 556a9202
...@@ -1140,8 +1140,8 @@ btr_free_root_invalidate( ...@@ -1140,8 +1140,8 @@ btr_free_root_invalidate(
} }
/** Prepare to free a B-tree. /** Prepare to free a B-tree.
@param[in] page_id page id @param[in,out] space tablespace
@param[in] page_size page size @param[in] page root page number
@param[in] index_id PAGE_INDEX_ID contents @param[in] index_id PAGE_INDEX_ID contents
@param[in,out] mtr mini-transaction @param[in,out] mtr mini-transaction
@return root block, to invoke btr_free_but_not_root() and btr_free_root() @return root block, to invoke btr_free_but_not_root() and btr_free_root()
...@@ -1149,32 +1149,32 @@ btr_free_root_invalidate( ...@@ -1149,32 +1149,32 @@ btr_free_root_invalidate(
static MY_ATTRIBUTE((warn_unused_result)) static MY_ATTRIBUTE((warn_unused_result))
buf_block_t* buf_block_t*
btr_free_root_check( btr_free_root_check(
const page_id_t& page_id, fil_space_t* space,
const page_size_t& page_size, ulint page,
index_id_t index_id, index_id_t index_id,
mtr_t* mtr) mtr_t* mtr)
{ {
ut_ad(page_id.space() != SRV_TMP_SPACE_ID); ut_ad(space->purpose == FIL_TYPE_TABLESPACE);
ut_ad(index_id != BTR_FREED_INDEX_ID); ut_ad(index_id != BTR_FREED_INDEX_ID);
buf_block_t* block = buf_page_get( if (buf_block_t* block = buf_page_get(
page_id, page_size, RW_X_LATCH, mtr); page_id_t(space->id, page), page_size_t(space->flags),
RW_X_LATCH, mtr)) {
if (block) {
buf_block_dbg_add_level(block, SYNC_TREE_NODE); buf_block_dbg_add_level(block, SYNC_TREE_NODE);
if (fil_page_index_page_check(block->frame) if (!fil_page_index_page_check(block->frame)
&& index_id == btr_page_get_index_id(block->frame)) { || index_id != btr_page_get_index_id(block->frame)) {
/* This should be a root page. return NULL;
It should not be possible to reassign the same
index_id for some other index in the tablespace. */
ut_ad(page_is_root(block->frame));
} else {
block = NULL;
} }
/* This should be a root page.
It should not be possible to reassign the same
index_id for some other index in the tablespace. */
ut_ad(page_is_root(block->frame));
return block;
} }
return(block); return NULL;
} }
/** Create the root node for a new index tree. /** Create the root node for a new index tree.
...@@ -1348,29 +1348,26 @@ btr_create( ...@@ -1348,29 +1348,26 @@ btr_create(
/** Free a B-tree except the root page. The root page MUST be freed after /** Free a B-tree except the root page. The root page MUST be freed after
this by calling btr_free_root. this by calling btr_free_root.
@param[in,out] space tablespace, or NULL
@param[in,out] block root page @param[in,out] block root page
@param[in] log_mode mtr logging mode */ @param[in] log_mode mtr logging mode */
static static
void void
btr_free_but_not_root( btr_free_but_not_root(
fil_space_t* space,
buf_block_t* block, buf_block_t* block,
mtr_log_t log_mode) mtr_log_t log_mode)
{ {
ibool finished; ibool finished;
mtr_t mtr; mtr_t mtr;
ut_ad(page_is_root(block->frame));
leaf_loop:
mtr_start(&mtr);
mtr_set_log_mode(&mtr, log_mode);
mtr.set_named_space_id(block->page.id.space());
page_t* root = block->frame; page_t* root = block->frame;
if (!root) { ut_ad(page_is_root(root));
mtr_commit(&mtr); ut_ad(!space || block->page.id.space() == space->id);
return; leaf_loop:
} mtr.start();
mtr.set_log_mode(log_mode);
if (space) mtr.set_named_space(space);
#ifdef UNIV_BTR_DEBUG #ifdef UNIV_BTR_DEBUG
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
...@@ -1384,18 +1381,15 @@ btr_free_but_not_root( ...@@ -1384,18 +1381,15 @@ btr_free_but_not_root(
finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF, finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF,
true, &mtr); true, &mtr);
mtr_commit(&mtr); mtr.commit();
if (!finished) { if (!finished) {
goto leaf_loop; goto leaf_loop;
} }
top_loop: top_loop:
mtr_start(&mtr); mtr.start();
mtr_set_log_mode(&mtr, log_mode); mtr.set_log_mode(log_mode);
mtr.set_named_space_id(block->page.id.space()); if (space) mtr.set_named_space(space);
root = block->frame;
#ifdef UNIV_BTR_DEBUG #ifdef UNIV_BTR_DEBUG
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
...@@ -1404,7 +1398,7 @@ btr_free_but_not_root( ...@@ -1404,7 +1398,7 @@ btr_free_but_not_root(
finished = fseg_free_step_not_header( finished = fseg_free_step_not_header(
root + PAGE_HEADER + PAGE_BTR_SEG_TOP, true, &mtr); root + PAGE_HEADER + PAGE_BTR_SEG_TOP, true, &mtr);
mtr_commit(&mtr); mtr.commit();
if (!finished) { if (!finished) {
goto top_loop; goto top_loop;
...@@ -1412,29 +1406,25 @@ btr_free_but_not_root( ...@@ -1412,29 +1406,25 @@ btr_free_but_not_root(
} }
/** Free a persistent index tree if it exists. /** Free a persistent index tree if it exists.
@param[in] page_id root page id @param[in,out] space tablespace
@param[in] page_size page size @param[in] page root page number
@param[in] index_id PAGE_INDEX_ID contents @param[in] index_id PAGE_INDEX_ID contents
@param[in,out] mtr mini-transaction */ @param[in,out] mtr mini-transaction */
void void
btr_free_if_exists( btr_free_if_exists(
const page_id_t& page_id, fil_space_t* space,
const page_size_t& page_size, ulint page,
index_id_t index_id, index_id_t index_id,
mtr_t* mtr) mtr_t* mtr)
{ {
buf_block_t* root = btr_free_root_check( if (buf_block_t* root = btr_free_root_check(space, page, index_id,
page_id, page_size, index_id, mtr); mtr)) {
ut_ad(page_is_root(root->frame));
if (root == NULL) { btr_free_but_not_root(space, root, mtr->get_log_mode());
return; mtr->set_named_space(space);
btr_free_root(root, mtr);
btr_free_root_invalidate(root, mtr);
} }
ut_ad(page_is_root(root->frame));
btr_free_but_not_root(root, mtr->get_log_mode());
mtr->set_named_space_id(page_id.space());
btr_free_root(root, mtr);
btr_free_root_invalidate(root, mtr);
} }
/** Free an index tree in a temporary tablespace or during TRUNCATE TABLE. /** Free an index tree in a temporary tablespace or during TRUNCATE TABLE.
...@@ -1449,13 +1439,10 @@ btr_free( ...@@ -1449,13 +1439,10 @@ btr_free(
mtr.start(); mtr.start();
mtr.set_log_mode(MTR_LOG_NO_REDO); mtr.set_log_mode(MTR_LOG_NO_REDO);
buf_block_t* block = buf_page_get( if (buf_block_t* block = buf_page_get(page_id, page_size, RW_X_LATCH,
page_id, page_size, RW_X_LATCH, &mtr); &mtr)) {
if (block) {
ut_ad(page_is_root(block->frame)); ut_ad(page_is_root(block->frame));
btr_free_but_not_root(NULL, block, MTR_LOG_NO_REDO);
btr_free_but_not_root(block, MTR_LOG_NO_REDO);
btr_free_root(block, &mtr); btr_free_root(block, &mtr);
} }
mtr.commit(); mtr.commit();
......
...@@ -911,7 +911,6 @@ dict_drop_index_tree( ...@@ -911,7 +911,6 @@ dict_drop_index_tree(
{ {
const byte* ptr; const byte* ptr;
ulint len; ulint len;
ulint space;
ulint root_page_no; ulint root_page_no;
ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(mutex_own(&dict_sys->mutex));
...@@ -938,35 +937,36 @@ dict_drop_index_tree( ...@@ -938,35 +937,36 @@ dict_drop_index_tree(
ut_ad(len == 4); ut_ad(len == 4);
space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); ulint space_id = mach_read_from_4(ptr);
ptr = rec_get_nth_field_old( ptr = rec_get_nth_field_old(
rec, DICT_FLD__SYS_INDEXES__ID, &len); rec, DICT_FLD__SYS_INDEXES__ID, &len);
ut_ad(len == 8); ut_ad(len == 8);
bool found;
const page_size_t page_size(fil_space_get_page_size(space,
&found));
if (!found) {
/* It is a single table tablespace and the .ibd file is
missing: do nothing */
return(false);
}
/* If tablespace is scheduled for truncate, do not try to drop /* If tablespace is scheduled for truncate, do not try to drop
the indexes in that tablespace. There is a truncate fixup action the indexes in that tablespace. There is a truncate fixup action
which will take care of it. */ which will take care of it. */
if (srv_is_tablespace_truncated(space)) { if (srv_is_tablespace_truncated(space_id)) {
return(false); return false;
} }
btr_free_if_exists(page_id_t(space, root_page_no), page_size, /* We cannot use fil_space_acquire_silent() here,
mach_read_from_8(ptr), mtr); because it would return NULL due to the pending
DROP or TRUNCATE operation. */
mutex_enter(&fil_system.mutex);
if (fil_space_t* space = fil_space_get_by_id(space_id)) {
space->n_pending_ops++;
mutex_exit(&fil_system.mutex);
btr_free_if_exists(space, root_page_no,
mach_read_from_8(ptr), mtr);
fil_space_release(space);
return true;
}
return(true); mutex_exit(&fil_system.mutex);
return false;
} }
/*******************************************************************//** /*******************************************************************//**
......
...@@ -373,16 +373,16 @@ btr_create( ...@@ -373,16 +373,16 @@ btr_create(
mtr_t* mtr); mtr_t* mtr);
/** Free a persistent index tree if it exists. /** Free a persistent index tree if it exists.
@param[in] page_id root page id @param[in,out] space tablespace
@param[in] page_size page size @param[in] page root page number
@param[in] index_id PAGE_INDEX_ID contents @param[in] index_id PAGE_INDEX_ID contents
@param[in,out] mtr mini-transaction */ @param[in,out] mtr mini-transaction */
void void
btr_free_if_exists( btr_free_if_exists(
const page_id_t& page_id, fil_space_t* space,
const page_size_t& page_size, ulint page,
index_id_t index_id, index_id_t index_id,
mtr_t* mtr); mtr_t* mtr);
/** Free an index tree in a temporary tablespace or during TRUNCATE TABLE. /** Free an index tree in a temporary tablespace or during TRUNCATE TABLE.
@param[in] page_id root page id @param[in] page_id root page id
......
...@@ -3021,10 +3021,8 @@ void truncate_t::drop_indexes(fil_space_t* space) const ...@@ -3021,10 +3021,8 @@ void truncate_t::drop_indexes(fil_space_t* space) const
} }
if (root_page_no != FIL_NULL) { if (root_page_no != FIL_NULL) {
const page_id_t root_page_id(space->id, root_page_no); btr_free_if_exists(space, root_page_no, it->m_id,
&mtr);
btr_free_if_exists(
root_page_id, page_size, it->m_id, &mtr);
} }
/* If tree is already freed then we might return immediately /* If tree is already freed then we might return immediately
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment