Merge branch '2.1' into develop

This commit is contained in:
Johan Wikman
2017-04-19 18:19:13 +03:00
14 changed files with 121 additions and 81 deletions

View File

@ -85,7 +85,7 @@ if (!defined $MAXADMIN || length($MAXADMIN) == 0) {
$MAXADMIN = $MAXADMIN_DEFAULT;
}
if (defined $MAXADMIN_SOCKET && length($MAXADMIN_SOCKET) > 0) {
$MAXADMIN_SOCKET = ' -S $MAXADMIN_SOCKET';
$MAXADMIN_SOCKET = ' -S ' . $MAXADMIN_SOCKET;
} else {
$MAXADMIN_SOCKET = '';
}
@ -145,7 +145,7 @@ while ( <MAXSCALE> ) {
next if (/--/ || $_ eq '');
if ( /\s+Name/) {
if ( /Name\:/) {
my $str;
my $perf_line;
@ -156,47 +156,45 @@ while ( <MAXSCALE> ) {
}
if (/(\s+Monitor )(.*)/) {
$monitor_data{$this_key}{'2state'}=$2;
}
if (/(State\:\s+)(.*)/) {
$monitor_data{$this_key}{'2state'}=$2;
}
if ( /Monitored servers\:/ ) {
my $server_list;
my @data_row = split(':', $_);
shift(@data_row);
foreach my $name (@data_row) {
$name =~ s/^\s+|\s+$//g;
$name =~ s/ //g;
$server_list .= $name . ":";
}
chop($server_list);
$monitor_data{$this_key}{'3servers'}=$server_list;
}
if ( /Monitored servers\:/ ) {
my $server_list;
my @data_row = split(':', $_);
shift(@data_row);
foreach my $name (@data_row) {
$name =~ s/^\s+|\s+$//g;
$name =~ s/ //g;
$server_list .= $name . ":";
}
chop($server_list);
$monitor_data{$this_key}{'3servers'}=$server_list;
}
if ( /(Sampling interval\:)\s+(\d+) milliseconds/ ) {
$monitor_data{$this_key}{'4interval'}=$2;
}
if ( /(Sampling interval\:)\s+(\d+) milliseconds/ ) {
$monitor_data{$this_key}{'4interval'}=$2;
}
if ( /Replication lag\:/ ) {
my @data_row = split(':', $_);
my $name = $data_row[1];
$name =~ s/^\s+|\s+$//g;
$monitor_data{$this_key}{'5repl_lag'}=$name;
}
if ( /Replication lag\:/ ) {
my @data_row = split(':', $_);
my $name = $data_row[1];
$name =~ s/^\s+|\s+$//g;
$monitor_data{$this_key}{'5repl_lag'}=$name;
}
}
for my $key ( sort(keys %monitor_data) ) {
my $local_hash = {};
$performance_data .= " $key=";
$local_hash = $monitor_data{$key};
my %new_hash = %$local_hash;
foreach my $key (sort (keys (%new_hash))) {
$performance_data .= $new_hash{$key} . ";";
}
chop($performance_data);
}
for my $key ( sort(keys %monitor_data) ) {
my $local_hash = {};
$performance_data .= " $key=";
$local_hash = $monitor_data{$key};
my %new_hash = %$local_hash;
foreach my $key (sort (keys (%new_hash))) {
$performance_data .= $new_hash{$key} . ";";
}
chop($performance_data);
}
if ($n_monitors) {
printf "OK: %d monitors found |%s\n", $n_monitors, $performance_data;
@ -207,4 +205,3 @@ if ($n_monitors) {
close(MAXSCALE);
exit 1;
}

View File

@ -86,7 +86,7 @@ if (!defined $MAXADMIN || length($MAXADMIN) == 0) {
}
if (defined $MAXADMIN_SOCKET && length($MAXADMIN_SOCKET) > 0) {
$MAXADMIN_SOCKET = ' -S $MAXADMIN_SOCKET';
$MAXADMIN_SOCKET = ' -S ' . $MAXADMIN_SOCKET;
} else {
$MAXADMIN_SOCKET = '';
}

View File

@ -86,7 +86,7 @@ if (!defined $MAXADMIN || length($MAXADMIN) == 0) {
}
if (defined $MAXADMIN_SOCKET && length($MAXADMIN_SOCKET) > 0) {
$MAXADMIN_SOCKET = ' -S $MAXADMIN_SOCKET';
$MAXADMIN_SOCKET = ' -S ' . $MAXADMIN_SOCKET;
} else {
$MAXADMIN_SOCKET = '';
}

View File

@ -937,17 +937,18 @@ static void usage(void)
" -?, --help show this help\n"
"\n"
"Defaults paths:\n"
" config file : %s/%s\n"
" configdir : %s\n"
" logdir : %s\n"
" cachedir : %s\n"
" libdir : %s\n"
" datadir : %s\n"
" execdir : %s\n"
" language : %s\n"
" piddir : %s\n"
" persistdir : %s\n"
" module configdir : %s\n"
" config file : %s/%s\n"
" configdir : %s\n"
" logdir : %s\n"
" cachedir : %s\n"
" libdir : %s\n"
" datadir : %s\n"
" execdir : %s\n"
" language : %s\n"
" piddir : %s\n"
" persistdir : %s\n"
" module configdir : %s\n"
" connector plugins : %s\n"
"\n"
"If '--basedir' is provided then all other paths, including the default\n"
"configuration file path, are defined relative to that. As an example,\n"
@ -959,7 +960,7 @@ static void usage(void)
get_configdir(), default_cnf_fname,
get_configdir(), get_logdir(), get_cachedir(), get_libdir(),
get_datadir(), get_execdir(), get_langdir(), get_piddir(),
get_config_persistdir(), get_module_configdir());
get_config_persistdir(), get_module_configdir(), get_connector_plugindir());
}

