MDEV-19509 InnoDB skips the tablespace in rotation list
- If one of the encryption threads already started the initialization of the tablespace then don't remove the other uninitialized tablespace from the rotation list. - If there is a change in innodb_encrypt_tables then don't remove the processed tablespace from rotation list.
This commit is contained in:
parent
79b46ab2a6
commit
88157247fc
@ -943,14 +943,10 @@ fil_crypt_read_crypt_data(fil_space_t* space)
|
|||||||
mtr.commit();
|
mtr.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/** Start encrypting a space
|
||||||
Start encrypting a space
|
|
||||||
@param[in,out] space Tablespace
|
@param[in,out] space Tablespace
|
||||||
@return true if a recheck is needed */
|
@return true if a recheck of tablespace is needed by encryption thread. */
|
||||||
static
|
static bool fil_crypt_start_encrypting_space(fil_space_t* space)
|
||||||
bool
|
|
||||||
fil_crypt_start_encrypting_space(
|
|
||||||
fil_space_t* space)
|
|
||||||
{
|
{
|
||||||
bool recheck = false;
|
bool recheck = false;
|
||||||
|
|
||||||
@ -1408,14 +1404,12 @@ fil_crypt_return_iops(
|
|||||||
fil_crypt_update_total_stat(state);
|
fil_crypt_update_total_stat(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/** 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
|
@param[in,out] state Rotation state
|
||||||
@param[in,out] state Rotation state
|
@param[in,out] recheck recheck of the tablespace is needed or
|
||||||
@param[in,out] recheck recheck ? */
|
still encryption thread does write page 0 */
|
||||||
static
|
static bool fil_crypt_find_space_to_rotate(
|
||||||
bool
|
|
||||||
fil_crypt_find_space_to_rotate(
|
|
||||||
key_state_t* key_state,
|
key_state_t* key_state,
|
||||||
rotate_thread_t* state,
|
rotate_thread_t* state,
|
||||||
bool* recheck)
|
bool* recheck)
|
||||||
@ -1448,7 +1442,9 @@ fil_crypt_find_space_to_rotate(
|
|||||||
if (srv_fil_crypt_rotate_key_age) {
|
if (srv_fil_crypt_rotate_key_age) {
|
||||||
state->space = fil_space_next(state->space);
|
state->space = fil_space_next(state->space);
|
||||||
} else {
|
} else {
|
||||||
state->space = fil_space_keyrotate_next(state->space);
|
state->space = fil_system->keyrotate_next(
|
||||||
|
state->space, *recheck,
|
||||||
|
key_state->key_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!state->should_shutdown() && state->space) {
|
while (!state->should_shutdown() && state->space) {
|
||||||
@ -1470,7 +1466,9 @@ fil_crypt_find_space_to_rotate(
|
|||||||
if (srv_fil_crypt_rotate_key_age) {
|
if (srv_fil_crypt_rotate_key_age) {
|
||||||
state->space = fil_space_next(state->space);
|
state->space = fil_space_next(state->space);
|
||||||
} else {
|
} else {
|
||||||
state->space = fil_space_keyrotate_next(state->space);
|
state->space = fil_system->keyrotate_next(
|
||||||
|
state->space, *recheck,
|
||||||
|
key_state->key_version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5983,28 +5983,32 @@ fil_space_remove_from_keyrotation(fil_space_t* space)
|
|||||||
Once started, the caller must keep calling this until it returns NULL.
|
Once started, the caller must keep calling this until it returns NULL.
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
fil_space_acquire() and fil_space_release() are invoked here which
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
blocks a concurrent operation from dropping the tablespace.
|
||||||
@param[in] prev_space Pointer to the previous fil_space_t.
|
@param[in] prev_space Previous tablespace or NULL to start
|
||||||
|
from beginning of fil_system->rotation 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
|
||||||
If NULL, use the first fil_space_t on fil_system->space_list.
|
If NULL, use the first fil_space_t on fil_system->space_list.
|
||||||
@return pointer to the next fil_space_t.
|
@return pointer to the next fil_space_t.
|
||||||
@retval NULL if this was the last*/
|
@retval NULL if this was the last */
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_keyrotate_next(
|
fil_system_t::keyrotate_next(
|
||||||
fil_space_t* prev_space)
|
fil_space_t* prev_space,
|
||||||
|
bool recheck,
|
||||||
|
uint key_version)
|
||||||
{
|
{
|
||||||
fil_space_t* space = prev_space;
|
|
||||||
fil_space_t* old = NULL;
|
|
||||||
|
|
||||||
mutex_enter(&fil_system->mutex);
|
mutex_enter(&fil_system->mutex);
|
||||||
|
|
||||||
if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) {
|
/* If one of the encryption threads already started the encryption
|
||||||
if (space) {
|
of the table then don't remove the unencrypted spaces from
|
||||||
ut_ad(space->n_pending_ops > 0);
|
rotation list
|
||||||
space->n_pending_ops--;
|
|
||||||
fil_space_remove_from_keyrotation(space);
|
If there is a change in innodb_encrypt_tables variables value then
|
||||||
}
|
don't remove the last processed tablespace from the rotation list. */
|
||||||
mutex_exit(&fil_system->mutex);
|
const bool remove = ((!recheck || prev_space->crypt_data)
|
||||||
return(NULL);
|
&& (!key_version == !srv_encrypt_tables));
|
||||||
}
|
|
||||||
|
fil_space_t* space = prev_space;
|
||||||
|
|
||||||
if (prev_space == NULL) {
|
if (prev_space == NULL) {
|
||||||
space = UT_LIST_GET_FIRST(fil_system->rotation_list);
|
space = UT_LIST_GET_FIRST(fil_system->rotation_list);
|
||||||
@ -6017,22 +6021,17 @@ fil_space_keyrotate_next(
|
|||||||
/* Move on to the next fil_space_t */
|
/* Move on to the next fil_space_t */
|
||||||
space->n_pending_ops--;
|
space->n_pending_ops--;
|
||||||
|
|
||||||
old = space;
|
|
||||||
space = UT_LIST_GET_NEXT(rotation_list, space);
|
space = UT_LIST_GET_NEXT(rotation_list, space);
|
||||||
|
|
||||||
fil_space_remove_from_keyrotation(old);
|
while (space != NULL
|
||||||
}
|
&& (UT_LIST_GET_LEN(space->chain) == 0
|
||||||
|
|| space->is_stopping())) {
|
||||||
|
space = UT_LIST_GET_NEXT(rotation_list, space);
|
||||||
|
}
|
||||||
|
|
||||||
/* Skip spaces that are being created by fil_ibd_create(),
|
if (remove) {
|
||||||
or dropped. Note that rotation_list contains only
|
fil_space_remove_from_keyrotation(prev_space);
|
||||||
space->purpose == FIL_TYPE_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) {
|
if (space != NULL) {
|
||||||
@ -6040,7 +6039,6 @@ fil_space_keyrotate_next(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_exit(&fil_system->mutex);
|
mutex_exit(&fil_system->mutex);
|
||||||
|
|
||||||
return(space);
|
return(space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,6 +538,25 @@ struct fil_system_t {
|
|||||||
@return tablespace
|
@return tablespace
|
||||||
@retval NULL if the tablespace does not exist or cannot be read */
|
@retval NULL if the tablespace does not exist or cannot be read */
|
||||||
fil_space_t* read_page0(ulint id);
|
fil_space_t* read_page0(ulint id);
|
||||||
|
|
||||||
|
/** 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 Previous tablespace or NULL to start
|
||||||
|
from beginning of fil_system->rotation
|
||||||
|
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
|
||||||
|
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* keyrotate_next(
|
||||||
|
fil_space_t* prev_space,
|
||||||
|
bool remove,
|
||||||
|
uint key_version);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The tablespace memory cache. This variable is NULL before the module is
|
/** The tablespace memory cache. This variable is NULL before the module is
|
||||||
@ -793,13 +812,15 @@ fil_space_next(
|
|||||||
Once started, the caller must keep calling this until it returns NULL.
|
Once started, the caller must keep calling this until it returns NULL.
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
fil_space_acquire() and fil_space_release() are invoked here which
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
blocks a concurrent operation from dropping the tablespace.
|
||||||
@param[in,out] prev_space Pointer to the previous fil_space_t.
|
@param[in] prev_space Previous tablespace or NULL to start
|
||||||
|
from beginning of fil_system->rotation list
|
||||||
|
@param[in] remove Whether to remove the previous tablespace from
|
||||||
|
the rotation list
|
||||||
If NULL, use the first fil_space_t on fil_system->space_list.
|
If NULL, use the first fil_space_t on fil_system->space_list.
|
||||||
@return pointer to the next fil_space_t.
|
@return pointer to the next fil_space_t.
|
||||||
@retval NULL if this was the last*/
|
@retval NULL if this was the last*/
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_keyrotate_next(
|
fil_space_keyrotate_next(fil_space_t* prev_space, bool remove)
|
||||||
fil_space_t* prev_space)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
|
||||||
/** Wrapper with reference-counting for a fil_space_t. */
|
/** Wrapper with reference-counting for a fil_space_t. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user