Skip to content

Commit 7301fba

Browse files
committed
MDEV-37755 fil_space_t::drop() doesn't remove space from fil_system.named_spaces
mtr.commit_file() call in fil_space_t::drop() removes space from fil_system.named_spaces, but then the space can be inserted in the container again by some another thread while fil_space_t::drop() is waiting for pending operations finishing. The fix is to check and remove a space from fil_system.named_spaces after all pengind operations on the space are finished. Also the ut_d() macro is removed for space->max_lsn=0 assignments to avoid repeated space removing from fil_system.named_spaces. There is error in ilist::pop_back(). ilist::end() returns sentinel, and the pop_back() removes sentinel from the list instead of the last element. The error is fixed in this commit. Reviewed by Marko Mäkelä
1 parent 759e352 commit 7301fba

File tree

3 files changed

+21
-16
lines changed

3 files changed

+21
-16
lines changed

include/ilist.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ template <class T, class Tag= void> class ilist
185185
ListNode *prev= pos.node_->prev;
186186
ListNode *next= pos.node_->next;
187187

188+
DBUG_ASSERT(prev->next == pos.node_);
189+
DBUG_ASSERT(next->prev == pos.node_);
190+
188191
prev->next= next;
189192
next->prev= prev;
190193

@@ -198,7 +201,7 @@ template <class T, class Tag= void> class ilist
198201
}
199202

200203
void push_back(reference value) noexcept { insert(end(), value); }
201-
void pop_back() noexcept { erase(end()); }
204+
void pop_back() noexcept { erase(--end()); }
202205

203206
void push_front(reference value) noexcept { insert(begin(), value); }
204207
void pop_front() noexcept { erase(begin()); }

storage/innobase/fil/fil0fil.cc

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -861,13 +861,7 @@ static void fil_space_free_low(fil_space_t *space) noexcept
861861
/* The tablespace must not be in fil_system.named_spaces. */
862862
ut_ad(srv_fast_shutdown == 2 || !srv_was_started
863863
|| space->max_lsn == 0);
864-
865-
/* Wait for fil_space_t::release() after
866-
fil_system_t::detach(), the tablespace cannot be found, so
867-
fil_space_t::get() would return NULL */
868-
while (space->referenced()) {
869-
std::this_thread::sleep_for(std::chrono::microseconds(100));
870-
}
864+
ut_ad(!space->referenced());
871865

872866
for (fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
873867
node != NULL; ) {
@@ -911,7 +905,7 @@ bool fil_space_free(ulint id, bool x_latched) noexcept
911905
mysql_mutex_assert_owner(&log_sys.mutex);
912906

913907
if (space->max_lsn != 0) {
914-
ut_d(space->max_lsn = 0);
908+
space->max_lsn = 0;
915909
fil_system.named_spaces.remove(*space);
916910
}
917911

@@ -1604,10 +1598,24 @@ fil_space_t *fil_space_t::drop(ulint id, pfs_os_file_t *detached_handle)
16041598

16051599
pfs_os_file_t handle= fil_system.detach(space, true);
16061600
mysql_mutex_unlock(&fil_system.mutex);
1601+
/* The above mtr.commit_file(*space, nullptr) should remove the space from
1602+
fil_system.named_spaces. Before we set the STOPPING_WRITES flag, another
1603+
concurrent operation could have marked the tablespace dirty again.
1604+
This clean-up corresponds to fil_space_free(). */
1605+
mysql_mutex_lock(&log_sys.mutex);
1606+
ut_ad((space->pending() & ~NEEDS_FSYNC) == (STOPPING | CLOSING));
1607+
if (space->max_lsn != 0)
1608+
{
1609+
space->max_lsn= 0;
1610+
fil_system.named_spaces.remove(*space);
1611+
}
1612+
mysql_mutex_unlock(&log_sys.mutex);
1613+
16071614
if (detached_handle)
16081615
*detached_handle = handle;
16091616
else
16101617
os_file_close(handle);
1618+
16111619
return space;
16121620
}
16131621

@@ -1630,12 +1638,6 @@ void fil_close_tablespace(ulint id) noexcept
16301638
while (buf_flush_list_space(space));
16311639

16321640
space->x_unlock();
1633-
mysql_mutex_lock(&log_sys.mutex);
1634-
if (space->max_lsn != 0) {
1635-
ut_d(space->max_lsn = 0);
1636-
fil_system.named_spaces.remove(*space);
1637-
}
1638-
mysql_mutex_unlock(&log_sys.mutex);
16391641
fil_space_free_low(space);
16401642
}
16411643

storage/innobase/mtr/mtr0mtr.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ bool mtr_t::commit_file(fil_space_t &space, const char *name)
375375

376376
if (!name && space.max_lsn)
377377
{
378-
ut_d(space.max_lsn= 0);
378+
space.max_lsn= 0;
379379
fil_system.named_spaces.remove(space);
380380
}
381381

0 commit comments

Comments
 (0)