View File

@ -22,6 +22,10 @@ namespace maxscale
#define TBP_EXPECT_TOKEN(string_literal) string_literal, (sizeof(string_literal) - 1)
// For debugging purposes.
// #define TBP_LOG_UNEXPECTED_AND_EXHAUSTED
#undef TBP_LOG_UNEXPECTED_AND_EXHAUSTED
/**
* @class TrxBoundaryParser
*
@ -149,7 +153,7 @@ private:
void log_unexpected()
{
#ifdef SS_DEBUG
#ifdef TBP_LOG_UNEXPECTED_AND_EXHAUSTED
MXS_NOTICE("Transaction tracking: In statement '%.*s', unexpected token at '%.*s'.",
(int)m_len, m_pSql, (int)(m_pEnd - m_pI), m_pI);
#endif
@ -157,7 +161,7 @@ private:
void log_exhausted()
{
#ifdef SS_DEBUG
#ifdef TBP_LOG_UNEXPECTED_AND_EXHAUSTED
MXS_NOTICE("Transaction tracking: More tokens expected in statement '%.*s'.", (int)m_len, m_pSql);
#endif
}

View File

@ -108,7 +108,7 @@ int test_validity()
TEST(!config_param_is_valid(params, "p8", "d", &ctx));
TEST(!config_param_is_valid(params, "p8", "a,d", &ctx));
TEST(!config_param_is_valid(params, "p8", "a,b,c,d", &ctx));
config_parameter_free(svc.parameters);
return 0;
}
@ -174,7 +174,9 @@ int test_add_parameter()
TEST(val == 5);
TEST(strcmp(config_get_string(ctx.parameters, "p6"), "/dev/null") == 0);
TEST(strcmp(config_get_string(ctx.parameters, "p7"), "some-service") == 0);
config_parameter_free(ctx.parameters);
config_parameter_free(svc1.parameters);
config_parameter_free(svc2.parameters);
return 0;
}
@ -201,7 +203,7 @@ int test_required_parameters()
config_add_param(&ctx, "p2", "1");
config_add_param(&ctx, "p3", "1");
TEST(!missing_required_parameters(params, ctx.parameters));
config_parameter_free(ctx.parameters);
return 0;
}

View File

@ -29,11 +29,14 @@
#if defined(NDEBUG)
#undef NDEBUG
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <maxscale/listener.h>
#include <maxscale/config.h>
#include <maxscale/dcb.h>
#include <maxscale/listener.h>
/**
* test1 Allocate a dcb and do lots of other things
@ -64,15 +67,15 @@ test1()
dcb->state = DCB_STATE_POLLING;
dcb_close(dcb);
ss_dfprintf(stderr, "Freed original dcb");
ss_info_dassert(!dcb_isvalid(dcb), "Freed DCB must not be valid");
ss_info_dassert(!dcb_isvalid(dcb), "Closed DCB must not be valid");
ss_dfprintf(stderr, "\t..done\nMake clone DCB a zombie");
clone->state = DCB_STATE_NOPOLLING;
dcb_add_to_list(clone);
dcb_close(clone);
ss_dfprintf(stderr, "\t..done\nCheck clone no longer valid");
ss_info_dassert(!dcb_isvalid(clone), "After closing, clone DCB must not be valid");
ss_dfprintf(stderr, "\t..done\nProcess the zombies list");
dcb_process_zombies(0);
ss_dfprintf(stderr, "\t..done\nCheck clone no longer valid");
ss_info_dassert(!dcb_isvalid(clone), "After zombie processing, clone DCB must not be valid");
ss_dfprintf(stderr, "\t..done\n");
return 0;
@ -81,6 +84,8 @@ test1()
int main(int argc, char **argv)
{
int result = 0;
MXS_CONFIG* glob_conf = config_get_global_options();
glob_conf->n_threads = 1;
dcb_global_init();
result += test1();

View File

@ -89,6 +89,8 @@ test2()
filter_add_parameter(f1, "name1", "value1");
filter_add_parameter(f1, "name2", "value2");
filter_add_parameter(f1, "name3", "value3");
filter_free(f1);
return 0;
}

View File

@ -46,19 +46,21 @@ static int
test1()
{
GWBUF *buffer;
char *(sql[100]);
char *sql;
int result, length, residual;
/* Poll tests */
ss_dfprintf(stderr,
"testmodutil : Rudimentary tests.");
buffer = gwbuf_alloc(100);
ss_info_dassert(GWBUF_IS_CONTIGUOUS(buffer), "Allocated buffer should be continuos");
memset(GWBUF_DATA(buffer), 0, GWBUF_LENGTH(buffer));
ss_info_dassert(0 == modutil_is_SQL(buffer), "Default buffer should be diagnosed as not SQL");
/* There would ideally be some straightforward way to create a SQL buffer? */
ss_dfprintf(stderr, "\t..done\nExtract SQL from buffer");
ss_info_dassert(0 == modutil_extract_SQL(buffer, sql, &length), "Default buffer should fail");
ss_info_dassert(0 == modutil_extract_SQL(buffer, &sql, &length), "Default buffer should fail");
ss_dfprintf(stderr, "\t..done\nExtract SQL from buffer different way?");
ss_info_dassert(0 == modutil_MySQL_Query(buffer, sql, &length, &residual), "Default buffer should fail");
ss_info_dassert(0 == modutil_MySQL_Query(buffer, &sql, &length, &residual), "Default buffer should fail");
ss_dfprintf(stderr, "\t..done\nReplace SQL in buffer");
ss_info_dassert(0 == modutil_replace_SQL(buffer, "select * from some_table;"), "Default buffer should fail");
ss_dfprintf(stderr, "\t..done\nTidy up.");
@ -166,6 +168,7 @@ void test_single_sql_packet1()
ss_info_dassert(gwbuf_length(complete) == sizeof(ok), "Complete packet buffer should contain enough data");
ss_info_dassert(memcmp(GWBUF_DATA(complete), ok, GWBUF_LENGTH(complete)) == 0,
"Complete packet buffer's data should be equal to original data");
gwbuf_free(complete);
/** Partial single packet */
buffer = gwbuf_alloc_and_load(sizeof(ok) - 4, ok);
@ -181,6 +184,7 @@ void test_single_sql_packet1()
ss_info_dassert(complete, "Complete packet buffer should not be NULL");
ss_info_dassert(complete->next, "The complete packet should be a chain of buffers");
ss_info_dassert(gwbuf_length(complete) == sizeof(ok), "Buffer should contain all data");
gwbuf_free(complete);
}
void test_multiple_sql_packets1()
@ -195,6 +199,7 @@ void test_multiple_sql_packets1()
"Complete packet buffer should contain enough data");
ss_info_dassert(memcmp(GWBUF_DATA(complete), resultset, GWBUF_LENGTH(complete)) == 0,
"Complete packet buffer's data should be equal to original data");
gwbuf_free(complete);
/** Partial data available with one complete packet */
GWBUF* head = gwbuf_alloc_and_load(7, resultset);
@ -204,14 +209,16 @@ void test_multiple_sql_packets1()
ss_info_dassert(complete, "Complete buffer should not be NULL");
ss_info_dassert(gwbuf_length(complete) == 5, "Complete buffer should contain first packet only");
ss_info_dassert(gwbuf_length(head) == 2, "Complete buffer should contain first packet only");
gwbuf_free(complete);
/** All packets are available */
head = gwbuf_append(head, tail);
complete = modutil_get_complete_packets(&head);
ss_info_dassert(buffer == NULL, "Old buffer should be NULL");
ss_info_dassert(head == NULL, "Old buffer should be NULL");
ss_info_dassert(complete, "Complete packet buffer should not be NULL");
ss_info_dassert(gwbuf_length(complete) == sizeof(resultset) - 5,
"Complete packet should be sizeof(resultset) - 5 bytes");
gwbuf_free(complete);
/** Sliding cutoff of the buffer boundary */
for (size_t i = 0; i < sizeof(resultset); i++)
@ -228,6 +235,8 @@ void test_multiple_sql_packets1()
gwbuf_copy_data(complete, 0, completelen, databuf);
gwbuf_copy_data(head, 0, headlen, databuf + completelen);
ss_info_dassert(memcmp(databuf, resultset, sizeof(resultset)) == 0, "Data should be OK");
gwbuf_free(head);
gwbuf_free(complete);
}
/** Fragmented buffer chain */
@ -285,6 +294,7 @@ void test_multiple_sql_packets1()
ss_info_dassert(gwbuf_copy_data(complete, 0, completelen, databuf) == completelen,
"All data should be readable");
ss_info_dassert(memcmp(databuf, resultset, sizeof(resultset)) == 0, "Data should be OK");
gwbuf_free(complete);
}
//
@ -412,6 +422,8 @@ void test_multiple_sql_packets2()
gwbuf_copy_data(next, 0, nextlen, databuf);
gwbuf_copy_data(head, 0, headlen, databuf + nextlen);
ss_info_dassert(memcmp(databuf, resultset, sizeof(resultset)) == 0, "Data should be OK");
gwbuf_free(head);
gwbuf_free(next);
}
/** Fragmented buffer chain */
@ -575,6 +587,7 @@ void test_large_packets()
ss_info_dassert(complete, "The complete buffer is not NULL");
ss_info_dassert(gwbuf_length(complete) == 0xffffff + 4, "Length should be correct");
gwbuf_free(buffer);
gwbuf_free(complete);
}
}

