Commit fd9f1638 authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-5205 - MariaDB does not start if more than 128 cpu's are available

- thread_pool_size command line option upper limit increased to 100 000
  (same as for max_connections)
- thread_pool_size system variable upper limit is maximum of 128 or
  the value given at command line
- thread groups are now allocated dynamically

Different limit for command line option and system variable was done to
avoid additional mutex for all_groups and threadpool_max_size.
parent 52dea410
SELECT @@global.thread_pool_size;
@@global.thread_pool_size
200
SET @@global.thread_pool_size=150;
SET @@global.thread_pool_size=200;
SET @@global.thread_pool_size=201;
Warnings:
Warning 1292 Truncated incorrect thread_pool_size value: '201'
SELECT @@global.thread_pool_size;
@@global.thread_pool_size
200
--loose-thread-handling=pool-of-threads
# uint global
--source include/not_windows.inc
--source include/not_embedded.inc
--source include/have_pool_of_threads.inc
SET @start_global_value = @@global.thread_pool_size;
#
......
--loose-thread-handling=pool-of-threads --loose-thread-pool-size=200
--source include/not_windows.inc
--source include/not_embedded.inc
--source include/have_pool_of_threads.inc
SELECT @@global.thread_pool_size;
# Set lower value
SET @@global.thread_pool_size=150;
# Set original value
SET @@global.thread_pool_size=200;
# Try higher value
SET @@global.thread_pool_size=201;
SELECT @@global.thread_pool_size;
......@@ -75,6 +75,11 @@ class I_P_List : public C, public I
*/
public:
I_P_List() : I(&m_first), m_first(NULL) {};
/*
empty() is used in many places in the code instead of a constructor, to
initialize a bzero-ed I_P_List instance.
*/
inline void empty() { m_first= NULL; C::reset(); I::set_last(&m_first); }
inline bool is_empty() const { return (m_first == NULL); }
inline void push_front(T* a)
......
......@@ -2298,6 +2298,18 @@ static bool fix_tp_min_threads(sys_var *, THD *, enum_var_type)
#ifndef _WIN32
static bool check_threadpool_size(sys_var *self, THD *thd, set_var *var)
{
ulonglong v= var->save_result.ulonglong_value;
if (v > threadpool_max_size)
{
var->save_result.ulonglong_value= threadpool_max_size;
return throw_bounds_warning(thd, self->name.str, true, true, v);
}
return false;
}
static bool fix_threadpool_size(sys_var*, THD*, enum_var_type)
{
tp_set_threadpool_size(threadpool_size);
......@@ -2342,7 +2354,7 @@ static Sys_var_uint Sys_threadpool_size(
"executing threads (threads in a waiting state do not count as executing).",
GLOBAL_VAR(threadpool_size), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(1, MAX_THREAD_GROUPS), DEFAULT(my_getncpus()), BLOCK_SIZE(1),
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_threadpool_size),
ON_UPDATE(fix_threadpool_size)
);
static Sys_var_uint Sys_threadpool_stall_limit(
......
......@@ -13,12 +13,13 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MAX_THREAD_GROUPS 128
#define MAX_THREAD_GROUPS 100000
/* Threadpool parameters */
extern uint threadpool_min_threads; /* Minimum threads in pool */
extern uint threadpool_idle_timeout; /* Shutdown idle worker threads after this timeout */
extern uint threadpool_size; /* Number of parallel executing threads */
extern uint threadpool_max_size;
extern uint threadpool_stall_limit; /* time interval in 10 ms units for stall checks*/
extern uint threadpool_max_threads; /* Maximum threads in pool */
extern uint threadpool_oversubscribe; /* Maximum active threads in group */
......
......@@ -30,6 +30,7 @@
uint threadpool_min_threads;
uint threadpool_idle_timeout;
uint threadpool_size;
uint threadpool_max_size;
uint threadpool_stall_limit;
uint threadpool_max_threads;
uint threadpool_oversubscribe;
......
......@@ -147,7 +147,7 @@ struct thread_group_t
} MY_ALIGNED(512);
static thread_group_t all_groups[MAX_THREAD_GROUPS];
static thread_group_t *all_groups;
static uint group_count;
/**
......@@ -517,7 +517,7 @@ static void* timer_thread(void *param)
timer->current_microtime= microsecond_interval_timer();
/* Check stalls in thread groups */
for(i=0; i< array_elements(all_groups);i++)
for (i= 0; i < threadpool_max_size; i++)
{
if(all_groups[i].connection_count)
check_stall(&all_groups[i]);
......@@ -907,6 +907,7 @@ int thread_group_init(thread_group_t *thread_group, pthread_attr_t* thread_attr)
thread_group->pollfd= -1;
thread_group->shutdown_pipe[0]= -1;
thread_group->shutdown_pipe[1]= -1;
thread_group->queue.empty();
DBUG_RETURN(0);
}
......@@ -1510,10 +1511,18 @@ static void *worker_main(void *param)
bool tp_init()
{
DBUG_ENTER("tp_init");
threadpool_max_size= max(threadpool_size, 128);
all_groups= (thread_group_t *)
my_malloc(sizeof(thread_group_t) * threadpool_max_size, MYF(MY_WME|MY_ZEROFILL));
if (!all_groups)
{
threadpool_max_size= 0;
DBUG_RETURN(1);
}
threadpool_started= true;
scheduler_init();
for(uint i=0; i < array_elements(all_groups); i++)
for (uint i= 0; i < threadpool_max_size; i++)
{
thread_group_init(&all_groups[i], get_connection_attrib());
}
......@@ -1542,10 +1551,11 @@ void tp_end()
DBUG_VOID_RETURN;
stop_timer(&pool_timer);
for(uint i=0; i< array_elements(all_groups); i++)
for (uint i= 0; i < threadpool_max_size; i++)
{
thread_group_close(&all_groups[i]);
}
my_free(all_groups);
threadpool_started= false;
DBUG_VOID_RETURN;
}
......@@ -1604,9 +1614,7 @@ void tp_set_threadpool_stall_limit(uint limit)
int tp_get_idle_thread_count()
{
int sum=0;
for(uint i= 0;
i< array_elements(all_groups) && (all_groups[i].pollfd >= 0);
i++)
for (uint i= 0; i < threadpool_max_size && all_groups[i].pollfd >= 0; i++)
{
sum+= (all_groups[i].thread_count - all_groups[i].active_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