Commit 159a6c2e authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-14505 - Threads_running becomes scalability bottleneck

Instead of updating global counter, calculate Threads_running on the fly.
All threads having command != COM_SLEEP are included.

Behaviour changes:

Previously SHOW STATUS and SHOW GLOBAL STATUS returned the same values
representing global status. Now SHOW STATUS always returns 1 indicating that
current session has 1 thread running.

Previously only threads that were executing dispatch_command() or running events
were accounted by Threads_running. Now it is rough equivalent of
SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE state!='Sleep'
parent 751e0f6b
......@@ -409,6 +409,23 @@ Table_open_cache_overflows 5
FLUSH TABLES;
FLUSH STATUS;
SET @@global.table_open_cache= @old_table_open_cache;
#
# MDEV-14505 - 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
SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='THREADS_RUNNING';
VARIABLE_VALUE
1
FLUSH STATUS;
SHOW STATUS LIKE 'Threads_running';
Variable_name Value
Threads_running 1
SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='THREADS_RUNNING';
VARIABLE_VALUE
1
connection default;
set @@global.concurrent_insert= @old_concurrent_insert;
SET GLOBAL log_output = @old_log_output;
......@@ -420,6 +420,16 @@ while ($i)
enable_query_log;
SET @@global.table_open_cache= @old_table_open_cache;
--echo #
--echo # MDEV-14505 - Threads_running becomes scalability bottleneck
--echo #
--echo # Session status for Threads_running is currently always 1.
SHOW STATUS LIKE 'Threads_running';
SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='THREADS_RUNNING';
FLUSH STATUS;
SHOW STATUS LIKE 'Threads_running';
SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='THREADS_RUNNING';
# Restore global concurrent_insert value. Keep in the end of the test file.
--connection default
set @@global.concurrent_insert= @old_concurrent_insert;
......
......@@ -297,7 +297,6 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
DBUG_ENTER("Event_worker_thread::run");
DBUG_PRINT("info", ("Time is %u, THD: %p", (uint)my_time(0), thd));
inc_thread_running();
if (res)
goto end;
......@@ -326,7 +325,6 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
event->name.str));
delete event;
dec_thread_running();
deinit_event_thread(thd);
DBUG_VOID_RETURN;
......
......@@ -492,7 +492,6 @@ uint protocol_version;
uint lower_case_table_names;
ulong tc_heuristic_recover= 0;
int32 thread_count, service_thread_count;
int32 thread_running;
int32 slave_open_temp_tables;
ulong thread_created;
ulong back_log, connect_timeout, concurrency, server_id;
......@@ -8640,7 +8639,7 @@ SHOW_VAR status_vars[]= {
{"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_NOFLUSH},
{"Threads_connected", (char*) &connection_count, SHOW_INT},
{"Threads_created", (char*) &thread_created, SHOW_LONG_NOFLUSH},
{"Threads_running", (char*) &thread_running, SHOW_INT},
{"Threads_running", (char*) offsetof(STATUS_VAR, threads_running), SHOW_UINT32_STATUS},
{"Transactions_multi_engine", (char*) &transactions_multi_engine, SHOW_LONG},
{"Rpl_transactions_multi_engine", (char*) &rpl_transactions_multi_engine, SHOW_LONG},
{"Transactions_gtid_foreign_engine", (char*) &transactions_gtid_foreign_engine, SHOW_LONG},
......@@ -8817,7 +8816,7 @@ static int mysql_init_variables(void)
kill_in_progress= 0;
cleanup_done= 0;
test_flags= select_errors= dropping_tables= ha_open_options=0;
thread_count= thread_running= kill_cached_threads= wake_thread= 0;
thread_count= kill_cached_threads= wake_thread= 0;
service_thread_count= 0;
slave_open_temp_tables= 0;
cached_thread_count= 0;
......
......@@ -595,7 +595,6 @@ extern mysql_rwlock_t LOCK_system_variables_hash;
extern mysql_cond_t COND_thread_count, COND_start_thread;
extern mysql_cond_t COND_manager;
extern mysql_cond_t COND_slave_background;
extern int32 thread_running;
extern int32 thread_count, service_thread_count;
extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
......@@ -785,16 +784,6 @@ inline void thread_safe_decrement64(int64 *value)
(void) my_atomic_add64_explicit(value, -1, MY_MEMORY_ORDER_RELAXED);
}
inline void inc_thread_running()
{
thread_safe_increment32(&thread_running);
}
inline void dec_thread_running()
{
thread_safe_decrement32(&thread_running);
}
extern void set_server_version(char *buf, size_t size);
#define current_thd _current_thd()
......
......@@ -4207,6 +4207,12 @@ void THD::set_status_var_init()
{
bzero((char*) &status_var, offsetof(STATUS_VAR,
last_cleared_system_status_var));
/*
Session status for Threads_running is always 1. It can only be queried
by thread itself via INFORMATION_SCHEMA.SESSION_STATUS or SHOW [SESSION]
STATUS. And at this point thread is guaranteed to be running.
*/
status_var.threads_running= 1;
}
......
......@@ -828,6 +828,7 @@ typedef struct system_status_var
ulonglong table_open_cache_overflows;
double last_query_cost;
double cpu_time, busy_time;
uint32_t threads_running;
/* Don't initialize */
/* Memory used for thread local storage */
int64 max_local_memory_used;
......
......@@ -1550,9 +1550,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
"<?>")));
bool drop_more_results= 0;
if (!is_com_multi)
inc_thread_running();
/* keep it withing 1 byte */
compile_time_assert(COM_END == 255);
......@@ -2410,10 +2407,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->m_digest= NULL;
if (!is_com_multi)
{
dec_thread_running();
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
}
thd->reset_kill_query(); /* Ensure that killed_errmsg is released */
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
......
......@@ -24,7 +24,8 @@
#define SHOW_always_last SHOW_KEY_CACHE_LONG, \
SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, \
SHOW_HAVE, SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, \
SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS, SHOW_LEX_STRING
SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS, SHOW_UINT32_STATUS, \
SHOW_LEX_STRING
#include "mariadb.h"
#undef SHOW_always_last
......
......@@ -3491,6 +3491,9 @@ const char* get_one_variable(THD *thd,
case SHOW_MY_BOOL:
end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
break;
case SHOW_UINT32_STATUS:
value= ((char *) status_var + (intptr) value);
/* fall through */
case SHOW_UINT:
end= int10_to_str((long) *(uint*) value, buff, 10);
break;
......@@ -3717,6 +3720,8 @@ uint calc_sum_of_all_status(STATUS_VAR *to)
add_to_status(to, &tmp->status_var);
to->local_memory_used+= tmp->status_var.local_memory_used;
}
if (tmp->get_command() != COM_SLEEP)
to->threads_running++;
}
mysql_mutex_unlock(&LOCK_thread_count);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment