Skip to content

Commit 1636db5

Browse files
committed
Revert "MDEV-24589 DROP TABLE is not crash-safe"
This reverts commit e731a28. 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.
1 parent 21973d0 commit 1636db5

File tree

4 files changed

+34
-20
lines changed

4 files changed

+34
-20
lines changed

storage/innobase/dict/dict0crea.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,7 @@ void dict_drop_index_tree(btr_pcur_t* pcur, trx_t* trx, mtr_t* mtr)
910910
byte* ptr;
911911
ulint len;
912912

913-
ut_ad(!trx || mutex_own(&dict_sys.mutex));
913+
ut_ad(mutex_own(&dict_sys.mutex));
914914
ut_a(!dict_table_is_comp(dict_sys.sys_indexes));
915915

916916
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)
936936

937937
const uint32_t space_id = mach_read_from_4(ptr);
938938
ut_ad(space_id < SRV_TMP_SPACE_ID);
939-
if (space_id != TRX_SYS_SPACE && trx
939+
if (space_id != TRX_SYS_SPACE
940940
&& trx_get_dict_operation(trx) == TRX_DICT_OP_TABLE) {
941941
/* We are about to delete the entire .ibd file;
942942
do not bother to free pages inside it. */

storage/innobase/include/dict0crea.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ dict_create_index_tree(
101101
@param[in,out] trx dictionary transaction
102102
@param[in,out] mtr mini-transaction */
103103
void dict_drop_index_tree(btr_pcur_t* pcur, trx_t* trx, mtr_t* mtr)
104-
MY_ATTRIBUTE((nonnull(1,3)));
104+
MY_ATTRIBUTE((nonnull));
105105

106106
/***************************************************************//**
107107
Creates an index tree for the index if it is not a member of a cluster.

storage/innobase/row/row0purge.cc

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ Created 3/14/1997 Heikki Tuuri
2727
#include "row0purge.h"
2828
#include "fsp0fsp.h"
2929
#include "mach0data.h"
30-
#include "dict0crea.h"
3130
#include "dict0stats.h"
3231
#include "trx0rseg.h"
3332
#include "trx0trx.h"
@@ -117,21 +116,6 @@ row_purge_remove_clust_if_poss_low(
117116
return true;
118117
}
119118

120-
if (node->table->id == DICT_INDEXES_ID) {
121-
/* If this is a record of the SYS_INDEXES table, then
122-
we have to free the file segments of the index tree
123-
associated with the index */
124-
dict_drop_index_tree(&node->pcur, nullptr, &mtr);
125-
mtr.commit();
126-
mtr.start();
127-
index->set_modified(mtr);
128-
129-
if (!row_purge_reposition_pcur(mode, node, &mtr)) {
130-
mtr.commit();
131-
return true;
132-
}
133-
}
134-
135119
rec_t* rec = btr_pcur_get_rec(&node->pcur);
136120
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
137121
rec_offs_init(offsets_);

storage/innobase/row/row0upd.cc

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2756,6 +2756,7 @@ row_upd_clust_step(
27562756
{
27572757
dict_index_t* index;
27582758
btr_pcur_t* pcur;
2759+
ibool success;
27592760
dberr_t err;
27602761
mtr_t mtr;
27612762
rec_t* rec;
@@ -2815,11 +2816,40 @@ row_upd_clust_step(
28152816
mode = BTR_MODIFY_LEAF;
28162817
}
28172818

2818-
if (!btr_pcur_restore_position(mode, pcur, &mtr)) {
2819+
success = btr_pcur_restore_position(mode, pcur, &mtr);
2820+
2821+
if (!success) {
28192822
err = DB_RECORD_NOT_FOUND;
28202823
goto exit_func;
28212824
}
28222825

2826+
/* If this is a row in SYS_INDEXES table of the data dictionary,
2827+
then we have to free the file segments of the index tree associated
2828+
with the index */
2829+
2830+
if (node->is_delete == PLAIN_DELETE
2831+
&& node->table->id == DICT_INDEXES_ID) {
2832+
2833+
ut_ad(!dict_index_is_online_ddl(index));
2834+
2835+
dict_drop_index_tree(pcur, trx, &mtr);
2836+
2837+
mtr.commit();
2838+
2839+
mtr.start();
2840+
index->set_modified(mtr);
2841+
2842+
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur,
2843+
&mtr);
2844+
if (!success) {
2845+
err = DB_ERROR;
2846+
2847+
mtr.commit();
2848+
2849+
return(err);
2850+
}
2851+
}
2852+
28232853
rec = btr_pcur_get_rec(pcur);
28242854
offsets = rec_get_offsets(rec, index, offsets_, index->n_core_fields,
28252855
ULINT_UNDEFINED, &heap);

0 commit comments

Comments
 (0)