MDEV-16115 Hang after reducing innodb_encryption_threads
The test encryption.create_or_replace would occasionally fail, because some fil_space_t::n_pending_ops would never be decremented. fil_crypt_find_space_to_rotate(): If rotate_thread_t::should_shutdown() holds due to innodb_encryption_threads having been reduced, do release the reference. fil_space_remove_from_keyrotation(), fil_space_next(): Declare the functions static, simplify a little, and define in the same compilation unit with the only caller, fil_crypt_find_space_to_rotate(). fil_crypt_key_mutex: Remove (unused).
This commit is contained in:
parent
3e3da1642d
commit
7f67ef1485
@ -44,15 +44,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
|
|||||||
#include "ha_prototypes.h" // IB_LOG_
|
#include "ha_prototypes.h" // IB_LOG_
|
||||||
#include <my_crypt.h>
|
#include <my_crypt.h>
|
||||||
|
|
||||||
/** Mutex for keys */
|
|
||||||
static ib_mutex_t fil_crypt_key_mutex;
|
|
||||||
|
|
||||||
static bool fil_crypt_threads_inited = false;
|
static bool fil_crypt_threads_inited = false;
|
||||||
|
|
||||||
#ifdef UNIV_PFS_MUTEX
|
|
||||||
static mysql_pfs_key_t fil_crypt_key_mutex_key;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Is encryption enabled/disabled */
|
/** Is encryption enabled/disabled */
|
||||||
UNIV_INTERN ulong srv_encrypt_tables = 0;
|
UNIV_INTERN ulong srv_encrypt_tables = 0;
|
||||||
|
|
||||||
@ -133,9 +126,6 @@ UNIV_INTERN
|
|||||||
void
|
void
|
||||||
fil_space_crypt_init()
|
fil_space_crypt_init()
|
||||||
{
|
{
|
||||||
mutex_create(fil_crypt_key_mutex_key,
|
|
||||||
&fil_crypt_key_mutex, SYNC_NO_ORDER_CHECK);
|
|
||||||
|
|
||||||
fil_crypt_throttle_sleep_event = os_event_create();
|
fil_crypt_throttle_sleep_event = os_event_create();
|
||||||
|
|
||||||
mutex_create(fil_crypt_stat_mutex_key,
|
mutex_create(fil_crypt_stat_mutex_key,
|
||||||
@ -152,7 +142,6 @@ fil_space_crypt_cleanup()
|
|||||||
{
|
{
|
||||||
os_event_free(fil_crypt_throttle_sleep_event);
|
os_event_free(fil_crypt_throttle_sleep_event);
|
||||||
fil_crypt_throttle_sleep_event = NULL;
|
fil_crypt_throttle_sleep_event = NULL;
|
||||||
mutex_free(&fil_crypt_key_mutex);
|
|
||||||
mutex_free(&crypt_stat_mutex);
|
mutex_free(&crypt_stat_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1451,6 +1440,109 @@ fil_crypt_return_iops(
|
|||||||
fil_crypt_update_total_stat(state);
|
fil_crypt_update_total_stat(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Remove space from key rotation list if there are no pending operations. */
|
||||||
|
static void fil_space_remove_from_keyrotation(fil_space_t *space)
|
||||||
|
{
|
||||||
|
ut_ad(mutex_own(&fil_system->mutex));
|
||||||
|
|
||||||
|
if (space->n_pending_ops == 0 && space->is_in_rotation_list)
|
||||||
|
{
|
||||||
|
space->is_in_rotation_list= false;
|
||||||
|
ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
|
||||||
|
UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the next tablespace from key rotation list.
|
||||||
|
@param space previous tablespace (NULL to start from the beginning)
|
||||||
|
@return pointer to the next tablespace (with n_pending_ops incremented)
|
||||||
|
@retval NULL if this was the last */
|
||||||
|
static fil_space_t *fil_space_keyrotate_next(fil_space_t *space)
|
||||||
|
{
|
||||||
|
ut_ad(mutex_own(&fil_system->mutex));
|
||||||
|
|
||||||
|
if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0)
|
||||||
|
{
|
||||||
|
if (space)
|
||||||
|
{
|
||||||
|
space->n_pending_ops--;
|
||||||
|
fil_space_remove_from_keyrotation(space);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!space)
|
||||||
|
{
|
||||||
|
space= UT_LIST_GET_FIRST(fil_system->rotation_list);
|
||||||
|
/* We can trust that space is not NULL because we
|
||||||
|
checked list length above */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
space->n_pending_ops--;
|
||||||
|
fil_space_t *old = space;
|
||||||
|
space= UT_LIST_GET_NEXT(rotation_list, space);
|
||||||
|
fil_space_remove_from_keyrotation(old);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip spaces that are being created by fil_ibd_create(),
|
||||||
|
or dropped. Note that rotation_list contains only
|
||||||
|
space->purpose == FIL_TABLESPACE. */
|
||||||
|
while (space && (!UT_LIST_GET_LEN(space->chain) || space->is_stopping()))
|
||||||
|
{
|
||||||
|
fil_space_t *old = space;
|
||||||
|
space= UT_LIST_GET_NEXT(rotation_list, space);
|
||||||
|
fil_space_remove_from_keyrotation(old);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (space)
|
||||||
|
space->n_pending_ops++;
|
||||||
|
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the next tablespace.
|
||||||
|
@param space previous tablespace (NULL to start from the beginning)
|
||||||
|
@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)
|
||||||
|
{
|
||||||
|
mutex_enter(&fil_system->mutex);
|
||||||
|
ut_ad(!space || space->n_pending_ops);
|
||||||
|
|
||||||
|
if (!srv_fil_crypt_rotate_key_age)
|
||||||
|
space= fil_space_keyrotate_next(space);
|
||||||
|
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->n_pending_ops++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ut_ad(space->n_pending_ops > 0);
|
||||||
|
/* Move on to the next fil_space_t */
|
||||||
|
space->n_pending_ops--;
|
||||||
|
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_TABLESPACE))
|
||||||
|
space= UT_LIST_GET_NEXT(space_list, space);
|
||||||
|
|
||||||
|
if (space)
|
||||||
|
space->n_pending_ops++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_exit(&fil_system->mutex);
|
||||||
|
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Search for a space needing rotation
|
Search for a space needing rotation
|
||||||
@param[in,out] key_state Key state
|
@param[in,out] key_state Key state
|
||||||
@ -1485,14 +1577,7 @@ fil_crypt_find_space_to_rotate(
|
|||||||
state->space = NULL;
|
state->space = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If key rotation is enabled (default) we iterate all tablespaces.
|
state->space = fil_space_next(state->space);
|
||||||
If key rotation is not enabled we iterate only the tablespaces
|
|
||||||
added to keyrotation list. */
|
|
||||||
if (srv_fil_crypt_rotate_key_age) {
|
|
||||||
state->space = fil_space_next(state->space);
|
|
||||||
} else {
|
|
||||||
state->space = fil_space_keyrotate_next(state->space);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!state->should_shutdown() && state->space) {
|
while (!state->should_shutdown() && state->space) {
|
||||||
fil_crypt_read_crypt_data(state->space);
|
fil_crypt_read_crypt_data(state->space);
|
||||||
@ -1505,14 +1590,15 @@ fil_crypt_find_space_to_rotate(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srv_fil_crypt_rotate_key_age) {
|
state->space = fil_space_next(state->space);
|
||||||
state->space = fil_space_next(state->space);
|
|
||||||
} else {
|
|
||||||
state->space = fil_space_keyrotate_next(state->space);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we didn't find any space return iops */
|
if (state->space) {
|
||||||
|
fil_space_release(state->space);
|
||||||
|
state->space = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no work to do; release our allocation of I/O capacity */
|
||||||
fil_crypt_return_iops(state);
|
fil_crypt_return_iops(state);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -6476,137 +6476,3 @@ fil_space_release_for_io(fil_space_t* space)
|
|||||||
space->n_pending_ios--;
|
space->n_pending_ios--;
|
||||||
mutex_exit(&fil_system->mutex);
|
mutex_exit(&fil_system->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the next fil_space_t.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_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*/
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_next(fil_space_t* prev_space)
|
|
||||||
{
|
|
||||||
fil_space_t* space=prev_space;
|
|
||||||
|
|
||||||
mutex_enter(&fil_system->mutex);
|
|
||||||
|
|
||||||
if (prev_space == NULL) {
|
|
||||||
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->n_pending_ops++;
|
|
||||||
} else {
|
|
||||||
ut_ad(space->n_pending_ops > 0);
|
|
||||||
|
|
||||||
/* Move on to the next fil_space_t */
|
|
||||||
space->n_pending_ops--;
|
|
||||||
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_TABLESPACE)) {
|
|
||||||
space = UT_LIST_GET_NEXT(space_list, space);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (space != NULL) {
|
|
||||||
space->n_pending_ops++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_exit(&fil_system->mutex);
|
|
||||||
|
|
||||||
return(space);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Remove space from key rotation list if there are no more
|
|
||||||
pending operations.
|
|
||||||
@param[in] 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->n_pending_ops == 0 && space->is_in_rotation_list) {
|
|
||||||
space->is_in_rotation_list = false;
|
|
||||||
ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
|
|
||||||
UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, 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_acquire() and fil_space_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*/
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_keyrotate_next(
|
|
||||||
fil_space_t* prev_space)
|
|
||||||
{
|
|
||||||
fil_space_t* space = prev_space;
|
|
||||||
fil_space_t* old = NULL;
|
|
||||||
|
|
||||||
mutex_enter(&fil_system->mutex);
|
|
||||||
|
|
||||||
if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) {
|
|
||||||
if (space) {
|
|
||||||
ut_ad(space->n_pending_ops > 0);
|
|
||||||
space->n_pending_ops--;
|
|
||||||
fil_space_remove_from_keyrotation(space);
|
|
||||||
}
|
|
||||||
mutex_exit(&fil_system->mutex);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prev_space == NULL) {
|
|
||||||
space = UT_LIST_GET_FIRST(fil_system->rotation_list);
|
|
||||||
|
|
||||||
/* We can trust that space is not NULL because we
|
|
||||||
checked list length above */
|
|
||||||
} else {
|
|
||||||
ut_ad(space->n_pending_ops > 0);
|
|
||||||
|
|
||||||
/* Move on to the next fil_space_t */
|
|
||||||
space->n_pending_ops--;
|
|
||||||
|
|
||||||
old = space;
|
|
||||||
space = UT_LIST_GET_NEXT(rotation_list, space);
|
|
||||||
|
|
||||||
fil_space_remove_from_keyrotation(old);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip spaces that are being created by fil_ibd_create(),
|
|
||||||
or dropped. Note that rotation_list contains only
|
|
||||||
space->purpose == FIL_TABLESPACE. */
|
|
||||||
while (space != NULL
|
|
||||||
&& (UT_LIST_GET_LEN(space->chain) == 0
|
|
||||||
|| space->is_stopping())) {
|
|
||||||
|
|
||||||
old = space;
|
|
||||||
space = UT_LIST_GET_NEXT(rotation_list, space);
|
|
||||||
fil_space_remove_from_keyrotation(old);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (space != NULL) {
|
|
||||||
space->n_pending_ops++;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_exit(&fil_system->mutex);
|
|
||||||
|
|
||||||
return(space);
|
|
||||||
}
|
|
||||||
|
@ -699,34 +699,6 @@ UNIV_INTERN
|
|||||||
void
|
void
|
||||||
fil_space_release_for_io(fil_space_t* space);
|
fil_space_release_for_io(fil_space_t* space);
|
||||||
|
|
||||||
/** Return the next fil_space_t.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in,out] 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 */
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_next(
|
|
||||||
fil_space_t* prev_space)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
|
||||||
|
|
||||||
/** Return the next fil_space_t from key rotation list.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in,out] 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*/
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_keyrotate_next(
|
|
||||||
fil_space_t* prev_space)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
|
||||||
|
|
||||||
/** Wrapper with reference-counting for a fil_space_t. */
|
/** Wrapper with reference-counting for a fil_space_t. */
|
||||||
class FilSpace
|
class FilSpace
|
||||||
{
|
{
|
||||||
|
@ -44,15 +44,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
|
|||||||
#include "ha_prototypes.h" // IB_LOG_
|
#include "ha_prototypes.h" // IB_LOG_
|
||||||
#include <my_crypt.h>
|
#include <my_crypt.h>
|
||||||
|
|
||||||
/** Mutex for keys */
|
|
||||||
static ib_mutex_t fil_crypt_key_mutex;
|
|
||||||
|
|
||||||
static bool fil_crypt_threads_inited = false;
|
static bool fil_crypt_threads_inited = false;
|
||||||
|
|
||||||
#ifdef UNIV_PFS_MUTEX
|
|
||||||
static mysql_pfs_key_t fil_crypt_key_mutex_key;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Is encryption enabled/disabled */
|
/** Is encryption enabled/disabled */
|
||||||
UNIV_INTERN ulong srv_encrypt_tables = 0;
|
UNIV_INTERN ulong srv_encrypt_tables = 0;
|
||||||
|
|
||||||
@ -133,9 +126,6 @@ UNIV_INTERN
|
|||||||
void
|
void
|
||||||
fil_space_crypt_init()
|
fil_space_crypt_init()
|
||||||
{
|
{
|
||||||
mutex_create(fil_crypt_key_mutex_key,
|
|
||||||
&fil_crypt_key_mutex, SYNC_NO_ORDER_CHECK);
|
|
||||||
|
|
||||||
fil_crypt_throttle_sleep_event = os_event_create();
|
fil_crypt_throttle_sleep_event = os_event_create();
|
||||||
|
|
||||||
mutex_create(fil_crypt_stat_mutex_key,
|
mutex_create(fil_crypt_stat_mutex_key,
|
||||||
@ -152,7 +142,6 @@ fil_space_crypt_cleanup()
|
|||||||
{
|
{
|
||||||
os_event_free(fil_crypt_throttle_sleep_event);
|
os_event_free(fil_crypt_throttle_sleep_event);
|
||||||
fil_crypt_throttle_sleep_event = NULL;
|
fil_crypt_throttle_sleep_event = NULL;
|
||||||
mutex_free(&fil_crypt_key_mutex);
|
|
||||||
mutex_free(&crypt_stat_mutex);
|
mutex_free(&crypt_stat_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1451,6 +1440,109 @@ fil_crypt_return_iops(
|
|||||||
fil_crypt_update_total_stat(state);
|
fil_crypt_update_total_stat(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Remove space from key rotation list if there are no pending operations. */
|
||||||
|
static void fil_space_remove_from_keyrotation(fil_space_t *space)
|
||||||
|
{
|
||||||
|
ut_ad(mutex_own(&fil_system->mutex));
|
||||||
|
|
||||||
|
if (space->n_pending_ops == 0 && space->is_in_rotation_list)
|
||||||
|
{
|
||||||
|
space->is_in_rotation_list= false;
|
||||||
|
ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
|
||||||
|
UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the next tablespace from key rotation list.
|
||||||
|
@param space previous tablespace (NULL to start from the beginning)
|
||||||
|
@return pointer to the next tablespace (with n_pending_ops incremented)
|
||||||
|
@retval NULL if this was the last */
|
||||||
|
static fil_space_t *fil_space_keyrotate_next(fil_space_t *space)
|
||||||
|
{
|
||||||
|
ut_ad(mutex_own(&fil_system->mutex));
|
||||||
|
|
||||||
|
if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0)
|
||||||
|
{
|
||||||
|
if (space)
|
||||||
|
{
|
||||||
|
space->n_pending_ops--;
|
||||||
|
fil_space_remove_from_keyrotation(space);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!space)
|
||||||
|
{
|
||||||
|
space= UT_LIST_GET_FIRST(fil_system->rotation_list);
|
||||||
|
/* We can trust that space is not NULL because we
|
||||||
|
checked list length above */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
space->n_pending_ops--;
|
||||||
|
fil_space_t *old = space;
|
||||||
|
space= UT_LIST_GET_NEXT(rotation_list, space);
|
||||||
|
fil_space_remove_from_keyrotation(old);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip spaces that are being created by fil_ibd_create(),
|
||||||
|
or dropped. Note that rotation_list contains only
|
||||||
|
space->purpose == FIL_TABLESPACE. */
|
||||||
|
while (space && (!UT_LIST_GET_LEN(space->chain) || space->is_stopping()))
|
||||||
|
{
|
||||||
|
fil_space_t *old = space;
|
||||||
|
space= UT_LIST_GET_NEXT(rotation_list, space);
|
||||||
|
fil_space_remove_from_keyrotation(old);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (space)
|
||||||
|
space->n_pending_ops++;
|
||||||
|
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the next tablespace.
|
||||||
|
@param space previous tablespace (NULL to start from the beginning)
|
||||||
|
@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)
|
||||||
|
{
|
||||||
|
mutex_enter(&fil_system->mutex);
|
||||||
|
ut_ad(!space || space->n_pending_ops);
|
||||||
|
|
||||||
|
if (!srv_fil_crypt_rotate_key_age)
|
||||||
|
space= fil_space_keyrotate_next(space);
|
||||||
|
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->n_pending_ops++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ut_ad(space->n_pending_ops > 0);
|
||||||
|
/* Move on to the next fil_space_t */
|
||||||
|
space->n_pending_ops--;
|
||||||
|
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_TABLESPACE))
|
||||||
|
space= UT_LIST_GET_NEXT(space_list, space);
|
||||||
|
|
||||||
|
if (space)
|
||||||
|
space->n_pending_ops++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_exit(&fil_system->mutex);
|
||||||
|
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Search for a space needing rotation
|
Search for a space needing rotation
|
||||||
@param[in,out] key_state Key state
|
@param[in,out] key_state Key state
|
||||||
@ -1485,14 +1577,7 @@ fil_crypt_find_space_to_rotate(
|
|||||||
state->space = NULL;
|
state->space = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If key rotation is enabled (default) we iterate all tablespaces.
|
state->space = fil_space_next(state->space);
|
||||||
If key rotation is not enabled we iterate only the tablespaces
|
|
||||||
added to keyrotation list. */
|
|
||||||
if (srv_fil_crypt_rotate_key_age) {
|
|
||||||
state->space = fil_space_next(state->space);
|
|
||||||
} else {
|
|
||||||
state->space = fil_space_keyrotate_next(state->space);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!state->should_shutdown() && state->space) {
|
while (!state->should_shutdown() && state->space) {
|
||||||
fil_crypt_read_crypt_data(state->space);
|
fil_crypt_read_crypt_data(state->space);
|
||||||
@ -1505,14 +1590,15 @@ fil_crypt_find_space_to_rotate(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srv_fil_crypt_rotate_key_age) {
|
state->space = fil_space_next(state->space);
|
||||||
state->space = fil_space_next(state->space);
|
|
||||||
} else {
|
|
||||||
state->space = fil_space_keyrotate_next(state->space);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we didn't find any space return iops */
|
if (state->space) {
|
||||||
|
fil_space_release(state->space);
|
||||||
|
state->space = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no work to do; release our allocation of I/O capacity */
|
||||||
fil_crypt_return_iops(state);
|
fil_crypt_return_iops(state);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -6863,137 +6863,3 @@ fil_space_release(fil_space_t* space)
|
|||||||
space->n_pending_ops--;
|
space->n_pending_ops--;
|
||||||
mutex_exit(&fil_system->mutex);
|
mutex_exit(&fil_system->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the next fil_space_t.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_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*/
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_next(fil_space_t* prev_space)
|
|
||||||
{
|
|
||||||
fil_space_t* space=prev_space;
|
|
||||||
|
|
||||||
mutex_enter(&fil_system->mutex);
|
|
||||||
|
|
||||||
if (prev_space == NULL) {
|
|
||||||
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->n_pending_ops++;
|
|
||||||
} else {
|
|
||||||
ut_ad(space->n_pending_ops > 0);
|
|
||||||
|
|
||||||
/* Move on to the next fil_space_t */
|
|
||||||
space->n_pending_ops--;
|
|
||||||
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_TABLESPACE)) {
|
|
||||||
space = UT_LIST_GET_NEXT(space_list, space);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (space != NULL) {
|
|
||||||
space->n_pending_ops++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_exit(&fil_system->mutex);
|
|
||||||
|
|
||||||
return(space);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Remove space from key rotation list if there are no more
|
|
||||||
pending operations.
|
|
||||||
@param[in] 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->n_pending_ops == 0 && space->is_in_rotation_list) {
|
|
||||||
space->is_in_rotation_list = false;
|
|
||||||
ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
|
|
||||||
UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, 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_acquire() and fil_space_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*/
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_keyrotate_next(
|
|
||||||
fil_space_t* prev_space)
|
|
||||||
{
|
|
||||||
fil_space_t* space = prev_space;
|
|
||||||
fil_space_t* old = NULL;
|
|
||||||
|
|
||||||
mutex_enter(&fil_system->mutex);
|
|
||||||
|
|
||||||
if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) {
|
|
||||||
if (space) {
|
|
||||||
ut_ad(space->n_pending_ops > 0);
|
|
||||||
space->n_pending_ops--;
|
|
||||||
fil_space_remove_from_keyrotation(space);
|
|
||||||
}
|
|
||||||
mutex_exit(&fil_system->mutex);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prev_space == NULL) {
|
|
||||||
space = UT_LIST_GET_FIRST(fil_system->rotation_list);
|
|
||||||
|
|
||||||
/* We can trust that space is not NULL because we
|
|
||||||
checked list length above */
|
|
||||||
} else {
|
|
||||||
ut_ad(space->n_pending_ops > 0);
|
|
||||||
|
|
||||||
/* Move on to the next fil_space_t */
|
|
||||||
space->n_pending_ops--;
|
|
||||||
|
|
||||||
old = space;
|
|
||||||
space = UT_LIST_GET_NEXT(rotation_list, space);
|
|
||||||
|
|
||||||
fil_space_remove_from_keyrotation(old);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip spaces that are being created by fil_ibd_create(),
|
|
||||||
or dropped. Note that rotation_list contains only
|
|
||||||
space->purpose == FIL_TABLESPACE. */
|
|
||||||
while (space != NULL
|
|
||||||
&& (UT_LIST_GET_LEN(space->chain) == 0
|
|
||||||
|| space->is_stopping())) {
|
|
||||||
|
|
||||||
old = space;
|
|
||||||
space = UT_LIST_GET_NEXT(rotation_list, space);
|
|
||||||
fil_space_remove_from_keyrotation(old);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (space != NULL) {
|
|
||||||
space->n_pending_ops++;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_exit(&fil_system->mutex);
|
|
||||||
|
|
||||||
return(space);
|
|
||||||
}
|
|
||||||
|
@ -705,34 +705,6 @@ UNIV_INTERN
|
|||||||
void
|
void
|
||||||
fil_space_release_for_io(fil_space_t* space);
|
fil_space_release_for_io(fil_space_t* space);
|
||||||
|
|
||||||
/** Return the next fil_space_t.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in,out] 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 */
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_next(
|
|
||||||
fil_space_t* prev_space)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
|
||||||
|
|
||||||
/** Return the next fil_space_t from key rotation list.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in,out] 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*/
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_keyrotate_next(
|
|
||||||
fil_space_t* prev_space)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
|
||||||
|
|
||||||
/** Wrapper with reference-counting for a fil_space_t. */
|
/** Wrapper with reference-counting for a fil_space_t. */
|
||||||
class FilSpace
|
class FilSpace
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user