summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@mariadb.org>2017-12-12 22:53:38 +0400
committerSergey Vojtovich <svoj@mariadb.org>2017-12-13 12:46:33 +0400
commit159a6c2e608d04732cb678c7691345b9b1dc69b1 (patch)
tree1e3f015f20b5b84e291ad134e3c8dbb16af31dfc
parent751e0f6b1ebeddb4faa3437daa399103bb212ac2 (diff)
downloadmariadb-git-159a6c2e608d04732cb678c7691345b9b1dc69b1.tar.gz
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'
-rw-r--r--mysql-test/r/status.result17
-rw-r--r--mysql-test/t/status.test10
-rw-r--r--sql/event_scheduler.cc2
-rw-r--r--sql/mysqld.cc5
-rw-r--r--sql/mysqld.h11
-rw-r--r--sql/sql_class.cc6
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_parse.cc7
-rw-r--r--sql/sql_plugin.h3
-rw-r--r--sql/sql_show.cc5
10 files changed, 44 insertions, 23 deletions
diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result
index 9b82c7896cb..18cde57b295 100644
--- a/mysql-test/r/status.result
+++ b/mysql-test/r/status.result
@@ -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;
diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test
index bff45fca583..92fba9ab0a6 100644
--- a/mysql-test/t/status.test
+++ b/mysql-test/t/status.test
@@ -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;
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index 1572fedff49..d0a2405526a 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -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 @@ end:
event->name.str));
delete event;
- dec_thread_running();
deinit_event_thread(thd);
DBUG_VOID_RETURN;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index f49365c9e9b..1f679ee6e9e 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -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;
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 7a430d4f00b..1ca193310cc 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -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()
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 9d30ad65be4..30b53807578 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -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;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 20318d55da1..46dea27dc7a 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -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;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7a4c7ca4c56..9ce6c6b8787 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -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 @@ com_multi_end:
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));
diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h
index f100e8a232a..5903029cd68 100644
--- a/sql/sql_plugin.h
+++ b/sql/sql_plugin.h
@@ -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
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index befffb55e2e..c374425f74a 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -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);