View File

@ -55,7 +55,6 @@ test1()
ss_dfprintf(stderr,
"testpoll : Initialise the polling system.");
init_test_env(NULL);
poll_init();
ss_dfprintf(stderr, "\t..done\nAdd a DCB");
dcb = dcb_alloc(DCB_ROLE_CLIENT_HANDLER, &dummy);

View File

@ -134,6 +134,7 @@ test1()
return 10;
}
output_counter++;
MXS_FREE(entry.queued_object);
}
else
{
@ -148,6 +149,7 @@ test1()
return 6;
}
output_counter++;
MXS_FREE(entry.queued_object);
}
else
{
@ -172,6 +174,7 @@ test1()
return 8;
}
output_counter++;
MXS_FREE(entry.queued_object);
}
else
{
@ -188,7 +191,7 @@ test1()
}
ss_dfprintf(stderr, "Successfully ended test\n");
mxs_queue_free(queue);
return 0;
}
@ -241,6 +244,7 @@ test2()
ss_info_dassert((0 == err), "Must join threads successfully");
ss_dfprintf(stderr, "\nThread %d ended with debug check fail at %d.\n", i, debug_check_fail);
}
mxs_queue_free(thread_queue);
return debug_check_fail ? 1 : 0;
}

View File

@ -386,21 +386,23 @@ int CacheFilterSession::clientReply(GWBUF* pData)
if (m_res.pData)
{
gwbuf_append(m_res.pData, pData);
m_res.length += gwbuf_length(pData); // pData may be a chain, so not GWBUF_LENGTH().
}
else
{
m_res.pData = pData;
m_res.length = gwbuf_length(pData);
}
if (m_state != CACHE_IGNORING_RESPONSE)
{
if (cache_max_resultset_size_exceeded(m_pCache->config(), gwbuf_length(m_res.pData)))
if (cache_max_resultset_size_exceeded(m_pCache->config(), m_res.length))
{
if (log_decisions())
{
MXS_NOTICE("Current size %uB of resultset, at least as much "
MXS_NOTICE("Current size %luB of resultset, at least as much "
"as maximum allowed size %luKiB. Not caching.",
gwbuf_length(m_res.pData),
m_res.length,
m_pCache->config().max_resultset_size / 1024);
}
@ -466,7 +468,8 @@ int CacheFilterSession::handle_expecting_fields()
bool insufficient = false;
size_t buflen = gwbuf_length(m_res.pData);
size_t buflen = m_res.length;
ss_dassert(m_res.length == gwbuf_length(m_res.pData));
while (!insufficient && (buflen - m_res.offset >= MYSQL_HEADER_LEN))
{
@ -528,7 +531,8 @@ int CacheFilterSession::handle_expecting_response()
int rv = 1;
size_t buflen = gwbuf_length(m_res.pData);
size_t buflen = m_res.length;
ss_dassert(m_res.length == gwbuf_length(m_res.pData));
if (buflen >= MYSQL_HEADER_LEN + 1) // We need the command byte.
{
@ -601,7 +605,8 @@ int CacheFilterSession::handle_expecting_rows()
bool insufficient = false;
size_t buflen = gwbuf_length(m_res.pData);
size_t buflen = m_res.length;
ss_dassert(m_res.length == gwbuf_length(m_res.pData));
while (!insufficient && (buflen - m_res.offset >= MYSQL_HEADER_LEN))
{
@ -661,7 +666,8 @@ int CacheFilterSession::handle_expecting_use_response()
int rv = 1;
size_t buflen = gwbuf_length(m_res.pData);
size_t buflen = m_res.length;
ss_dassert(m_res.length == gwbuf_length(m_res.pData));
if (buflen >= MYSQL_HEADER_LEN + 1) // We need the command byte.
{
@ -733,6 +739,7 @@ int CacheFilterSession::send_upstream()
void CacheFilterSession::reset_response_state()
{
m_res.pData = NULL;
m_res.length = 0;
m_res.nTotalFields = 0;
m_res.nFields = 0;
m_res.nRows = 0;

View File

@ -35,6 +35,7 @@ public:
struct CACHE_RESPONSE_STATE
{
GWBUF* pData; /**< Response data, possibly incomplete. */
size_t length; /**< Length of pData. */
size_t nTotalFields; /**< The number of fields a resultset contains. */
size_t nFields; /**< How many fields we have received, <= n_totalfields. */
size_t nRows; /**< How many rows we have received. */

View File

@ -187,6 +187,7 @@ typedef struct maxrows_response_state
size_t n_rows; /**< How many rows we have received. */
size_t offset; /**< Where we are in the response buffer. */
size_t rows_offset; /**< Offset to first row in result set */
size_t length; /**< Buffer size. */
} MAXROWS_RESPONSE_STATE;
static void maxrows_response_state_reset(MAXROWS_RESPONSE_STATE *state);
@ -354,6 +355,8 @@ static int routeQuery(MXS_FILTER *instance,
csdata->state = MAXROWS_IGNORING_RESPONSE;
csdata->large_packet = false;
csdata->discard_resultset = false;
// Set buffer size to 0
csdata->res.length = 0;
switch ((int)MYSQL_GET_COMMAND(data))
{
@ -414,23 +417,25 @@ static int clientReply(MXS_FILTER *instance,
if (csdata->res.data)
{
gwbuf_append(csdata->res.data, data);
csdata->res.length += gwbuf_length(data);
}
else
{
csdata->res.data = data;
csdata->res.length = gwbuf_length(data);
}
if (csdata->state != MAXROWS_IGNORING_RESPONSE)
{
if (!csdata->discard_resultset)
{
if (gwbuf_length(csdata->res.data) > csdata->instance->config.max_resultset_size)
if (csdata->res.length > csdata->instance->config.max_resultset_size)
{
if (csdata->instance->config.debug & MAXROWS_DEBUG_DISCARDING)
{
MXS_NOTICE("Current size %uB of resultset, at least as much "
MXS_NOTICE("Current size %luB of resultset, at least as much "
"as maximum allowed size %uKiB. Not returning data.",
gwbuf_length(csdata->res.data),
csdata->res.length,
csdata->instance->config.max_resultset_size / 1024);
}
@ -573,7 +578,7 @@ static int handle_expecting_fields(MAXROWS_SESSION_DATA *csdata)
bool insufficient = false;
size_t buflen = gwbuf_length(csdata->res.data);
size_t buflen = csdata->res.length;
while (!insufficient && (buflen - csdata->res.offset >= MYSQL_HEADER_LEN))
{
@ -650,7 +655,7 @@ static int handle_expecting_response(MAXROWS_SESSION_DATA *csdata)
ss_dassert(csdata->res.data);
int rv = 1;
size_t buflen = gwbuf_length(csdata->res.data);
size_t buflen = csdata->res.length;
// Reset field counters
csdata->res.n_fields = 0;
@ -770,7 +775,7 @@ static int handle_rows(MAXROWS_SESSION_DATA *csdata)
int rv = 1;
bool insufficient = false;
size_t buflen = gwbuf_length(csdata->res.data);
size_t buflen = csdata->res.length;
while (!insufficient && (buflen - csdata->res.offset >= MYSQL_HEADER_LEN))
{