Commit 1fe3dd00 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-24426 fil_crypt_thread keep spinning even if innodb_encryption_rotate_key_age=0

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.
parent 6bb3949e
--innodb-encryption-rotate-key-age=2 --innodb-encryption-rotate-key-age=0
--innodb-encryption-threads=4 --innodb-encryption-threads=4
--innodb-tablespaces-encryption --innodb-tablespaces-encryption
--plugin-load-add=$FILE_KEY_MANAGEMENT_SO --plugin-load-add=$FILE_KEY_MANAGEMENT_SO
......
...@@ -1402,13 +1402,10 @@ fil_crypt_realloc_iops( ...@@ -1402,13 +1402,10 @@ fil_crypt_realloc_iops(
fil_crypt_update_total_stat(state); fil_crypt_update_total_stat(state);
} }
/*********************************************************************** /** Release excess allocated iops
Return allocated iops to global @param state rotation state
@param[in,out] state Rotation state */ @param wake whether to wake up other threads */
static static void fil_crypt_return_iops(rotate_thread_t *state, bool wake= true)
void
fil_crypt_return_iops(
rotate_thread_t *state)
{ {
if (state->allocated_iops > 0) { if (state->allocated_iops > 0) {
uint iops = state->allocated_iops; uint iops = state->allocated_iops;
...@@ -1424,7 +1421,9 @@ fil_crypt_return_iops( ...@@ -1424,7 +1421,9 @@ fil_crypt_return_iops(
n_fil_crypt_iops_allocated -= iops; n_fil_crypt_iops_allocated -= iops;
state->allocated_iops = 0; 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); mutex_exit(&fil_crypt_threads_mutex);
} }
...@@ -1437,7 +1436,8 @@ fil_crypt_return_iops( ...@@ -1437,7 +1436,8 @@ fil_crypt_return_iops(
the encryption parameters were changed the encryption parameters were changed
@param encrypt expected state of innodb_encrypt_tables @param encrypt expected state of innodb_encrypt_tables
@return the next tablespace to process (n_pending_ops incremented) @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, inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
bool recheck, bool encrypt) bool recheck, bool encrypt)
{ {
...@@ -1472,15 +1472,20 @@ inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space, ...@@ -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; space= &*it;
if (space->acquire_if_not_stopped(true)) if (space->acquire_if_not_stopped(true))
return space; 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. /** 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, ...@@ -1489,6 +1494,7 @@ inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
encryption parameters were changed encryption parameters were changed
@param encrypt expected state of innodb_encrypt_tables @param encrypt expected state of innodb_encrypt_tables
@return the next tablespace @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 */ @retval nullptr upon reaching the end of the iteration */
inline fil_space_t *fil_space_t::next(fil_space_t *space, bool recheck, inline fil_space_t *fil_space_t::next(fil_space_t *space, bool recheck,
bool encrypt) bool encrypt)
...@@ -1561,10 +1567,25 @@ static bool fil_crypt_find_space_to_rotate( ...@@ -1561,10 +1567,25 @@ static bool fil_crypt_find_space_to_rotate(
state->space = NULL; state->space = NULL;
} }
state->space = fil_space_t::next(state->space, *recheck, bool wake;
key_state->key_version != 0); 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 /* If there is no crypt data and we have not yet read
page 0 for this tablespace, we need to read it before page 0 for this tablespace, we need to read it before
we can continue. */ we can continue. */
...@@ -1579,18 +1600,16 @@ static bool fil_crypt_find_space_to_rotate( ...@@ -1579,18 +1600,16 @@ static bool fil_crypt_find_space_to_rotate(
state->min_key_version_found = key_state->key_version; state->min_key_version_found = key_state->key_version;
return true; return true;
} }
state->space = fil_space_t::next(state->space, *recheck,
key_state->key_version != 0);
} }
if (state->space) { if (state->space) {
state->space->release(); state->space->release();
done:
state->space = NULL; state->space = NULL;
} }
/* no work to do; release our allocation of I/O capacity */ /* no work to do; release our allocation of I/O capacity */
fil_crypt_return_iops(state); fil_crypt_return_iops(state, wake);
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment