Commit 1636db54 authored by Marko Mäkelä's avatar Marko Mäkelä

Revert "MDEV-24589 DROP TABLE is not crash-safe"

This reverts commit e731a283.

A crash occurred during the test stress.ddl_innodb when
fil_delete_tablespace() for DROP TABLE was waiting in
fil_check_pending_operations() and a purge thread for handling
an earlier DROP INDEX was attempting to load the index root page
in btr_free_if_exists() and btr_free_root_check(). The function
buf_page_get_gen() would write out several times
"trying to read...being-dropped tablespace"
before giving up and committing suicide.

It turns out that during any page access in btr_free_if_exists(),
fil_space_t::set_stopping() could have been invoked by
fil_check_pending_operations(), as part of dropping the tablespace.
Preventing this race condition would require extensive changes
to the allocation code or some locking mechanism that would ensure
that we only set the flag if btr_free_if_exists() is not in progress.

Either way, that could be a too risky change in a GA release.
Because MDEV-24589 is not strictly necessary in the 10.5 release
series and it only is a requirement for MDEV-25180 in a later
major release, we will revert the change from 10.5.
parent 21973d0d
...@@ -910,7 +910,7 @@ void dict_drop_index_tree(btr_pcur_t* pcur, trx_t* trx, mtr_t* mtr) ...@@ -910,7 +910,7 @@ void dict_drop_index_tree(btr_pcur_t* pcur, trx_t* trx, mtr_t* mtr)
byte* ptr; byte* ptr;
ulint len; ulint len;
ut_ad(!trx || mutex_own(&dict_sys.mutex)); ut_ad(mutex_own(&dict_sys.mutex));
ut_a(!dict_table_is_comp(dict_sys.sys_indexes)); ut_a(!dict_table_is_comp(dict_sys.sys_indexes));
ptr = rec_get_nth_field_old(rec, DICT_FLD__SYS_INDEXES__PAGE_NO, &len); ptr = rec_get_nth_field_old(rec, DICT_FLD__SYS_INDEXES__PAGE_NO, &len);
...@@ -936,7 +936,7 @@ void dict_drop_index_tree(btr_pcur_t* pcur, trx_t* trx, mtr_t* mtr) ...@@ -936,7 +936,7 @@ void dict_drop_index_tree(btr_pcur_t* pcur, trx_t* trx, mtr_t* mtr)
const uint32_t space_id = mach_read_from_4(ptr); const uint32_t space_id = mach_read_from_4(ptr);
ut_ad(space_id < SRV_TMP_SPACE_ID); ut_ad(space_id < SRV_TMP_SPACE_ID);
if (space_id != TRX_SYS_SPACE && trx if (space_id != TRX_SYS_SPACE
&& trx_get_dict_operation(trx) == TRX_DICT_OP_TABLE) { && trx_get_dict_operation(trx) == TRX_DICT_OP_TABLE) {
/* We are about to delete the entire .ibd file; /* We are about to delete the entire .ibd file;
do not bother to free pages inside it. */ do not bother to free pages inside it. */
......
...@@ -101,7 +101,7 @@ dict_create_index_tree( ...@@ -101,7 +101,7 @@ dict_create_index_tree(
@param[in,out] trx dictionary transaction @param[in,out] trx dictionary transaction
@param[in,out] mtr mini-transaction */ @param[in,out] mtr mini-transaction */
void dict_drop_index_tree(btr_pcur_t* pcur, trx_t* trx, mtr_t* mtr) void dict_drop_index_tree(btr_pcur_t* pcur, trx_t* trx, mtr_t* mtr)
MY_ATTRIBUTE((nonnull(1,3))); MY_ATTRIBUTE((nonnull));
/***************************************************************//** /***************************************************************//**
Creates an index tree for the index if it is not a member of a cluster. Creates an index tree for the index if it is not a member of a cluster.
......
...@@ -27,7 +27,6 @@ Created 3/14/1997 Heikki Tuuri ...@@ -27,7 +27,6 @@ Created 3/14/1997 Heikki Tuuri
#include "row0purge.h" #include "row0purge.h"
#include "fsp0fsp.h" #include "fsp0fsp.h"
#include "mach0data.h" #include "mach0data.h"
#include "dict0crea.h"
#include "dict0stats.h" #include "dict0stats.h"
#include "trx0rseg.h" #include "trx0rseg.h"
#include "trx0trx.h" #include "trx0trx.h"
...@@ -117,21 +116,6 @@ row_purge_remove_clust_if_poss_low( ...@@ -117,21 +116,6 @@ row_purge_remove_clust_if_poss_low(
return true; return true;
} }
if (node->table->id == DICT_INDEXES_ID) {
/* If this is a record of the SYS_INDEXES table, then
we have to free the file segments of the index tree
associated with the index */
dict_drop_index_tree(&node->pcur, nullptr, &mtr);
mtr.commit();
mtr.start();
index->set_modified(mtr);
if (!row_purge_reposition_pcur(mode, node, &mtr)) {
mtr.commit();
return true;
}
}
rec_t* rec = btr_pcur_get_rec(&node->pcur); rec_t* rec = btr_pcur_get_rec(&node->pcur);
rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_); rec_offs_init(offsets_);
......
...@@ -2756,6 +2756,7 @@ row_upd_clust_step( ...@@ -2756,6 +2756,7 @@ row_upd_clust_step(
{ {
dict_index_t* index; dict_index_t* index;
btr_pcur_t* pcur; btr_pcur_t* pcur;
ibool success;
dberr_t err; dberr_t err;
mtr_t mtr; mtr_t mtr;
rec_t* rec; rec_t* rec;
...@@ -2815,11 +2816,40 @@ row_upd_clust_step( ...@@ -2815,11 +2816,40 @@ row_upd_clust_step(
mode = BTR_MODIFY_LEAF; mode = BTR_MODIFY_LEAF;
} }
if (!btr_pcur_restore_position(mode, pcur, &mtr)) { success = btr_pcur_restore_position(mode, pcur, &mtr);
if (!success) {
err = DB_RECORD_NOT_FOUND; err = DB_RECORD_NOT_FOUND;
goto exit_func; goto exit_func;
} }
/* If this is a row in SYS_INDEXES table of the data dictionary,
then we have to free the file segments of the index tree associated
with the index */
if (node->is_delete == PLAIN_DELETE
&& node->table->id == DICT_INDEXES_ID) {
ut_ad(!dict_index_is_online_ddl(index));
dict_drop_index_tree(pcur, trx, &mtr);
mtr.commit();
mtr.start();
index->set_modified(mtr);
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur,
&mtr);
if (!success) {
err = DB_ERROR;
mtr.commit();
return(err);
}
}
rec = btr_pcur_get_rec(pcur); rec = btr_pcur_get_rec(pcur);
offsets = rec_get_offsets(rec, index, offsets_, index->n_core_fields, offsets = rec_get_offsets(rec, index, offsets_, index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
......
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