From fd011fc1282a5a3dd49cfec4ef49d01538b414af Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 5 Jan 2015 11:31:28 +0200 Subject: [PATCH 1/5] Fixed build issues due to missing headers. --- query_classifier/query_classifier.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/query_classifier/query_classifier.cc b/query_classifier/query_classifier.cc index 19345ccd6..dfcf8d149 100644 --- a/query_classifier/query_classifier.cc +++ b/query_classifier/query_classifier.cc @@ -174,8 +174,8 @@ bool parse_query ( data = (uint8_t*)GWBUF_DATA(querybuf); len = MYSQL_GET_PACKET_LEN(data)-1; /*< distract 1 for packet type byte */ - - if (len < 1 || len >= SIZE_MAX - 1 || (query_str = (char *)malloc(len+1)) == NULL) + + if (len < 1 || len >= ~((size_t)0) - 1 || (query_str = (char *)malloc(len+1)) == NULL) { /** Free parsing info data */ parsing_info_done(pi); From 87294136555b904ab28a4a52a4dc299359651108 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 5 Jan 2015 11:31:28 +0200 Subject: [PATCH 2/5] Fixed build issues due to missing headers. --- query_classifier/query_classifier.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/query_classifier/query_classifier.cc b/query_classifier/query_classifier.cc index 19345ccd6..dfcf8d149 100644 --- a/query_classifier/query_classifier.cc +++ b/query_classifier/query_classifier.cc @@ -174,8 +174,8 @@ bool parse_query ( data = (uint8_t*)GWBUF_DATA(querybuf); len = MYSQL_GET_PACKET_LEN(data)-1; /*< distract 1 for packet type byte */ - - if (len < 1 || len >= SIZE_MAX - 1 || (query_str = (char *)malloc(len+1)) == NULL) + + if (len < 1 || len >= ~((size_t)0) - 1 || (query_str = (char *)malloc(len+1)) == NULL) { /** Free parsing info data */ parsing_info_done(pi); From 6adccb3c171765515712dd5e08f073a90edee499 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 5 Jan 2015 13:28:27 +0200 Subject: [PATCH 3/5] Fix to bug 680: http://bugs.mariadb.com/show_bug.cgi?id=680 service.h:Added the 'serviceStartFailed' function which tries to start services with successfully started routers but no successfully started listeners. mysql_mon.c:Added a call to ServiceStartFailed when servers come available. --- server/core/service.c | 66 ++++++++++++++++++++++++------ server/include/server.h | 1 + server/include/service.h | 3 ++ server/modules/monitor/mysql_mon.c | 28 +++++++++++-- 4 files changed, 83 insertions(+), 15 deletions(-) diff --git a/server/core/service.c b/server/core/service.c index 8db451d11..1ddb6ebd6 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -331,16 +331,22 @@ serviceStart(SERVICE *service) { SERV_PROTOCOL *port; int listeners = 0; - - if ((service->router_instance = service->router->createInstance(service, - service->routerOptions)) == NULL) - { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "%s: Failed to create router instance for service. Service not started.", - service->name))); - service->state = SERVICE_STATE_FAILED; - return 0; - } + if(service->router_instance == NULL) + { + /* + * This is the first time this service's router is being started or the + * previous attempt failed. + */ + if((service->router_instance = service->router->createInstance(service, + service->routerOptions)) == NULL) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "%s: Failed to create router instance for service. Service not started.", + service->name))); + service->state = SERVICE_STATE_FAILED; + return 0; + } + } port = service->ports; while (!service->svc_do_shutdown && port) @@ -353,7 +359,10 @@ int listeners = 0; service->state = SERVICE_STATE_STARTED; service->stats.started = time(0); } - + else + { + service->state = SERVICE_STATE_LISTENER_FAILED; + } return listeners; } @@ -408,6 +417,40 @@ int n = 0,i; return n; } +/** + * Try to start services that failed to start their listeners but successfully + * started their routers. + * @return Number of successfully started services + */ +int +serviceStartFailedListeners() +{ +SERVICE *ptr; +int n = 0,i; + + spinlock_acquire(&service_spin); + ptr = allServices; + spinlock_release(&service_spin); + + while (ptr && !ptr->svc_do_shutdown) + { + if(ptr->state == SERVICE_STATE_LISTENER_FAILED) + { + n += (i = serviceStart(ptr)); + + if(i == 0) + { + LOGIF(LE, (skygw_log_write( + LOGFILE_ERROR, + "Error : Failed to start service '%s'.", + ptr->name))); + } + } + ptr = ptr->next; + } + return n; +} + /** * Stop a service * @@ -815,7 +858,6 @@ SERVICE *service; return service; } - /** * Print details of an individual service * diff --git a/server/include/server.h b/server/include/server.h index 4bb514d65..018593380 100644 --- a/server/include/server.h +++ b/server/include/server.h @@ -130,6 +130,7 @@ typedef struct server { (SERVER_RUNNING|SERVER_MASTER|SERVER_SLAVE|SERVER_MAINT)) == \ (SERVER_RUNNING|SERVER_MASTER)) +#define SRV_DOWN_STATUS(status) ((status & SERVER_RUNNING) == 0) /** * Is the server valid candidate for root master. The server must be running, * marked as master and not have maintenance bit set. diff --git a/server/include/service.h b/server/include/service.h index ab18e5d29..f0477941b 100644 --- a/server/include/service.h +++ b/server/include/service.h @@ -152,6 +152,8 @@ typedef enum count_spec_t {COUNT_NONE=0, COUNT_ATLEAST, COUNT_EXACT, COUNT_ATMOS #define SERVICE_STATE_STARTED 2 /**< The service has been started */ #define SERVICE_STATE_FAILED 3 /**< The service failed to start */ #define SERVICE_STATE_STOPPED 4 /**< The service has been stopped */ +#define SERVICE_STATE_LISTENER_FAILED 5 /**< The service successfully started the + router but failed to start the listeners*/ extern SERVICE *service_alloc(const char *, const char *); extern int service_free(SERVICE *); @@ -165,6 +167,7 @@ extern void serviceAddRouterOption(SERVICE *, char *); extern void serviceClearRouterOptions(SERVICE *); extern int serviceStart(SERVICE *); extern int serviceStartAll(); +extern int serviceStartFailedListeners(); extern void serviceStartProtocol(SERVICE *, char *, int); extern int serviceStop(SERVICE *); extern int serviceRestart(SERVICE *); diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index 41d9872a9..b10f8ad0d 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -64,6 +64,8 @@ #include #include +#include "service.h" + /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; extern size_t log_ses_count[]; @@ -610,7 +612,7 @@ int num_servers=0; MONITOR_SERVERS *root_master = NULL; size_t nrounds = 0; int log_no_master = 1; - +int new_backends = 0; if (mysql_thread_init()) { LOGIF(LE, (skygw_log_write_flush( @@ -648,7 +650,10 @@ int log_no_master = 1; nrounds += 1; /* reset num_servers */ num_servers = 0; - + + /* reset new_backends */ + new_backends = 0; + /* start from the first server in the list */ ptr = handle->databases; @@ -691,7 +696,13 @@ int log_no_master = 1; !(SERVER_IS_IN_CLUSTER(ptr->server))) { dcb_call_foreach(DCB_REASON_NOT_RESPONDING); - } + } + + if(SRV_DOWN_STATUS(ptr->mon_prev_status) && + SERVER_IS_RUNNING(ptr->server)) + { + new_backends++; + } } if (mon_status_changed(ptr)) @@ -726,6 +737,17 @@ int log_no_master = 1; ptr = ptr->next; } + + /** + * Some new servers are now running. Try to start services + * that failed to start their listeners but successfully created + * their router instances. + */ + + if(new_backends > 0) + { + serviceStartFailedListeners(); + } ptr = handle->databases; /* if only one server is configured, that's is Master */ From 468ce72c18d8acc6dc409acd91db70cf5df48083 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 5 Jan 2015 13:54:27 +0200 Subject: [PATCH 4/5] Fix to bug 681: http://bugs.mariadb.com/show_bug.cgi?id=681 Added casts to floating point versions of values when doing divisions. --- server/modules/routing/readwritesplit/readwritesplit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 2a7cb5d9e..8edff5d63 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4692,7 +4692,7 @@ static bool have_enough_servers( "would be required.", router->service->name, (*p_rses)->rses_config.rw_max_slave_conn_percent, - min_nsrv/(router_nsrv/100)))); + (double)min_nsrv/((double)router_nsrv/100.0)))); } } free(*p_rses); From 91a3109f4dfe2abc2f640767193582a24741cca7 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 5 Jan 2015 14:28:16 +0200 Subject: [PATCH 5/5] Fix to bug 638: http://bugs.mariadb.com/show_bug.cgi?id=638 readwritesplit.c:Added missing backend type when using max_slave_replication_lag hint. --- server/modules/routing/readwritesplit/readwritesplit.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 8edff5d63..c8be8af26 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -2235,7 +2235,7 @@ static bool route_single_stmt( { rlag_max = rses_get_max_replication_lag(rses); } - btype = BE_UNDEFINED; /*< target may be master or slave */ + btype = route_target & TARGET_SLAVE ? BE_SLAVE : BE_MASTER; /*< target may be master or slave */ /** * Search backend server by name or replication lag. * If it fails, then try to find valid slave or master. @@ -4684,15 +4684,16 @@ static bool have_enough_servers( } if (nservers < min_nsrv) { - LOGIF(LE, (skygw_log_write_flush( + double dbgpct = ((double)min_nsrv/(double)router_nsrv)*100.0; + LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Unable to start %s service. There are " "too few backend servers configured in " - "MaxScale.cnf. Found %d%% when at least %d%% " + "MaxScale.cnf. Found %d%% when at least %.0f%% " "would be required.", router->service->name, (*p_rses)->rses_config.rw_max_slave_conn_percent, - (double)min_nsrv/((double)router_nsrv/100.0)))); + dbgpct))); } } free(*p_rses);