diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index a43bd09dde4..94d4f7a0be1 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -356,6 +356,17 @@ FLUSH STATUS; # This should not report 0 as FLUSH STATUS is called. TIMESTAMPDIFF(SECOND,'DTVALUE','DTVALUE') <> 0 1 +# +# BUG#99412 - Threads_running becomes scalability bottleneck +# +# Session status for Threads_running is currently always 1. +SHOW STATUS LIKE 'Threads_running'; +Variable_name Value +Threads_running 1 +FLUSH STATUS; +SHOW STATUS LIKE 'Threads_running'; +Variable_name Value +Threads_running 1 set @@global.concurrent_insert= @old_concurrent_insert; SET GLOBAL log_output = @old_log_output; # diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index 69dd0e60cb2..5af24df7922 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -475,6 +475,15 @@ let $time_4=`SELECT VARIABLE_VALUE FROM performance_schema.session_status WHERE disconnect con4; +--echo # +--echo # BUG#99412 - Threads_running becomes scalability bottleneck +--echo # +--echo # Session status for Threads_running is currently always 1. +--connection default +SHOW STATUS LIKE 'Threads_running'; +FLUSH STATUS; +SHOW STATUS LIKE 'Threads_running'; + # Restore global concurrent_insert value. Keep in the end of the test file. --connection default set @@global.concurrent_insert= @old_concurrent_insert; diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index f7182867f58..b3c52c7d17a 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -170,7 +170,6 @@ bool post_init_event_thread(THD *thd) { Global_THD_manager *thd_manager = Global_THD_manager::get_instance(); thd_manager->add_thd(thd); - thd_manager->inc_thread_running(); return false; } @@ -190,7 +189,6 @@ void deinit_event_thread(THD *thd) { DBUG_PRINT("exit", ("Event thread finishing")); thd->release_resources(); thd_manager->remove_thd(thd); - thd_manager->dec_thread_running(); delete thd; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 85b93bbf97e..6e55295c629 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8239,15 +8239,6 @@ static int show_max_used_connections_time(THD *thd, SHOW_VAR *var, char *buff) { return 0; } -static int show_num_thread_running(THD *, SHOW_VAR *var, char *buff) { - var->type = SHOW_LONGLONG; - var->value = buff; - long long *value = reinterpret_cast(buff); - *value = static_cast( - Global_THD_manager::get_instance()->get_num_thread_running()); - return 0; -} - static int show_num_thread_created(THD *, SHOW_VAR *var, char *buff) { var->type = SHOW_LONG; var->value = buff; @@ -8940,8 +8931,8 @@ SHOW_VAR status_vars[] = { SHOW_INT, SHOW_SCOPE_GLOBAL}, {"Threads_created", (char *)&show_num_thread_created, SHOW_FUNC, SHOW_SCOPE_GLOBAL}, - {"Threads_running", (char *)&show_num_thread_running, SHOW_FUNC, - SHOW_SCOPE_GLOBAL}, + {"Threads_running", (char *)offsetof(System_status_var, threads_running), + SHOW_LONGLONG_STATUS, SHOW_SCOPE_GLOBAL}, {"Uptime", (char *)&show_starttime, SHOW_FUNC, SHOW_SCOPE_GLOBAL}, #ifdef ENABLED_PROFILING {"Uptime_since_flush_status", (char *)&show_flushstatustime, SHOW_FUNC, diff --git a/sql/mysqld_thd_manager.cc b/sql/mysqld_thd_manager.cc index a477953b6cc..21f16c26e4b 100644 --- a/sql/mysqld_thd_manager.cc +++ b/sql/mysqld_thd_manager.cc @@ -133,7 +133,6 @@ Global_THD_manager::Global_THD_manager() THD_array(PSI_INSTRUMENT_ME), }, thread_ids(PSI_INSTRUMENT_ME), - atomic_num_thread_running(0), atomic_thread_created(0), thread_id_counter(reserved_thread_id + 1), unit_test(false) diff --git a/sql/mysqld_thd_manager.h b/sql/mysqld_thd_manager.h index bf04e6b623f..f5fe17711e9 100644 --- a/sql/mysqld_thd_manager.h +++ b/sql/mysqld_thd_manager.h @@ -147,22 +147,6 @@ class Global_THD_manager { */ void remove_thd(THD *thd); - /** - Retrieves thread running statistic variable. - @return int Returns the total number of threads currently running - */ - int get_num_thread_running() const { return atomic_num_thread_running; } - - /** - Increments thread running statistic variable. - */ - void inc_thread_running() { atomic_num_thread_running++; } - - /** - Decrements thread running statistic variable. - */ - void dec_thread_running() { atomic_num_thread_running--; } - /** Retrieves thread created statistic variable. @return ulonglong Returns the total number of threads created @@ -267,9 +251,6 @@ class Global_THD_manager { // Mutex protecting thread_ids mysql_mutex_t LOCK_thread_ids; - // Count of active threads which are running queries in the system. - std::atomic atomic_num_thread_running; - // Cumulative number of threads created by mysqld daemon. std::atomic atomic_thread_created; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f709b7afdbd..48287780f54 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -810,7 +810,7 @@ void THD::init(void) { update_charset(); reset_current_stmt_binlog_format_row(); reset_binlog_local_stmt_filter(); - memset(&status_var, 0, sizeof(status_var)); + reset_system_status_vars(&status_var); binlog_row_event_extra_data = nullptr; if (variables.sql_log_bin) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d27e36bc9b1..e235ba43eac 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1547,7 +1547,6 @@ bool dispatch_command(THD *thd, const COM_DATA *com_data, } thd->set_query_id(next_query_id()); thd->reset_rewritten_query(); - thd_manager->inc_thread_running(); if (!(server_command_flags[command] & CF_SKIP_QUESTIONS)) thd->status_var.questions++; @@ -2195,8 +2194,6 @@ done: /* Prevent rewritten query from getting "stuck" in SHOW PROCESSLIST. */ thd->reset_rewritten_query(); - thd_manager->dec_thread_running(); - /* Freeing the memroot will leave the THD::work_part_info invalid. */ thd->work_part_info = nullptr; diff --git a/sql/system_variables.cc b/sql/system_variables.cc index 782461c75b2..92f87c72cf1 100644 --- a/sql/system_variables.cc +++ b/sql/system_variables.cc @@ -93,4 +93,5 @@ void add_diff_to_status(System_status_var *to_var, System_status_var *from_var, */ void reset_system_status_vars(System_status_var *status_vars) { memset(status_vars, 0, sizeof(*status_vars)); + status_vars->threads_running = 1; } diff --git a/sql/system_variables.h b/sql/system_variables.h index 11d4732dfa6..2d7a05f586e 100644 --- a/sql/system_variables.h +++ b/sql/system_variables.h @@ -488,6 +488,8 @@ struct System_status_var { */ double last_query_cost; ulonglong last_query_partial_plans; + + ulonglong threads_running; }; /* diff --git a/storage/perfschema/pfs_visitor.cc b/storage/perfschema/pfs_visitor.cc index 66e120035b2..c4f1f959b2b 100644 --- a/storage/perfschema/pfs_visitor.cc +++ b/storage/perfschema/pfs_visitor.cc @@ -1196,6 +1196,12 @@ void PFS_connection_status_visitor::visit_thread(PFS_thread *) {} void PFS_connection_status_visitor::visit_THD(THD *thd) { add_to_status(m_status_vars, &thd->status_var); + if ((thd->get_command() != COM_SLEEP && + thd->system_thread == NON_SYSTEM_THREAD) || + thd->system_thread == SYSTEM_THREAD_EVENT_SCHEDULER || + thd->system_thread == SYSTEM_THREAD_EVENT_WORKER) { + m_status_vars->threads_running++; + } } PFS_instance_wait_visitor::PFS_instance_wait_visitor() {} diff --git a/unittest/gunit/thd_manager-t.cc b/unittest/gunit/thd_manager-t.cc index 22e947c6eaf..689d808d31a 100644 --- a/unittest/gunit/thd_manager-t.cc +++ b/unittest/gunit/thd_manager-t.cc @@ -82,14 +82,6 @@ TEST_F(ThreadManagerTest, AddRemoveTHDWithGuard) { EXPECT_EQ(0U, thd_manager->get_thd_count()); } -TEST_F(ThreadManagerTest, IncDecThreadRunning) { - EXPECT_EQ(0, thd_manager->get_num_thread_running()); - thd_manager->inc_thread_running(); - EXPECT_EQ(1, thd_manager->get_num_thread_running()); - thd_manager->dec_thread_running(); - EXPECT_EQ(0, thd_manager->get_num_thread_running()); -} - TEST_F(ThreadManagerTest, IncThreadCreated) { EXPECT_EQ(0U, thd_manager->get_num_thread_created()); thd_manager->inc_thread_created();