diff options
Diffstat (limited to 'storage/innobase/fil')
-rw-r--r-- | storage/innobase/fil/fil0crypt.cc | 122 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 114 |
2 files changed, 100 insertions, 136 deletions
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 7c342ca0637..7c4046871cc 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -41,9 +41,6 @@ Modified Jan Lindström jan.lindstrom@mariadb.com #include "fil0pagecompress.h" #include <my_crypt.h> -/** Mutex for keys */ -static ib_mutex_t fil_crypt_key_mutex; - static bool fil_crypt_threads_inited = false; /** Is encryption enabled/disabled */ @@ -113,8 +110,6 @@ UNIV_INTERN void fil_space_crypt_init() { - mutex_create(LATCH_ID_FIL_CRYPT_MUTEX, &fil_crypt_key_mutex); - fil_crypt_throttle_sleep_event = os_event_create(0); mutex_create(LATCH_ID_FIL_CRYPT_STAT_MUTEX, &crypt_stat_mutex); @@ -128,7 +123,6 @@ void fil_space_crypt_cleanup() { os_event_destroy(fil_crypt_throttle_sleep_event); - mutex_free(&fil_crypt_key_mutex); mutex_free(&crypt_stat_mutex); } @@ -1582,6 +1576,94 @@ fil_crypt_return_iops( fil_crypt_update_total_stat(state); } +/** 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 +the encryption parameters were changed +@param encrypt expected state of innodb_encrypt_tables +@return the next tablespace to process (n_pending_ops incremented) +@retval NULL if this was the last */ +inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space, + bool recheck, bool encrypt) +{ + ut_ad(mutex_own(&mutex)); + + sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it= + space ? space : rotation_list.begin(); + const sized_ilist<fil_space_t, rotation_list_tag_t>::iterator end= + rotation_list.end(); + + if (space) + { + while (++it != end && (!UT_LIST_GET_LEN(it->chain) || it->is_stopping())); + + /* If one of the encryption threads already started the encryption + of the table then don't remove the unencrypted spaces from rotation list + + If there is a change in innodb_encrypt_tables variables value then + don't remove the last processed tablespace from the rotation list. */ + space->release(); + + if (!space->referenced() && + (!recheck || space->crypt_data) && !encrypt == !srv_encrypt_tables && + space->is_in_rotation_list) + { + ut_a(!rotation_list.empty()); + rotation_list.remove(*space); + space->is_in_rotation_list= false; + } + } + + if (it == end) + return NULL; + + space= &*it; + space->acquire(); + return space; +} + +/** Return the next tablespace. +@param space previous tablespace (NULL to start from the beginning) +@param recheck whether the removal condition needs to be rechecked after +the encryption parameters were changed +@param encrypt expected state of innodb_encrypt_tables +@return pointer to the next tablespace (with n_pending_ops incremented) +@retval NULL if this was the last */ +static fil_space_t *fil_space_next(fil_space_t *space, bool recheck, + bool encrypt) +{ + mutex_enter(&fil_system.mutex); + + if (!srv_fil_crypt_rotate_key_age) + space= fil_system.keyrotate_next(space, recheck, encrypt); + else if (!space) + { + space= UT_LIST_GET_FIRST(fil_system.space_list); + /* We can trust that space is not NULL because at least the + system tablespace is always present and loaded first. */ + space->acquire(); + } + else + { + /* Move on to the next fil_space_t */ + space->release(); + space= UT_LIST_GET_NEXT(space_list, space); + + /* Skip abnormal tablespaces or those that are being created by + fil_ibd_create(), or being dropped. */ + while (space && + (UT_LIST_GET_LEN(space->chain) == 0 || + space->is_stopping() || space->purpose != FIL_TYPE_TABLESPACE)) + space= UT_LIST_GET_NEXT(space_list, space); + + if (space) + space->acquire(); + } + + mutex_exit(&fil_system.mutex); + return space; +} + /** Search for a space needing rotation @param[in,out] key_state Key state @param[in,out] state Rotation state @@ -1614,13 +1696,8 @@ static bool fil_crypt_find_space_to_rotate( state->space = NULL; } - /* If key rotation is enabled (default) we iterate all tablespaces. - If key rotation is not enabled we iterate only the tablespaces - added to keyrotation list. */ - state->space = srv_fil_crypt_rotate_key_age - ? fil_space_next(state->space) - : fil_system.keyrotate_next(state->space, *recheck, - key_state->key_version); + state->space = fil_space_next(state->space, *recheck, + key_state->key_version != 0); while (!state->should_shutdown() && state->space) { /* If there is no crypt data and we have not yet read @@ -1638,13 +1715,16 @@ static bool fil_crypt_find_space_to_rotate( return true; } - state->space = srv_fil_crypt_rotate_key_age - ? fil_space_next(state->space) - : fil_system.keyrotate_next(state->space, *recheck, - key_state->key_version); + state->space = fil_space_next(state->space, *recheck, + key_state->key_version != 0); + } + + if (state->space) { + state->space->release(); + state->space = NULL; } - /* if we didn't find any space return iops */ + /* no work to do; release our allocation of I/O capacity */ fil_crypt_return_iops(state); return false; @@ -2455,13 +2535,11 @@ static void fil_crypt_rotation_list_fill() if (!space->size) { /* Protect the tablespace while we may release fil_system.mutex. */ - space->n_pending_ops++; -#ifndef DBUG_OFF + ut_d(space->acquire()); ut_d(const fil_space_t* s=) fil_system.read_page0(space->id); ut_ad(!s || s == space); -#endif - space->n_pending_ops--; + ut_d(space->release()); if (!space->size) { /* Page 0 was not loaded. Skip this tablespace. */ diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 57303a25300..d47e9f3f5bf 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -4914,120 +4914,6 @@ test_make_filepath() #endif /* UNIV_ENABLE_UNIT_TEST_MAKE_FILEPATH */ /* @} */ -/** Return the next fil_space_t. -Once started, the caller must keep calling this until it returns NULL. -fil_space_t::acquire() and fil_space_t::release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system.space_list. -@return pointer to the next fil_space_t. -@retval NULL if this was the last*/ -fil_space_t* -fil_space_next(fil_space_t* prev_space) -{ - fil_space_t* space=prev_space; - - mutex_enter(&fil_system.mutex); - - if (!space) { - space = UT_LIST_GET_FIRST(fil_system.space_list); - } else { - ut_a(space->referenced()); - - /* Move on to the next fil_space_t */ - space->release(); - space = UT_LIST_GET_NEXT(space_list, space); - } - - /* Skip spaces that are being created by - fil_ibd_create(), or dropped, or !tablespace. */ - while (space != NULL - && (UT_LIST_GET_LEN(space->chain) == 0 - || space->is_stopping() - || space->purpose != FIL_TYPE_TABLESPACE)) { - space = UT_LIST_GET_NEXT(space_list, space); - } - - if (space != NULL) { - space->acquire(); - } - - mutex_exit(&fil_system.mutex); - - return(space); -} - -/** -Remove space from key rotation list if there are no more -pending operations. -@param[in,out] space Tablespace */ -static -void -fil_space_remove_from_keyrotation(fil_space_t* space) -{ - ut_ad(mutex_own(&fil_system.mutex)); - ut_ad(space); - - if (!space->referenced() && space->is_in_rotation_list) { - space->is_in_rotation_list = false; - ut_a(!fil_system.rotation_list.empty()); - fil_system.rotation_list.remove(*space); - } -} - - -/** Return the next fil_space_t from key rotation list. -Once started, the caller must keep calling this until it returns NULL. -fil_space_t::acquire() and fil_space_t::release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system.space_list. -@param[in] recheck recheck of the tablespace is needed or - still encryption thread does write page0 for it -@param[in] key_version key version of the key state thread -@return pointer to the next fil_space_t. -@retval NULL if this was the last */ -fil_space_t *fil_system_t::keyrotate_next(fil_space_t *prev_space, - bool recheck, uint key_version) -{ - mutex_enter(&fil_system.mutex); - - /* If one of the encryption threads already started the encryption - of the table then don't remove the unencrypted spaces from rotation list - - If there is a change in innodb_encrypt_tables variables value then - don't remove the last processed tablespace from the rotation list. */ - const bool remove= (!recheck || prev_space->crypt_data) && - !key_version == !srv_encrypt_tables; - sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it= - prev_space ? prev_space : fil_system.rotation_list.end(); - - if (it == fil_system.rotation_list.end()) - it= fil_system.rotation_list.begin(); - else - { - /* Move on to the next fil_space_t */ - prev_space->release(); - - ++it; - - while (it != fil_system.rotation_list.end() && - (UT_LIST_GET_LEN(it->chain) == 0 || it->is_stopping())) - ++it; - - if (remove) - fil_space_remove_from_keyrotation(prev_space); - } - - fil_space_t *space= it == fil_system.rotation_list.end() ? NULL : &*it; - - if (space) - space->acquire(); - - mutex_exit(&fil_system.mutex); - return space; -} - /** Determine the block size of the data file. @param[in] space tablespace @param[in] offset page number |