diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-12-18 16:53:45 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-12-18 16:53:45 +0200 |
commit | cd093d79f990cfa7923d3f3ca9352c4f0ee1415d (patch) | |
tree | 70d6cb4b2325dcb52b327be7fd9885330fedb6f9 | |
parent | a1974d1991f808146c11ca0ada3724e8bafd5fb8 (diff) | |
download | mariadb-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.cc | 21 | ||||
-rw-r--r-- | storage/innobase/include/fil0fil.h | 14 |
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) { |