summaryrefslogtreecommitdiff
path: root/storage/innobase/fil/fil0crypt.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/fil/fil0crypt.cc')
-rw-r--r--storage/innobase/fil/fil0crypt.cc122
1 files changed, 100 insertions, 22 deletions
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index c08f1eedc33..6f9f1c2c17c 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 */
@@ -105,8 +102,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);
@@ -120,7 +115,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);
}
@@ -1455,6 +1449,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
@@ -1487,13 +1569,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
@@ -1511,13 +1588,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;
@@ -2172,13 +2252,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. */