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(
}
/** Prepare to free a B-tree.
@param[in] page_id page id
@param[in] page_size page size
@param[in,out] space tablespace
@param[in] page root page number
@param[in] index_id PAGE_INDEX_ID contents
@param[in,out] mtr mini-transaction
@return root block, to invoke btr_free_but_not_root() and btr_free_root()
......@@ -1149,32 +1149,32 @@ 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_size_t& page_size,
index_id_t index_id,
mtr_t* mtr)
fil_space_t* space,
ulint page,
index_id_t index_id,
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);
buf_block_t* block = buf_page_get(
page_id, page_size, RW_X_LATCH, mtr);
if (block) {
if (buf_block_t* block = buf_page_get(
page_id_t(space->id, page), page_size_t(space->flags),
RW_X_LATCH, mtr)) {
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
if (fil_page_index_page_check(block->frame)
&& index_id == btr_page_get_index_id(block->frame)) {
/* 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));
} else {
block = NULL;
if (!fil_page_index_page_check(block->frame)
|| index_id != btr_page_get_index_id(block->frame)) {
return 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.
......@@ -1348,29 +1348,26 @@ btr_create(
/** Free a B-tree except the root page. The root page MUST be freed after
this by calling btr_free_root.
@param[in,out] space tablespace, or NULL
@param[in,out] block root page
@param[in] log_mode mtr logging mode */
static
void
btr_free_but_not_root(
fil_space_t* space,
buf_block_t* block,
mtr_log_t log_mode)
{
ibool finished;
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;
if (!root) {
mtr_commit(&mtr);
return;
}
ut_ad(page_is_root(root));
ut_ad(!space || block->page.id.space() == space->id);
leaf_loop:
mtr.start();
mtr.set_log_mode(log_mode);
if (space) mtr.set_named_space(space);
#ifdef UNIV_BTR_DEBUG
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
......@@ -1384,18 +1381,15 @@ btr_free_but_not_root(
finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF,
true, &mtr);
mtr_commit(&mtr);
mtr.commit();
if (!finished) {
goto leaf_loop;
}
top_loop:
mtr_start(&mtr);
mtr_set_log_mode(&mtr, log_mode);
mtr.set_named_space_id(block->page.id.space());
root = block->frame;
mtr.start();
mtr.set_log_mode(log_mode);
if (space) mtr.set_named_space(space);
#ifdef UNIV_BTR_DEBUG
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
......@@ -1404,7 +1398,7 @@ btr_free_but_not_root(
finished = fseg_free_step_not_header(
root + PAGE_HEADER + PAGE_BTR_SEG_TOP, true, &mtr);
mtr_commit(&mtr);
mtr.commit();
if (!finished) {
goto top_loop;
......@@ -1412,29 +1406,25 @@ btr_free_but_not_root(
}
/** Free a persistent index tree if it exists.
@param[in] page_id root page id
@param[in] page_size page size
@param[in,out] space tablespace
@param[in] page root page number
@param[in] index_id PAGE_INDEX_ID contents
@param[in,out] mtr mini-transaction */
void
btr_free_if_exists(
const page_id_t& page_id,
const page_size_t& page_size,
index_id_t index_id,
mtr_t* mtr)
fil_space_t* space,
ulint page,
index_id_t index_id,
mtr_t* mtr)
{
buf_block_t* root = btr_free_root_check(
page_id, page_size, index_id, mtr);
if (root == NULL) {
return;
if (buf_block_t* root = btr_free_root_check(space, page, index_id,
mtr)) {
ut_ad(page_is_root(root->frame));
btr_free_but_not_root(space, root, mtr->get_log_mode());
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.
......@@ -1449,13 +1439,10 @@ btr_free(
mtr.start();
mtr.set_log_mode(MTR_LOG_NO_REDO);
buf_block_t* block = buf_page_get(
page_id, page_size, RW_X_LATCH, &mtr);
if (block) {
if (buf_block_t* block = buf_page_get(page_id, page_size, RW_X_LATCH,
&mtr)) {
ut_ad(page_is_root(block->frame));
btr_free_but_not_root(block, MTR_LOG_NO_REDO);
btr_free_but_not_root(NULL, block, MTR_LOG_NO_REDO);
btr_free_root(block, &mtr);
}
mtr.commit();
......
......@@ -911,7 +911,6 @@ dict_drop_index_tree(
{
const byte* ptr;
ulint len;
ulint space;
ulint root_page_no;
ut_ad(mutex_own(&dict_sys->mutex));
......@@ -938,35 +937,36 @@ dict_drop_index_tree(
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(
rec, DICT_FLD__SYS_INDEXES__ID, &len);
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
the indexes in that tablespace. There is a truncate fixup action
which will take care of it. */
if (srv_is_tablespace_truncated(space)) {
return(false);
if (srv_is_tablespace_truncated(space_id)) {
return false;
}
btr_free_if_exists(page_id_t(space, root_page_no), page_size,
mach_read_from_8(ptr), mtr);
/* We cannot use fil_space_acquire_silent() here,
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(
mtr_t* mtr);
/** Free a persistent index tree if it exists.
@param[in] page_id root page id
@param[in] page_size page size
@param[in,out] space tablespace
@param[in] page root page number
@param[in] index_id PAGE_INDEX_ID contents
@param[in,out] mtr mini-transaction */
void
btr_free_if_exists(
const page_id_t& page_id,
const page_size_t& page_size,
index_id_t index_id,
mtr_t* mtr);
fil_space_t* space,
ulint page,
index_id_t index_id,
mtr_t* mtr);
/** Free an index tree in a temporary tablespace or during TRUNCATE TABLE.
@param[in] page_id root page id
......
......@@ -3021,10 +3021,8 @@ void truncate_t::drop_indexes(fil_space_t* space) const
}
if (root_page_no != FIL_NULL) {
const page_id_t root_page_id(space->id, root_page_no);
btr_free_if_exists(
root_page_id, page_size, it->m_id, &mtr);
btr_free_if_exists(space, root_page_no, it->m_id,
&mtr);
}
/* 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