Revert "MDEV-12266: Remove lookups when dropping indexes"
This reverts commit d2660362920a82588508028f263dad9c16f08865. The patch would cause a crash when DROP TABLE is executed and the .ibd file is missing. It is not easy to fix this; there is some delicate logic in fil_space_get_page_size().
This commit is contained in:
parent
e895041ba9
commit
04bac13b30
@ -1140,8 +1140,8 @@ btr_free_root_invalidate(
|
||||
}
|
||||
|
||||
/** Prepare to free a B-tree.
|
||||
@param[in,out] space tablespace
|
||||
@param[in] page root page number
|
||||
@param[in] page_id page id
|
||||
@param[in] page_size page size
|
||||
@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(
|
||||
fil_space_t* space,
|
||||
ulint page,
|
||||
index_id_t index_id,
|
||||
mtr_t* mtr)
|
||||
const page_id_t& page_id,
|
||||
const page_size_t& page_size,
|
||||
index_id_t index_id,
|
||||
mtr_t* mtr)
|
||||
{
|
||||
ut_ad(space->purpose == FIL_TYPE_TABLESPACE);
|
||||
ut_ad(page_id.space() != SRV_TMP_SPACE_ID);
|
||||
ut_ad(index_id != BTR_FREED_INDEX_ID);
|
||||
|
||||
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_t* block = buf_page_get(
|
||||
page_id, page_size, RW_X_LATCH, mtr);
|
||||
|
||||
if (block) {
|
||||
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)) {
|
||||
return NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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 NULL;
|
||||
return(block);
|
||||
}
|
||||
|
||||
/** Create the root node for a new index tree.
|
||||
@ -1348,26 +1348,29 @@ 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;
|
||||
|
||||
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);
|
||||
if (!root) {
|
||||
mtr_commit(&mtr);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
|
||||
@ -1381,15 +1384,18 @@ leaf_loop:
|
||||
|
||||
finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF,
|
||||
true, &mtr);
|
||||
mtr.commit();
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (!finished) {
|
||||
|
||||
goto leaf_loop;
|
||||
}
|
||||
top_loop:
|
||||
mtr.start();
|
||||
mtr.set_log_mode(log_mode);
|
||||
if (space) mtr.set_named_space(space);
|
||||
mtr_start(&mtr);
|
||||
mtr_set_log_mode(&mtr, log_mode);
|
||||
mtr.set_named_space_id(block->page.id.space());
|
||||
|
||||
root = block->frame;
|
||||
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
@ -1398,7 +1404,7 @@ top_loop:
|
||||
|
||||
finished = fseg_free_step_not_header(
|
||||
root + PAGE_HEADER + PAGE_BTR_SEG_TOP, true, &mtr);
|
||||
mtr.commit();
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (!finished) {
|
||||
goto top_loop;
|
||||
@ -1406,25 +1412,29 @@ top_loop:
|
||||
}
|
||||
|
||||
/** Free a persistent index tree if it exists.
|
||||
@param[in,out] space tablespace
|
||||
@param[in] page root page number
|
||||
@param[in] page_id root page id
|
||||
@param[in] page_size page size
|
||||
@param[in] index_id PAGE_INDEX_ID contents
|
||||
@param[in,out] mtr mini-transaction */
|
||||
void
|
||||
btr_free_if_exists(
|
||||
fil_space_t* space,
|
||||
ulint page,
|
||||
index_id_t index_id,
|
||||
mtr_t* mtr)
|
||||
const page_id_t& page_id,
|
||||
const page_size_t& page_size,
|
||||
index_id_t index_id,
|
||||
mtr_t* mtr)
|
||||
{
|
||||
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);
|
||||
buf_block_t* root = btr_free_root_check(
|
||||
page_id, page_size, index_id, mtr);
|
||||
|
||||
if (root == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
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.
|
||||
@ -1439,10 +1449,13 @@ btr_free(
|
||||
mtr.start();
|
||||
mtr.set_log_mode(MTR_LOG_NO_REDO);
|
||||
|
||||
if (buf_block_t* block = buf_page_get(page_id, page_size, RW_X_LATCH,
|
||||
&mtr)) {
|
||||
buf_block_t* block = buf_page_get(
|
||||
page_id, page_size, RW_X_LATCH, &mtr);
|
||||
|
||||
if (block) {
|
||||
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);
|
||||
}
|
||||
mtr.commit();
|
||||
|
@ -911,6 +911,7 @@ dict_drop_index_tree(
|
||||
{
|
||||
const byte* ptr;
|
||||
ulint len;
|
||||
ulint space;
|
||||
ulint root_page_no;
|
||||
|
||||
ut_ad(mutex_own(&dict_sys->mutex));
|
||||
@ -937,36 +938,35 @@ dict_drop_index_tree(
|
||||
|
||||
ut_ad(len == 4);
|
||||
|
||||
ulint space_id = mach_read_from_4(ptr);
|
||||
space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
|
||||
|
||||
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_id)) {
|
||||
return false;
|
||||
if (srv_is_tablespace_truncated(space)) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
btr_free_if_exists(page_id_t(space, root_page_no), page_size,
|
||||
mach_read_from_8(ptr), mtr);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system.mutex);
|
||||
return false;
|
||||
return(true);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
|
@ -373,16 +373,16 @@ btr_create(
|
||||
mtr_t* mtr);
|
||||
|
||||
/** Free a persistent index tree if it exists.
|
||||
@param[in,out] space tablespace
|
||||
@param[in] page root page number
|
||||
@param[in] page_id root page id
|
||||
@param[in] page_size page size
|
||||
@param[in] index_id PAGE_INDEX_ID contents
|
||||
@param[in,out] mtr mini-transaction */
|
||||
void
|
||||
btr_free_if_exists(
|
||||
fil_space_t* space,
|
||||
ulint page,
|
||||
index_id_t index_id,
|
||||
mtr_t* mtr);
|
||||
const page_id_t& page_id,
|
||||
const page_size_t& page_size,
|
||||
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,8 +3021,10 @@ void truncate_t::drop_indexes(fil_space_t* space) const
|
||||
}
|
||||
|
||||
if (root_page_no != FIL_NULL) {
|
||||
btr_free_if_exists(space, root_page_no, it->m_id,
|
||||
&mtr);
|
||||
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);
|
||||
}
|
||||
|
||||
/* If tree is already freed then we might return immediately
|
||||
|
Loading…
x
Reference in New Issue
Block a user