Merge branch '2.2' into develop

This commit is contained in:
Markus Mäkelä
2018-02-05 10:22:43 +02:00
71 changed files with 2097 additions and 749 deletions

View File

@ -73,6 +73,7 @@ target_link_libraries(maxscale-common
z
rt
m
sqlite3
stdc++
gnutls
gcrypt

View File

@ -43,6 +43,8 @@ Backend::~Backend()
void Backend::close(close_type type)
{
ss_dassert(m_dcb->n_close == 0);
if (!m_closed)
{
m_closed = true;

View File

@ -116,6 +116,7 @@ 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_LOCAL_ADDRESS[] = "local_address";
const char CN_REQUIRED[] = "required";
const char CN_RETRY_ON_FAILURE[] = "retry_on_failure";
const char CN_ROUTER[] = "router";
@ -1624,6 +1625,10 @@ handle_global_item(const char *name, const char *value)
{
gateway.passive = config_truth_value((char*)value);
}
else if (strcmp(name, CN_LOCAL_ADDRESS) == 0)
{
gateway.local_address = MXS_STRDUP_A(value);
}
else
{
for (i = 0; lognames[i].name; i++)

View File

@ -1123,6 +1123,7 @@ void dcb_close(DCB *dcb)
++dcb->n_close;
// TODO: Will this happen on a regular basis?
MXS_WARNING("dcb_close(%p) called %u times.", dcb, dcb->n_close);
ss_dassert(!true);
}
}
@ -3208,6 +3209,26 @@ static uint32_t dcb_poll_handler(MXS_POLL_DATA *data, int thread_id, uint32_t ev
return dcb_handler(dcb, events);
}
static bool dcb_is_still_valid(DCB* target, int id)
{
bool rval = false;
for (DCB *dcb = this_unit.all_dcbs[id];
dcb; dcb = dcb->thread.next)
{
if (target == dcb)
{
if (dcb->n_close == 0)
{
rval = true;
}
break;
}
}
return rval;
}
class FakeEventTask: public mxs::WorkerDisposableTask
{
FakeEventTask(const FakeEventTask&);
@ -3223,8 +3244,15 @@ public:
void execute(Worker& worker)
{
m_dcb->fakeq = m_buffer;
dcb_handler(m_dcb, m_ev);
if (dcb_is_still_valid(m_dcb, worker.get_current_id()))
{
m_dcb->fakeq = m_buffer;
dcb_handler(m_dcb, m_ev);
}
else
{
gwbuf_free(m_buffer);
}
}
private:

View File

@ -46,6 +46,7 @@
#include <maxscale/paths.h>
#include <maxscale/query_classifier.h>
#include <maxscale/server.h>
#include <maxscale/sqlite3.h>
#include <maxscale/session.h>
#include <maxscale/utils.h>
#include <maxscale/version.h>
@ -189,6 +190,7 @@ static void disable_module_unloading(const char* arg);
static void enable_module_unloading(const char* arg);
static void redirect_output_to_file(const char* arg);
static bool user_is_acceptable(const char* specified_user);
static bool init_sqlite3();
struct DEBUG_ARGUMENT
{
@ -1957,6 +1959,13 @@ int main(int argc, char **argv)
}
}
if (!init_sqlite3())
{
MXS_ERROR("Could not initialize sqlite3, exiting.");
rc = MAXSCALE_INTERNALERROR;
goto return_main;
}
MXS_NOTICE("MariaDB MaxScale %s started", MAXSCALE_VERSION);
MXS_NOTICE("MaxScale is running in process %i", getpid());
@ -3304,3 +3313,33 @@ static bool user_is_acceptable(const char* specified_user)
return acceptable;
}
static bool init_sqlite3()
{
bool rv = true;
// Collecting the memstatus introduces locking that, according to customer reports,
// has a significant impact on the performance.
if (sqlite3_config(SQLITE_CONFIG_MEMSTATUS, (int)0) == SQLITE_OK) // 0 turns off.
{
MXS_NOTICE("The collection of SQLite memory allocation statistics turned off.");
}
else
{
MXS_WARNING("Could not turn off the collection of SQLite memory allocation statistics.");
// Non-fatal, we simply will take a small performance hit.
}
if (sqlite3_config(SQLITE_CONFIG_MULTITHREAD) == SQLITE_OK)
{
MXS_NOTICE("Threading mode of SQLite set to Multi-thread.");
}
else
{
MXS_ERROR("Could not set the threading mode of SQLite to Multi-thread. "
"MaxScale will terminate.");
rv = false;
}
return rv;
}

View File

@ -2427,3 +2427,16 @@ static bool journal_is_stale(MXS_MONITOR *monitor, time_t max_age)
return is_stale;
}
MXS_MONITORED_SERVER* mon_get_monitored_server(MXS_MONITOR* mon, SERVER* search_server)
{
ss_dassert(mon && search_server);
for (MXS_MONITORED_SERVER* iter = mon->monitored_servers; iter != NULL; iter = iter->next)
{
if (iter->server == search_server)
{
return iter;
}
}
return NULL;
}

