MXS-1360 Add 'thread_stack_size' configuration value
Using the 'thread_stack_size' configuration value, the stack size of the worker threads can be adjusted.
This commit is contained in:
@ -150,6 +150,16 @@ Additional threads will be created to execute other internal services within
|
|||||||
MariaDB MaxScale. This setting is used to configure the number of threads that
|
MariaDB MaxScale. This setting is used to configure the number of threads that
|
||||||
will be used to manage the user connections.
|
will be used to manage the user connections.
|
||||||
|
|
||||||
|
#### `thread_stack_size`
|
||||||
|
|
||||||
|
This parameter controls the stack size of the worker threads. The default value
|
||||||
|
is 0, which means that the pthread default will be used. The size can be specified
|
||||||
|
as explained in detail [here](#sizes).
|
||||||
|
|
||||||
|
```
|
||||||
|
thread_stack_size=5Mi
|
||||||
|
```
|
||||||
|
|
||||||
#### `auth_connect_timeout`
|
#### `auth_connect_timeout`
|
||||||
|
|
||||||
The connection timeout in seconds for the MySQL connections to the backend
|
The connection timeout in seconds for the MySQL connections to the backend
|
||||||
|
|||||||
@ -152,6 +152,7 @@ extern const char CN_SSL_KEY[];
|
|||||||
extern const char CN_SSL_VERSION[];
|
extern const char CN_SSL_VERSION[];
|
||||||
extern const char CN_STRIP_DB_ESC[];
|
extern const char CN_STRIP_DB_ESC[];
|
||||||
extern const char CN_THREADS[];
|
extern const char CN_THREADS[];
|
||||||
|
extern const char CN_THREAD_STACK_SIZE[];
|
||||||
extern const char CN_TYPE[];
|
extern const char CN_TYPE[];
|
||||||
extern const char CN_UNIX[];
|
extern const char CN_UNIX[];
|
||||||
extern const char CN_USER[];
|
extern const char CN_USER[];
|
||||||
@ -189,6 +190,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
bool config_check; /**< Only check config */
|
bool config_check; /**< Only check config */
|
||||||
int n_threads; /**< Number of polling threads */
|
int n_threads; /**< Number of polling threads */
|
||||||
|
size_t thread_stack_size; /**< The stack size of each worker thread */
|
||||||
char *version_string; /**< The version string of embedded db library */
|
char *version_string; /**< The version string of embedded db library */
|
||||||
char release_string[RELEASE_STR_LENGTH]; /**< The release name string of the system */
|
char release_string[RELEASE_STR_LENGTH]; /**< The release name string of the system */
|
||||||
char sysname[SYSNAME_LEN]; /**< The OS name of the system */
|
char sysname[SYSNAME_LEN]; /**< The OS name of the system */
|
||||||
@ -446,6 +448,14 @@ int config_truth_value(const char *value);
|
|||||||
*/
|
*/
|
||||||
int config_threadcount(void);
|
int config_threadcount(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get thread stack size
|
||||||
|
*
|
||||||
|
* @return The configured worker thread stack size.
|
||||||
|
*/
|
||||||
|
size_t config_thread_stack_size(void);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get number of non-blocking polls
|
* @brief Get number of non-blocking polls
|
||||||
*
|
*
|
||||||
|
|||||||
@ -132,6 +132,7 @@ const char CN_SSL_KEY[] = "ssl_key";
|
|||||||
const char CN_SSL_VERSION[] = "ssl_version";
|
const char CN_SSL_VERSION[] = "ssl_version";
|
||||||
const char CN_STRIP_DB_ESC[] = "strip_db_esc";
|
const char CN_STRIP_DB_ESC[] = "strip_db_esc";
|
||||||
const char CN_THREADS[] = "threads";
|
const char CN_THREADS[] = "threads";
|
||||||
|
const char CN_THREAD_STACK_SIZE[] = "thread_stack_size";
|
||||||
const char CN_TYPE[] = "type";
|
const char CN_TYPE[] = "type";
|
||||||
const char CN_UNIX[] = "unix";
|
const char CN_UNIX[] = "unix";
|
||||||
const char CN_USER[] = "user";
|
const char CN_USER[] = "user";
|
||||||
@ -163,6 +164,7 @@ static void remove_first_last_char(char* value);
|
|||||||
static bool test_regex_string_validity(const char* regex_string, const char* key);
|
static bool test_regex_string_validity(const char* regex_string, const char* key);
|
||||||
static pcre2_code* compile_regex_string(const char* regex_string, bool jit_enabled,
|
static pcre2_code* compile_regex_string(const char* regex_string, bool jit_enabled,
|
||||||
uint32_t options, uint32_t* output_ovector_size);
|
uint32_t options, uint32_t* output_ovector_size);
|
||||||
|
static uint64_t get_suffixed_size(const char* value);
|
||||||
|
|
||||||
int config_get_ifaddr(unsigned char *output);
|
int config_get_ifaddr(unsigned char *output);
|
||||||
static int config_get_release_string(char* release);
|
static int config_get_release_string(char* release);
|
||||||
@ -1068,64 +1070,8 @@ int config_get_integer(const MXS_CONFIG_PARAMETER *params, const char *key)
|
|||||||
uint64_t config_get_size(const MXS_CONFIG_PARAMETER *params, const char *key)
|
uint64_t config_get_size(const MXS_CONFIG_PARAMETER *params, const char *key)
|
||||||
{
|
{
|
||||||
const char *value = config_get_value_string(params, key);
|
const char *value = config_get_value_string(params, key);
|
||||||
char *end;
|
|
||||||
uint64_t size = strtoll(value, &end, 10);
|
|
||||||
|
|
||||||
switch (*end)
|
return get_suffixed_size(value);
|
||||||
{
|
|
||||||
case 'T':
|
|
||||||
case 't':
|
|
||||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
|
||||||
{
|
|
||||||
size *= 1024ULL * 1024ULL * 1024ULL * 1024ULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size *= 1000ULL * 1000ULL * 1000ULL * 1000ULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'G':
|
|
||||||
case 'g':
|
|
||||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
|
||||||
{
|
|
||||||
size *= 1024ULL * 1024ULL * 1024ULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size *= 1000ULL * 1000ULL * 1000ULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'M':
|
|
||||||
case 'm':
|
|
||||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
|
||||||
{
|
|
||||||
size *= 1024ULL * 1024ULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size *= 1000ULL * 1000ULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'K':
|
|
||||||
case 'k':
|
|
||||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
|
||||||
{
|
|
||||||
size *= 1024ULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size *= 1000ULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* config_get_string(const MXS_CONFIG_PARAMETER *params, const char *key)
|
const char* config_get_string(const MXS_CONFIG_PARAMETER *params, const char *key)
|
||||||
@ -1334,6 +1280,11 @@ config_threadcount()
|
|||||||
return gateway.n_threads;
|
return gateway.n_threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t config_thread_stack_size()
|
||||||
|
{
|
||||||
|
return gateway.thread_stack_size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of non-blocking polls to be done before a blocking poll
|
* Return the number of non-blocking polls to be done before a blocking poll
|
||||||
* is issued.
|
* is issued.
|
||||||
@ -1424,6 +1375,10 @@ handle_global_item(const char *name, const char *value)
|
|||||||
gateway.n_threads = MXS_MAX_THREADS;
|
gateway.n_threads = MXS_MAX_THREADS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strcmp(name, CN_THREAD_STACK_SIZE) == 0)
|
||||||
|
{
|
||||||
|
gateway.thread_stack_size = get_suffixed_size(value);
|
||||||
|
}
|
||||||
else if (strcmp(name, CN_NON_BLOCKING_POLLS) == 0)
|
else if (strcmp(name, CN_NON_BLOCKING_POLLS) == 0)
|
||||||
{
|
{
|
||||||
gateway.n_nbpoll = atoi(value);
|
gateway.n_nbpoll = atoi(value);
|
||||||
@ -1799,6 +1754,17 @@ global_defaults()
|
|||||||
gateway.admin_ssl_cert[0] = '\0';
|
gateway.admin_ssl_cert[0] = '\0';
|
||||||
gateway.admin_ssl_ca_cert[0] = '\0';
|
gateway.admin_ssl_ca_cert[0] = '\0';
|
||||||
|
|
||||||
|
gateway.thread_stack_size = 0;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
if (pthread_attr_init(&attr) == 0)
|
||||||
|
{
|
||||||
|
size_t thread_stack_size;
|
||||||
|
if (pthread_attr_getstacksize(&attr, &thread_stack_size) == 0)
|
||||||
|
{
|
||||||
|
gateway.thread_stack_size = thread_stack_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (version_string != NULL)
|
if (version_string != NULL)
|
||||||
{
|
{
|
||||||
gateway.version_string = MXS_STRDUP_A(version_string);
|
gateway.version_string = MXS_STRDUP_A(version_string);
|
||||||
@ -3890,6 +3856,7 @@ json_t* config_maxscale_to_json(const char* host)
|
|||||||
json_object_set_new(param, "execdir", json_string(get_execdir()));
|
json_object_set_new(param, "execdir", json_string(get_execdir()));
|
||||||
json_object_set_new(param, "connector_plugindir", json_string(get_connector_plugindir()));
|
json_object_set_new(param, "connector_plugindir", json_string(get_connector_plugindir()));
|
||||||
json_object_set_new(param, CN_THREADS, json_integer(config_threadcount()));
|
json_object_set_new(param, CN_THREADS, json_integer(config_threadcount()));
|
||||||
|
json_object_set_new(param, CN_THREAD_STACK_SIZE, json_integer(config_thread_stack_size()));
|
||||||
|
|
||||||
MXS_CONFIG* cnf = config_get_global_options();
|
MXS_CONFIG* cnf = config_get_global_options();
|
||||||
|
|
||||||
@ -4117,3 +4084,74 @@ static bool test_regex_string_validity(const char* regex_string, const char* key
|
|||||||
pcre2_code_free(code);
|
pcre2_code_free(code);
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string into the corresponding value, interpreting
|
||||||
|
* IEC or SI prefixes used as suffixes appropriately.
|
||||||
|
*
|
||||||
|
* @param value A numerical string, possibly suffixed by a IEC
|
||||||
|
* binary prefix or SI prefix.
|
||||||
|
*
|
||||||
|
* @return The corresponding size.
|
||||||
|
*/
|
||||||
|
static uint64_t get_suffixed_size(const char* value)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
uint64_t size = strtoll(value, &end, 10);
|
||||||
|
|
||||||
|
switch (*end)
|
||||||
|
{
|
||||||
|
case 'T':
|
||||||
|
case 't':
|
||||||
|
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||||
|
{
|
||||||
|
size *= 1024ULL * 1024ULL * 1024ULL * 1024ULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size *= 1000ULL * 1000ULL * 1000ULL * 1000ULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'G':
|
||||||
|
case 'g':
|
||||||
|
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||||
|
{
|
||||||
|
size *= 1024ULL * 1024ULL * 1024ULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size *= 1000ULL * 1000ULL * 1000ULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
case 'm':
|
||||||
|
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||||
|
{
|
||||||
|
size *= 1024ULL * 1024ULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size *= 1000ULL * 1000ULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'K':
|
||||||
|
case 'k':
|
||||||
|
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||||
|
{
|
||||||
|
size *= 1024ULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size *= 1000ULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|||||||
@ -1293,6 +1293,7 @@ int main(int argc, char **argv)
|
|||||||
int ini_rval;
|
int ini_rval;
|
||||||
intptr_t thread_id;
|
intptr_t thread_id;
|
||||||
int n_threads; /*< number of epoll listener threads */
|
int n_threads; /*< number of epoll listener threads */
|
||||||
|
size_t thread_stack_size;
|
||||||
int n_services;
|
int n_services;
|
||||||
int eno = 0; /*< local variable for errno */
|
int eno = 0; /*< local variable for errno */
|
||||||
int opt;
|
int opt;
|
||||||
@ -2032,12 +2033,13 @@ int main(int argc, char **argv)
|
|||||||
/*<
|
/*<
|
||||||
* Start workers. We start from 1, worker 0 will be running in the main thread.
|
* Start workers. We start from 1, worker 0 will be running in the main thread.
|
||||||
*/
|
*/
|
||||||
|
thread_stack_size = config_thread_stack_size();
|
||||||
for (i = 1; i < n_threads; i++)
|
for (i = 1; i < n_threads; i++)
|
||||||
{
|
{
|
||||||
worker = Worker::get(i);
|
worker = Worker::get(i);
|
||||||
ss_dassert(worker);
|
ss_dassert(worker);
|
||||||
|
|
||||||
if (!worker->start())
|
if (!worker->start(thread_stack_size))
|
||||||
{
|
{
|
||||||
const char* logerr = "Failed to start worker thread.";
|
const char* logerr = "Failed to start worker thread.";
|
||||||
print_log_n_stderr(true, true, logerr, logerr, 0);
|
print_log_n_stderr(true, true, logerr, logerr, 0);
|
||||||
@ -2061,7 +2063,10 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MXS_NOTICE("MaxScale started with %d server threads.", config_threadcount());
|
|
||||||
|
MXS_NOTICE("MaxScale started with %d worker threads, each with a stack size of %lu bytes.",
|
||||||
|
n_threads, thread_stack_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Successful start, notify the parent process that it can exit.
|
* Successful start, notify the parent process that it can exit.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -241,9 +241,12 @@ public:
|
|||||||
* This function will start a new thread, in which the `run`
|
* This function will start a new thread, in which the `run`
|
||||||
* function will be executed.
|
* function will be executed.
|
||||||
*
|
*
|
||||||
|
* @param stack_size The stack size of the new thread. A value of 0 means
|
||||||
|
* that the pthread default should be used.
|
||||||
|
*
|
||||||
* @return True if the thread could be started, false otherwise.
|
* @return True if the thread could be started, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool start();
|
bool start(size_t stack_size = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits for the worker to finish.
|
* Waits for the worker to finish.
|
||||||
|
|||||||
@ -843,11 +843,11 @@ void Worker::run()
|
|||||||
MXS_NOTICE("Worker %d has shut down.", m_id);
|
MXS_NOTICE("Worker %d has shut down.", m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Worker::start()
|
bool Worker::start(size_t stack_size)
|
||||||
{
|
{
|
||||||
m_started = true;
|
m_started = true;
|
||||||
|
|
||||||
if (!thread_start(&m_thread, &Worker::thread_main, this, 0))
|
if (!thread_start(&m_thread, &Worker::thread_main, this, stack_size))
|
||||||
{
|
{
|
||||||
m_started = false;
|
m_started = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user