1
0
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:
Thirunarayanan Balathandayuthapani
2026-10-15 19:46:04 +05:30
parent d9a1aa9a06
commit 7d81395cca
5 changed files with 14 additions and 7 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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()) {