mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-41395 fil_space_t::create() may release fil_system.mutex
- By default fil_crypt_must_default_encrypt() holds, and then fil_crypt_thread() waits indefinitely in wait_for_work() once the default_encrypt list has been exhausted. A tablespace for which no fil_crypt_threads_signal() is issued would therefore never be encrypted at all. fil_ibd_create(): Invoke fil_crypt_threads_signal() after fil_space_t::clear_stopped() dict_load_tablespace(): Invoke fil_crypt_threads_signal(), because fil_ibd_open() may have added the tablespace to fil_system.default_encrypt_tables. This is the single point through which every dictionary-driven tablespace open passes; it is only invoked by dict_load_table_one(), hence by dict_sys_t::load_table(). The call in dict_table_open_on_name() does not cover it, because that function returns a cached table before reaching the wake-up. A table first loaded by dict_table_open_on_id() would thus never be signalled, neither then nor later. row_import_cleanup(): Do not invoke fil_crypt_threads_signal(). fil_crypt_add_imported_space() registers it afterwards and broadcasts. fil_crypt_threads_signal(): Also return early when no encryption thread is running. srv_n_fil_crypt_threads_started: Declare as Atomic_relaxed<uint>, for the unlocked read in fil_crypt_threads_signal().
This commit is contained in:
@@ -2285,6 +2285,14 @@ dict_load_tablespace(
|
||||
fil_space_t::VALIDATE_SPACE_ID,
|
||||
{table->name.m_name, strlen(table->name.m_name)}, filepath);
|
||||
|
||||
/* fil_space_t::create() may have added the tablespace to
|
||||
fil_system.default_encrypt_tables. Signalling here covers
|
||||
every caller of dict_sys_t::load_table() and
|
||||
dict_load_table_on_id(), including dict_table_open_on_name()
|
||||
for a table that some other thread had already loaded into
|
||||
the cache. */
|
||||
fil_crypt_threads_signal();
|
||||
|
||||
if (!table->space) {
|
||||
/* We failed to find a sensible tablespace file */
|
||||
table->file_unreadable = true;
|
||||
|
||||
@@ -57,7 +57,7 @@ static uint32_t fil_crypt_settings_version;
|
||||
uint srv_n_fil_crypt_threads;
|
||||
|
||||
/** No of key rotation threads started */
|
||||
uint srv_n_fil_crypt_threads_started;
|
||||
Atomic_relaxed<uint> srv_n_fil_crypt_threads_started;
|
||||
|
||||
/** At this age or older a space/page will be rotated */
|
||||
uint srv_fil_crypt_rotate_key_age;
|
||||
@@ -104,7 +104,7 @@ static mysql_mutex_t crypt_stat_mutex;
|
||||
/** Wake up the encryption threads */
|
||||
void fil_crypt_threads_signal(bool broadcast)
|
||||
{
|
||||
if (!fil_crypt_threads_inited)
|
||||
if (!fil_crypt_threads_inited || !srv_n_fil_crypt_threads_started)
|
||||
return;
|
||||
mysql_mutex_lock(&fil_crypt_threads_mutex);
|
||||
if (broadcast)
|
||||
@@ -2185,7 +2185,7 @@ static void fil_crypt_thread()
|
||||
pfs_register_thread(page_encrypt_thread_key);
|
||||
#endif /* UNIV_PFS_THREAD */
|
||||
mysql_mutex_lock(&fil_crypt_threads_mutex);
|
||||
rotate_thread_t thr(srv_n_fil_crypt_threads_started++);
|
||||
rotate_thread_t thr(srv_n_fil_crypt_threads_started.fetch_add(1));
|
||||
pthread_cond_broadcast(&fil_crypt_cond);
|
||||
|
||||
if (!thr.should_shutdown()) {
|
||||
@@ -2319,7 +2319,7 @@ restart_iteration:
|
||||
}
|
||||
}
|
||||
func_exit:
|
||||
srv_n_fil_crypt_threads_started--;
|
||||
srv_n_fil_crypt_threads_started.fetch_sub(1);
|
||||
pthread_cond_broadcast(&fil_crypt_cond);
|
||||
mysql_mutex_unlock(&fil_crypt_threads_mutex);
|
||||
|
||||
|
||||
@@ -2024,7 +2024,6 @@ fil_ibd_create(
|
||||
fil_node_t* node = space->add(path, OS_FILE_CLOSED, size, false, true);
|
||||
space->set_stopped();
|
||||
mysql_mutex_unlock(&fil_system.mutex);
|
||||
fil_crypt_threads_signal();
|
||||
|
||||
buf_block_t *header[2];
|
||||
{
|
||||
@@ -2134,6 +2133,7 @@ func_exit:
|
||||
space->release();
|
||||
}
|
||||
mysql_mutex_unlock(&fil_system.mutex);
|
||||
fil_crypt_threads_signal();
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
|
||||
@@ -210,7 +210,7 @@ extern uint32_t srv_undo_tablespaces_active;
|
||||
extern unsigned long long srv_max_undo_log_size;
|
||||
|
||||
extern uint srv_n_fil_crypt_threads;
|
||||
extern uint srv_n_fil_crypt_threads_started;
|
||||
extern Atomic_relaxed<uint> srv_n_fil_crypt_threads_started;
|
||||
|
||||
/** Enable or Disable Truncate of UNDO tablespace. */
|
||||
extern my_bool srv_undo_log_truncate;
|
||||
|
||||
@@ -2317,7 +2317,6 @@ row_import_cleanup(row_prebuilt_t* prebuilt,
|
||||
prebuilt->trx->op_info = "";
|
||||
|
||||
DBUG_EXECUTE_IF("ib_import_before_checkpoint_crash", DBUG_SUICIDE(););
|
||||
fil_crypt_threads_signal();
|
||||
|
||||
if (err != DB_SUCCESS
|
||||
|| !dict_table_get_first_index(table)->is_gen_clust()) {
|
||||
|
||||
Reference in New Issue
Block a user