summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-12-18 16:53:45 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-12-18 16:53:45 +0200
commitcd093d79f990cfa7923d3f3ca9352c4f0ee1415d (patch)
tree70d6cb4b2325dcb52b327be7fd9885330fedb6f9
parenta1974d1991f808146c11ca0ada3724e8bafd5fb8 (diff)
downloadmariadb-git-cd093d79f990cfa7923d3f3ca9352c4f0ee1415d.tar.gz
MDEV-24442 Assertion space->referenced() failed in fil_crypt_space_needs_rotation
A race condition between deleting an .ibd file and fil_crypt_thread marking pages dirty was introduced in commit 118e258aaac5da75a2ac4556201aaea3688fac67 (part of MDEV-23855). fil_space_t::acquire_if_not_stopped(): Correctly return false if the STOPPING flag is set, indicating that any further activity on the tablespace must be avoided. Also, remove the constant parameter have_mutex=true and move the function declaration to the same compilation unit with the only callers. fil_crypt_flush_space(): Remove an unused variable.
-rw-r--r--storage/innobase/fil/fil0crypt.cc21
-rw-r--r--storage/innobase/include/fil0fil.h14
2 files changed, 19 insertions, 16 deletions
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index f5b278e3496..acc196a910d 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -1430,6 +1430,19 @@ static void fil_crypt_return_iops(rotate_thread_t *state, bool wake= true)
fil_crypt_update_total_stat(state);
}
+/** Acquire a tablespace reference.
+@return whether a tablespace reference was successfully acquired */
+inline bool fil_space_t::acquire_if_not_stopped()
+{
+ ut_ad(mutex_own(&fil_system.mutex));
+ const uint32_t n= acquire_low();
+ if (UNIV_LIKELY(!(n & (STOPPING | CLOSING))))
+ return true;
+ if (UNIV_UNLIKELY(n & STOPPING))
+ return false;
+ return UNIV_LIKELY(!(n & CLOSING)) || prepare(true);
+}
+
/** Return the next tablespace from rotation_list.
@param space previous tablespace (NULL to start from the start)
@param recheck whether the removal condition needs to be rechecked after
@@ -1478,7 +1491,7 @@ inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
do
{
space= &*it;
- if (space->acquire_if_not_stopped(true))
+ if (space->acquire_if_not_stopped())
return space;
if (++it == end)
return nullptr;
@@ -2007,12 +2020,10 @@ fil_crypt_flush_space(
mtr_t mtr;
mtr.start();
- dberr_t err;
-
if (buf_block_t* block = buf_page_get_gen(
page_id_t(space->id, 0), space->zip_size(),
RW_X_LATCH, NULL, BUF_GET_POSSIBLY_FREED,
- __FILE__, __LINE__, &mtr, &err)) {
+ __FILE__, __LINE__, &mtr)) {
mtr.set_named_space(space);
crypt_data->write_page0(block, &mtr);
}
@@ -2250,7 +2261,7 @@ static void fil_crypt_rotation_list_fill()
if (space->purpose != FIL_TYPE_TABLESPACE
|| space->is_in_rotation_list
|| UT_LIST_GET_LEN(space->chain) == 0
- || !space->acquire_if_not_stopped(true)) {
+ || !space->acquire_if_not_stopped()) {
continue;
}
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 79dd6933056..f011eb6af69 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -520,8 +520,9 @@ private:
}
public:
MY_ATTRIBUTE((warn_unused_result))
- /** @return whether a tablespace reference was successfully acquired */
- inline bool acquire_if_not_stopped(bool have_mutex= false);
+ /** Acquire a tablespace reference.
+ @return whether a tablespace reference was successfully acquired */
+ inline bool acquire_if_not_stopped();
MY_ATTRIBUTE((warn_unused_result))
/** Acquire a tablespace reference for I/O.
@@ -1434,15 +1435,6 @@ inline void fil_space_t::reacquire()
ut_ad(UT_LIST_GET_FIRST(chain)->is_open());
}
-inline bool fil_space_t::acquire_if_not_stopped(bool have_mutex)
-{
- ut_ad(mutex_own(&fil_system.mutex) == have_mutex);
- const uint32_t n= acquire_low();
- if (UNIV_LIKELY(!(n & (STOPPING | CLOSING))))
- return true;
- return UNIV_LIKELY(!(n & CLOSING)) || prepare(have_mutex);
-}
-
/** Note that operations on the tablespace must stop or can resume */
inline void fil_space_t::set_stopping(bool stopping)
{