View File

@ -262,47 +262,18 @@ static void unpack_datetime(uint8_t *ptr, int length, struct tm *dest)
uint64_t val = 0;
uint32_t second, minute, hour, day, month, year;
if (length == -1)
{
val = gw_mysql_get_byte8(ptr);
second = val - ((val / 100) * 100);
val /= 100;
minute = val - ((val / 100) * 100);
val /= 100;
hour = val - ((val / 100) * 100);
val /= 100;
day = val - ((val / 100) * 100);
val /= 100;
month = val - ((val / 100) * 100);
val /= 100;
year = val;
}
else
{
// TODO: Figure out why DATETIME(0) doesn't work like it others do
val = unpack_bytes(ptr, datetime_sizes[length]);
val *= log_10_values[6 - length];
if (val < 0)
{
val = -val;
}
int subsecond = val % 1000000;
val /= 1000000;
second = val % 60;
val /= 60;
minute = val % 60;
val /= 60;
hour = val % 24;
val /= 24;
day = val % 32;
val /= 32;
month = val % 13;
val /= 13;
year = val;
}
val = gw_mysql_get_byte8(ptr);
second = val - ((val / 100) * 100);
val /= 100;
minute = val - ((val / 100) * 100);
val /= 100;
hour = val - ((val / 100) * 100);
val /= 100;
day = val - ((val / 100) * 100);
val /= 100;
month = val - ((val / 100) * 100);
val /= 100;
year = val;
memset(dest, 0, sizeof(struct tm));
dest->tm_year = year - 1900;
@ -502,7 +473,7 @@ static size_t temporal_field_size(uint8_t type, uint8_t decimals, int length)
return 3 + ((decimals + 1) / 2);
case TABLE_COL_TYPE_DATETIME:
return length < 0 || length > 6 ? 8 : datetime_sizes[length];
return 8;
case TABLE_COL_TYPE_TIMESTAMP:
return 4;
@ -649,6 +620,7 @@ size_t unpack_numeric_field(uint8_t *src, uint8_t type, uint8_t *metadata, uint8
break;
}
ss_dassert(size > 0);
memcpy(dest, src, size);
return size;
}

View File

@ -320,10 +320,7 @@ void session_close(MXS_SESSION *session)
{
if (session->router_session)
{
if (session->state != SESSION_STATE_STOPPING)
{
session->state = SESSION_STATE_STOPPING;
}
session->state = SESSION_STATE_STOPPING;
MXS_ROUTER_OBJECT* router = session->service->router;
MXS_ROUTER* router_instance = session->service->router_instance;

View File

@ -41,6 +41,7 @@
#include <openssl/sha.h>
#include <maxscale/alloc.h>
#include <maxscale/config.h>
#include <maxscale/dcb.h>
#include <maxscale/log_manager.h>
#include <maxscale/limits.h>
@ -1019,6 +1020,8 @@ int open_network_socket(enum mxs_socket_type type, struct sockaddr_storage *addr
memcpy(addr, ai->ai_addr, ai->ai_addrlen);
set_port(addr, port);
freeaddrinfo(ai);
if ((type == MXS_SOCKET_NETWORK && !configure_network_socket(so)) ||
(type == MXS_SOCKET_LISTENER && !configure_listener_socket(so)))
{
@ -1032,9 +1035,39 @@ int open_network_socket(enum mxs_socket_type type, struct sockaddr_storage *addr
close(so);
so = -1;
}
}
else if (type == MXS_SOCKET_NETWORK)
{
MXS_CONFIG* config = config_get_global_options();
freeaddrinfo(ai);
if (config->local_address)
{
if ((rc = getaddrinfo(config->local_address, NULL, &hint, &ai)) == 0)
{
struct sockaddr_storage local_address = {};
memcpy(&local_address, ai->ai_addr, ai->ai_addrlen);
freeaddrinfo(ai);
if (bind(so, (struct sockaddr*)&local_address, sizeof(local_address)) == 0)
{
MXS_INFO("Bound connecting socket to \"%s\".", config->local_address);
}
else
{
MXS_ERROR("Could not bind connecting socket to local address \"%s\", "
"connecting to server using default local address: %s",
config->local_address, mxs_strerror(errno));
}
}
else
{
MXS_ERROR("Could not get address information for local address \"%s\", "
"connecting to server using default local address: %s",
config->local_address, mxs_strerror(errno));
}
}
}
}
}
return so;