Merge branch '2.1' into 2.2

This commit is contained in:
Markus Mäkelä
2017-10-03 14:30:06 +03:00
39 changed files with 685 additions and 417 deletions

View File

@ -110,6 +110,8 @@ const char CN_PORT[] = "port";
const char CN_PROTOCOL[] = "protocol";
const char CN_QUERY_CLASSIFIER[] = "query_classifier";
const char CN_QUERY_CLASSIFIER_ARGS[] = "query_classifier_args";
const char CN_QUERY_RETRIES[] = "query_retries";
const char CN_QUERY_RETRY_TIMEOUT[] = "query_retry_timeout";
const char CN_RELATIONSHIPS[] = "relationships";
const char CN_LINKS[] = "links";
const char CN_REQUIRED[] = "required";
@ -1473,6 +1475,34 @@ handle_global_item(const char *name, const char *value)
"'ORACLE'. Using 'DEFAULT' as default.", value, name);
}
}
else if (strcmp(name, CN_QUERY_RETRIES) == 0)
{
char* endptr;
int intval = strtol(value, &endptr, 0);
if (*endptr == '\0' && intval >= 0)
{
gateway.query_retries = intval;
}
else
{
MXS_ERROR("Invalid timeout value for '%s': %s", CN_QUERY_RETRIES, value);
return 0;
}
}
else if (strcmp(name, CN_QUERY_RETRY_TIMEOUT) == 0)
{
char* endptr;
int intval = strtol(value, &endptr, 0);
if (*endptr == '\0' && intval > 0)
{
gateway.query_retries = intval;
}
else
{
MXS_ERROR("Invalid timeout value for '%s': %s", CN_QUERY_RETRY_TIMEOUT, value);
return 0;
}
}
else if (strcmp(name, CN_LOG_THROTTLING) == 0)
{
if (*value == 0)
@ -1761,6 +1791,8 @@ global_defaults()
gateway.admin_ssl_key[0] = '\0';
gateway.admin_ssl_cert[0] = '\0';
gateway.admin_ssl_ca_cert[0] = '\0';
gateway.query_retries = DEFAULT_QUERY_RETRIES;
gateway.query_retry_timeout = DEFAULT_QUERY_RETRY_TIMEOUT;
gateway.thread_stack_size = 0;
pthread_attr_t attr;

View File

@ -383,33 +383,33 @@ sigfatal_handler(int i)
}
fatal_handling = 1;
MXS_CONFIG* cnf = config_get_global_options();
fprintf(stderr, "\n\nMaxScale " MAXSCALE_VERSION " received fatal signal %d\n", i);
fprintf(stderr, "Fatal: MaxScale " MAXSCALE_VERSION " received fatal signal %d. "
"Attempting backtrace.\n", i);
fprintf(stderr, "Commit ID: %s System name: %s Release string: %s\n\n",
maxscale_commit, cnf->sysname, cnf->release_string);
#ifdef HAVE_GLIBC
MXS_ALERT("Fatal: MaxScale " MAXSCALE_VERSION " received fatal signal %d. Attempting backtrace.", i);
void *addrs[128];
int count = backtrace(addrs, 128);
// First print the stack trace to stderr as malloc is likely broken
backtrace_symbols_fd(addrs, count, STDERR_FILENO);
MXS_ALERT("Fatal: MaxScale " MAXSCALE_VERSION " received fatal signal %d. "
"Attempting backtrace.", i);
MXS_ALERT("Commit ID: %s System name: %s "
"Release string: %s",
maxscale_commit, cnf->sysname, cnf->release_string);
// Then see if we can log them
char** symbols = backtrace_symbols(addrs, count);
#ifdef HAVE_GLIBC
if (symbols)
{
void *addrs[128];
int count = backtrace(addrs, 128);
char** symbols = backtrace_symbols(addrs, count);
if (symbols)
for (int n = 0; n < count; n++)
{
for (int n = 0; n < count; n++)
{
MXS_ALERT(" %s\n", symbols[n]);
}
MXS_FREE(symbols);
}
else
{
fprintf(stderr, "\nresolving symbols to error log failed, writing call trace to stderr:\n");
backtrace_symbols_fd(addrs, count, fileno(stderr));
MXS_ALERT(" %s\n", symbols[n]);
}
MXS_FREE(symbols);
}
#endif
@ -421,8 +421,6 @@ sigfatal_handler(int i)
raise(i);
}
/**
* @node Wraps sigaction calls
*

View File

@ -23,9 +23,11 @@
MXS_BEGIN_DECLS
#define DEFAULT_NBPOLLS 3 /**< Default number of non block polls before we block */
#define DEFAULT_POLLSLEEP 1000 /**< Default poll wait time (milliseconds) */
#define DEFAULT_NTHREADS 1 /**< Default number of polling threads */
#define DEFAULT_NBPOLLS 3 /**< Default number of non block polls before we block */
#define DEFAULT_POLLSLEEP 1000 /**< Default poll wait time (milliseconds) */
#define DEFAULT_NTHREADS 1 /**< Default number of polling threads */
#define DEFAULT_QUERY_RETRIES 0 /**< Number of retries for interrupted queries */
#define DEFAULT_QUERY_RETRY_TIMEOUT 5 /**< Timeout for query retries */
/**
* Maximum length for configuration parameter value.

View File

@ -812,7 +812,7 @@ bool check_monitor_permissions(MXS_MONITOR* monitor, const char* query)
break;
}
}
else if (mysql_query(mondb->con, query) != 0)
else if (mxs_mysql_query(mondb->con, query) != 0)
{
switch (mysql_errno(mondb->con))
{

View File

@ -21,12 +21,15 @@
*/
#include <maxscale/mysql_utils.h>
#include <string.h>
#include <stdbool.h>
#include <errmsg.h>
#include <maxscale/alloc.h>
#include <maxscale/log_manager.h>
#include <maxscale/debug.h>
#include <maxscale/config.h>
#include <maxscale/debug.h>
#include <maxscale/log_manager.h>
/**
* @brief Calculate the length of a length-encoded integer in bytes
@ -147,16 +150,6 @@ char* mxs_lestr_consume(uint8_t** c, size_t *size)
return start;
}
/**
* Creates a connection to a MySQL database engine. If necessary, initializes SSL.
*
* @param con A valid MYSQL structure.
* @param server The server on which the MySQL engine is running.
* @param user The MySQL login ID.
* @param passwd The password for the user.
*/
MYSQL *mxs_mysql_real_connect(MYSQL *con, SERVER *server, const char *user, const char *passwd)
{
SSL_LISTENER *listener = server->server_ssl;
@ -183,6 +176,40 @@ MYSQL *mxs_mysql_real_connect(MYSQL *con, SERVER *server, const char *user, cons
return mysql;
}
static bool is_connection_error(int errcode)
{
switch (errcode)
{
case CR_SOCKET_CREATE_ERROR:
case CR_CONNECTION_ERROR:
case CR_CONN_HOST_ERROR:
case CR_IPSOCK_ERROR:
case CR_SERVER_GONE_ERROR:
case CR_TCP_CONNECTION:
case CR_SERVER_LOST:
return true;
default:
return false;
}
}
int mxs_mysql_query(MYSQL* conn, const char* query)
{
MXS_CONFIG* cnf = config_get_global_options();
time_t start = time(NULL);
int rc = mysql_query(conn, query);
for (int n = 0; rc != 0 && n < cnf->query_retries &&
is_connection_error(mysql_errno(conn)) &&
time(NULL) - start < cnf->query_retry_timeout; n++)
{
rc = mysql_query(conn, query);
}
return rc;
}
bool mxs_mysql_trim_quotes(char *s)
{
bool dequoted = true;