summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-12-17 13:46:21 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-12-17 13:46:21 +0200
commit1fe3dd003a027ab618ce445eab37140a04c4a426 (patch)
treebf7290f9ebe3f19c14b31c336533b4f10f545a06
parent6bb3949eb37bbe674a3550b502b3f60474cc0d46 (diff)
downloadmariadb-git-1fe3dd003a027ab618ce445eab37140a04c4a426.tar.gz
MDEV-24426 fil_crypt_thread keep spinning even if innodb_encryption_rotate_key_age=0bb-10.5-MDEV-24426
After MDEV-15528, two modes of operation in the fil_crypt_thread remains, depending on whether innodb_encryption_rotate_key_age=0 (whether key rotation is disabled). If the key rotation is disabled, the fil_crypt_thread miss the opportunity to sleep, which will result in lots of wasted CPU usage. fil_crypt_return_iops(): Add a parameter to specify whether other fil_crypt_thread should be woken up. fil_system_t::keyrotate_next(): Return the special value fil_system.temp_space to indicate that no work is to be done. fil_space_t::next(): Propagage the special value fil_system.temp_space to the caller. fil_crypt_find_space_to_rotate(): If no work is to be done, do not wake up other threads.
-rw-r--r--mysql-test/suite/mariabackup/xb_compressed_encrypted.opt2
-rw-r--r--storage/innobase/fil/fil0crypt.cc57
2 files changed, 39 insertions, 20 deletions
diff --git a/mysql-test/suite/mariabackup/xb_compressed_encrypted.opt b/mysql-test/suite/mariabackup/xb_compressed_encrypted.opt
index 8baef973470..4105fecfe58 100644
--- a/mysql-test/suite/mariabackup/xb_compressed_encrypted.opt
+++ b/mysql-test/suite/mariabackup/xb_compressed_encrypted.opt
@@ -1,4 +1,4 @@
---innodb-encryption-rotate-key-age=2
+--innodb-encryption-rotate-key-age=0
--innodb-encryption-threads=4
--innodb-tablespaces-encryption
--plugin-load-add=$FILE_KEY_MANAGEMENT_SO
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 2e7e258a04b..dce492b8069 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -1402,13 +1402,10 @@ fil_crypt_realloc_iops(
fil_crypt_update_total_stat(state);
}
-/***********************************************************************
-Return allocated iops to global
-@param[in,out] state Rotation state */
-static
-void
-fil_crypt_return_iops(
- rotate_thread_t *state)
+/** Release excess allocated iops
+@param state rotation state
+@param wake whether to wake up other threads */
+static void fil_crypt_return_iops(rotate_thread_t *state, bool wake= true)
{
if (state->allocated_iops > 0) {
uint iops = state->allocated_iops;
@@ -1424,7 +1421,9 @@ fil_crypt_return_iops(
n_fil_crypt_iops_allocated -= iops;
state->allocated_iops = 0;
- os_event_set(fil_crypt_threads_event);
+ if (wake) {
+ os_event_set(fil_crypt_threads_event);
+ }
mutex_exit(&fil_crypt_threads_mutex);
}
@@ -1437,7 +1436,8 @@ fil_crypt_return_iops(
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 */
+@retval fil_system.temp_space if there is no work to do
+@retval nullptr upon reaching the end of the iteration */
inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
bool recheck, bool encrypt)
{
@@ -1472,15 +1472,20 @@ inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
}
}
- while (it != end)
+ if (it == end)
+ return temp_space;
+
+ do
{
space= &*it;
if (space->acquire_if_not_stopped(true))
return space;
- while (++it != end && (!UT_LIST_GET_LEN(it->chain) || it->is_stopping()));
+ if (++it == end)
+ return nullptr;
}
+ while (!UT_LIST_GET_LEN(it->chain) || it->is_stopping());
- return NULL;
+ return nullptr;
}
/** Determine the next tablespace for encryption key rotation.
@@ -1489,6 +1494,7 @@ inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
encryption parameters were changed
@param encrypt expected state of innodb_encrypt_tables
@return the next tablespace
+@retval fil_system.temp_space if there is no work to do
@retval nullptr upon reaching the end of the iteration */
inline fil_space_t *fil_space_t::next(fil_space_t *space, bool recheck,
bool encrypt)
@@ -1561,10 +1567,25 @@ static bool fil_crypt_find_space_to_rotate(
state->space = NULL;
}
- state->space = fil_space_t::next(state->space, *recheck,
- key_state->key_version != 0);
+ bool wake;
+ for (;;) {
+ state->space = fil_space_t::next(state->space, *recheck,
+ key_state->key_version != 0);
+ wake = state->should_shutdown();
+ if (wake) {
+ break;
+ }
+
+ if (state->space == fil_system.temp_space) {
+ goto done;
+ } else {
+ wake = true;
+ }
+
+ if (!state->space) {
+ break;
+ }
- while (!state->should_shutdown() && state->space) {
/* If there is no crypt data and we have not yet read
page 0 for this tablespace, we need to read it before
we can continue. */
@@ -1579,18 +1600,16 @@ static bool fil_crypt_find_space_to_rotate(
state->min_key_version_found = key_state->key_version;
return true;
}
-
- state->space = fil_space_t::next(state->space, *recheck,
- key_state->key_version != 0);
}
if (state->space) {
state->space->release();
+done:
state->space = NULL;
}
/* no work to do; release our allocation of I/O capacity */
- fil_crypt_return_iops(state);
+ fil_crypt_return_iops(state, wake);
return false;