diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 01883215981..3ae56d0cd08 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1740,6 +1740,17 @@ struct System_status_var *get_thd_status_var(THD *thd, bool *aggregated) { return &thd->status_var; } +void aggregate_status_var(std::function callback, + unsigned long tid) { + Find_thd_with_id find_thd_with_id(tid); + THD *thd = Global_THD_manager::get_instance()->find_thd(&find_thd_with_id); + if (thd != nullptr) { + callback(thd); + mysql_mutex_assert_owner(&thd->LOCK_thd_data); + mysql_mutex_unlock(&thd->LOCK_thd_data); + } +} + static void option_error_reporter(enum loglevel level, uint ecode, ...) { va_list args; va_start(args, ecode); diff --git a/sql/mysqld.h b/sql/mysqld.h index 9ab6db8ac64..ff7b2753735 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -131,6 +132,7 @@ bool is_secure_file_path(const char *path); ulong sql_rnd_with_mutex(); struct System_status_var *get_thd_status_var(THD *thd, bool *aggregated); +void aggregate_status_var(std::function cb, unsigned long tid); bool update_Sys_slow_log_path(const char *const log_file_name, const bool need_lock); diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc index f2eedcb90e2..187ea228161 100644 --- a/storage/perfschema/pfs_instr.cc +++ b/storage/perfschema/pfs_instr.cc @@ -35,6 +35,7 @@ #include "my_psi_config.h" #include "my_sys.h" #include "sql/mysqld.h" // get_thd_status_var +#include "sql/mysqld_thd_manager.h" #include "storage/perfschema/pfs.h" #include "storage/perfschema/pfs_account.h" #include "storage/perfschema/pfs_buffer_container.h" @@ -1781,32 +1782,36 @@ void aggregate_all_memory(bool alive, PFS_memory_shared_stat *from_array, void aggregate_thread_status(PFS_thread *thread, PFS_account *safe_account, PFS_user *safe_user, PFS_host *safe_host) { THD *thd = thread->m_thd; - bool aggregated = false; + unsigned long tid = thread->m_processlist_id; if (thd == nullptr) { return; } - System_status_var *status_var = get_thd_status_var(thd, &aggregated); + auto fn = [&safe_account, &safe_user, &safe_host](THD *thd) { + bool aggregated = false; + System_status_var *status_var = get_thd_status_var(thd, &aggregated); - if (unlikely(aggregated)) { - /* THD is being closed, status has already been aggregated. */ - return; - } + if (unlikely(aggregated)) { + /* THD is being closed, status has already been aggregated. */ + return; + } - if (likely(safe_account != nullptr)) { - safe_account->aggregate_status_stats(status_var); - return; - } + if (likely(safe_account != nullptr)) { + safe_account->aggregate_status_stats(status_var); + return; + } - if (safe_user != nullptr) { - safe_user->aggregate_status_stats(status_var); - } + if (safe_user != nullptr) { + safe_user->aggregate_status_stats(status_var); + } - if (safe_host != nullptr) { - safe_host->aggregate_status_stats(status_var); - } + if (safe_host != nullptr) { + safe_host->aggregate_status_stats(status_var); + } + }; + aggregate_status_var(fn, tid); return; } diff --git a/storage/perfschema/unittest/pfs_server_stubs.cc b/storage/perfschema/unittest/pfs_server_stubs.cc index db2044ef070..55bff0faabc 100644 --- a/storage/perfschema/unittest/pfs_server_stubs.cc +++ b/storage/perfschema/unittest/pfs_server_stubs.cc @@ -50,6 +50,8 @@ struct System_status_var *get_thd_status_var(THD *, bool *) { return nullptr; } +void aggregate_status_var(std::function, unsigned long) {} + unsigned int mysql_errno_to_sqlstate_index(unsigned int) { return 0; } SERVICE_TYPE(registry) * mysql_plugin_registry_acquire() { return nullptr; }