Merge branch '2.2' into develop
This commit is contained in:
@ -73,6 +73,7 @@ target_link_libraries(maxscale-common
|
||||
z
|
||||
rt
|
||||
m
|
||||
sqlite3
|
||||
stdc++
|
||||
gnutls
|
||||
gcrypt
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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++)
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user