Merge branch 'master' into schemarouter_refresh

This commit is contained in:
Markus Makela
2015-07-20 11:42:43 +03:00
11 changed files with 499 additions and 289 deletions

View File

@ -17,7 +17,7 @@ Bugs can be reported in the MariaDB Jira
[https://mariadb.atlassian.net](https://mariadb.atlassian.net) [https://mariadb.atlassian.net](https://mariadb.atlassian.net)
## Installing MaxScale ## Installing MaxScale
Information about installing MaxScale, either from a repository or by building from source code, is included in the guide [Getting Started with MaxScale](/Documentation/Getting-Started/Getting-Started-With-MaxScale.md). Information about installing MaxScale, either from a repository or by building from source code, is included in the [MariaDB MaxScale Installation Guide](../Getting-Started/MariaDB-MaxScale-Installation-Guide.md).
The same guide also provides basic information on running MaxScale. More detailed information about configuring MaxScale is given in the [Configuration Guide](/Documentation/Getting-Started/Configuration-Guide.md). The same guide also provides basic information on running MaxScale. More detailed information about configuring MaxScale is given in the [Configuration Guide](/Documentation/Getting-Started/Configuration-Guide.md).

View File

@ -16,7 +16,7 @@ The simplest way to install MaxScale is to use one of the binary packages that a
![image alt text](images/getting_started.png) ![image alt text](images/getting_started.png)
If you want to install only MaxScale, futher down you will find the product specific download pages. Click on the MariaDB MaxScale link and follow the distribution specific instructions. If you want to install only MaxScale, further down you will find the product specific download pages. Click on the MariaDB MaxScale link and follow the distribution specific instructions.
![image alt text](images/getting_started2.png) ![image alt text](images/getting_started2.png)

View File

@ -98,6 +98,14 @@ A list of event names which cause the script to be executed. If this option is n
events=master_down,slave_down events=master_down,slave_down
``` ```
### `mysql51_replication`
Enable support for MySQL 5.1 replication monitoring. This is needed if a MySQL server older than 5.5 is used as a slave in replication.
```
mysql51_replication=true
```
## Script events ## Script events
Here is a table of all possible event types and their descriptions. Here is a table of all possible event types and their descriptions.

View File

@ -2,7 +2,7 @@
## 1.1.1 GA ## 1.1.1 GA
This document details the changes in version 1.1.1 since the release of the 1.1 GA Release of the MaxScale product. MaxScale 1.1 is the current stable (GA) release of MaxScale. Version 1.1.1 is mainly a bug fix release introducing fixes, but also introduces some improvements to existing functionality.
## New Features ## New Features
@ -20,42 +20,43 @@ Using the password functionality in MaxScale is now a lot easier. Both programs
## Bug Fixes ## Bug Fixes
Here is a list of bugs fixed since the release of the 1.1 version of MaxScale. The bug IDs are from the **[Mariadb Jira](https://mariadb.atlassian.net/)**. Here is a list of bugs fixed since the release of the 1.1.0 version of MaxScale. The bug IDs are from the **[MariaDB Jira](https://mariadb.atlassian.net/)**.
|Bug|Description| * [MXS-99](https://mariadb.atlassian.net/browse/MXS-99): /etc/init.d/maxscale reload doesn't do anything
|---|-----------| * [MXS-83](https://mariadb.atlassian.net/browse/MXS-83): linkage fails when system pcre library is recent
|[MXS-99](https://mariadb.atlassian.net/browse/MXS-99)|/etc/init.d/maxscale reload doesn't do anything| * [MXS-112](https://mariadb.atlassian.net/browse/MXS-112): Disable saving of session commands in the readwritesplit and schemarouter modules
|[MXS-83](https://mariadb.atlassian.net/browse/MXS-83)|linkage fails when system pcre library is recent| * [MXS-114](https://mariadb.atlassian.net/browse/MXS-114): Disable recovery of disconnected slaves
|[MXS-112](https://mariadb.atlassian.net/browse/MXS-112)|Disable saving of session commands in the readwritesplit and schemarouter modules| * [MXS-73](https://mariadb.atlassian.net/browse/MXS-73): MaxScale uses nearly 100% CPU
|[MXS-114](https://mariadb.atlassian.net/browse/MXS-114)|Disable recovery of disconnected slaves| * [MXS-36](https://mariadb.atlassian.net/browse/MXS-36): bugzillaId-671: wrong message if SHOW DATABASES privilege is missing
|[MXS-73](https://mariadb.atlassian.net/browse/MXS-73)|MaxScale uses nearly 100% CPU | * [MXS-39](https://mariadb.atlassian.net/browse/MXS-39): bugzillaId-731:Boolean configuration parameters accept inconsistent parameters
|[MXS-36](https://mariadb.atlassian.net/browse/MXS-36)|bugzillaId-671: wrong message if SHOW DATABASES privilege is missing| * [MXS-64](https://mariadb.atlassian.net/browse/MXS-64): maxkeys and Maxpasswd do not produce informative error output
|[MXS-39](https://mariadb.atlassian.net/browse/MXS-39)|bugzillaId-731:Boolean configuration parameters accept inconsistent parameters| * [MXS-25](https://mariadb.atlassian.net/browse/MXS-25): bugzillaId-656: MySQL Monitor: claims that Master is available after master failure
|[MXS-64](https://mariadb.atlassian.net/browse/MXS-64)|maxkeys and Maxpasswd do not produce informative error output| * [MXS-82](https://mariadb.atlassian.net/browse/MXS-82): cmake warns when mariadb is compiled without mysql_release
|[MXS-25](https://mariadb.atlassian.net/browse/MXS-25)|bugzillaId-656: MySQL Monitor: claims that Master is available after master failure| * [MXS-69](https://mariadb.atlassian.net/browse/MXS-69): dbfwfilter should be pessimistic about rule syntax errors
|[MXS-82](https://mariadb.atlassian.net/browse/MXS-82)|cmake warns when mariadb is compiled without mysql_release| * [MXS-98](https://mariadb.atlassian.net/browse/MXS-98): regexfilter log
|[MXS-69](https://mariadb.atlassian.net/browse/MXS-69)|dbfwfilter should be pessimistic about rule syntax errors| * [MXS-28](https://mariadb.atlassian.net/browse/MXS-28): bugzillaId-433: Logging don't include assert information
|[MXS-98](https://mariadb.atlassian.net/browse/MXS-98)|regexfilter log| * [MXS-75](https://mariadb.atlassian.net/browse/MXS-75): "wildcard" rule also blocks COUNT(*)
|[MXS-28](https://mariadb.atlassian.net/browse/MXS-28)|bugzillaId-433: Logging don't include assert information| * [MXS-118](https://mariadb.atlassian.net/browse/MXS-118): Two monitors loaded at the same time result into not working installation
|[MXS-75](https://mariadb.atlassian.net/browse/MXS-75)|"wildcard" rule also blocks COUNT(*)| * [MXS-33](https://mariadb.atlassian.net/browse/MXS-33): bugzillaId-702: CLI: list services command shows negative values for the number of users of a service (Read Service).
|[MXS-118](https://mariadb.atlassian.net/browse/MXS-118)|Two monitors loaded at the same time result into not working installation| * [MXS-17](https://mariadb.atlassian.net/browse/MXS-17): bugzillaId-736: Memory leak while doing read/write splitting
|[MXS-33](https://mariadb.atlassian.net/browse/MXS-33)|bugzillaId-702: CLI: list services command shows negative values for the number of users of a service (Read Service).| * [MXS-30](https://mariadb.atlassian.net/browse/MXS-30): bugzillaId-487: Buffer manager should not use pointer arithmetic on void*
|[MXS-17](https://mariadb.atlassian.net/browse/MXS-17)|bugzillaId-736: Memory leak while doing read/write splitting| * [MXS-81](https://mariadb.atlassian.net/browse/MXS-81): cmake fails when init scripts are missing
|[MXS-30](https://mariadb.atlassian.net/browse/MXS-30)|bugzillaId-487: Buffer manager should not use pointer arithmetic on void*| * [MXS-127](https://mariadb.atlassian.net/browse/MXS-127): disable_sescmd_history causes MaxScale to crash under load
## Known Issues ## Known Issues
There are a number bugs and known limitations within this version of MaxScale, the most serious of this are listed below. There are a number bugs and known limitations within this version of MaxScale, the most serious of these are listed below.
* The Read/Write Splitter is a little too strict when it receives errors from slave servers during execution of session commands. This can result in sessions being terminated in situation in which MaxScale could recover without terminating the sessions. * The Read/Write Splitter is a little too strict when it receives errors from slave servers during execution of session commands. This can result in sessions being terminated in situations from which MaxScale could recover without terminating the sessions.
* MaxScale can not manage authentication that uses wildcard matching in hostnames in the mysql.user table of the backend database. The only wildcards that can be used are in IP address entries. * MaxScale cannot manage authentication that uses wildcard matching in hostnames in the mysql.user table of the backend database. The only wildcards that can be used are in IP address entries.
* When users have different passwords based on the host from which they connect MaxScale is unable to determine which password it should use to connect to the backend database. This results in failed connections and unusable usernames in MaxScale. * When users have different passwords based on the host from which they connect MaxScale is unable to determine which password it should use to connect to the backend database. This results in failed connections and unusable usernames in MaxScale.
* Binlog Router Plugin is compatible with MySQL 5.6 * Binlog Router Plugin is compatible with MySQL 5.6
Binlog Router Plugin currently does not work for MariaDB 5.5 and MariaDB 10.0 Binlog Router Plugin currently does not work for MariaDB 5.5 and MariaDB 10.0
* LONGBLOB are currently not supported. * LONGBLOB are currently not supported.
* Galera Cluster variables, such as @@wsrep_node_name, are not resolved by the embedded MariaDB parser. * Galera Cluster variables, such as @@wsrep_node_name, are not resolved by the embedded MariaDB parser.
@ -64,7 +65,7 @@ There are a number bugs and known limitations within this version of MaxScale, t
## Packaging ## Packaging
Both RPM and Debian packages are available for MaxScale in addition to the tar based releases previously distributed we now provide Both RPM and Debian packages are available for MaxScale in addition to the tar based releases. Packages are now provided for:
* CentOS/RedHat 5 * CentOS/RedHat 5

View File

@ -15,7 +15,7 @@ In almost all the cases these can be avoided by proper server configuration and
Here is an example configuration of the schemarouter router: Here is an example configuration of the schemarouter router:
``` ```
Shard Router] [Shard Router]
type=service type=service
router=schemarouter router=schemarouter
servers=server1,server2 servers=server1,server2

View File

@ -29,7 +29,7 @@ issues and communicate with the MaxScale community.
or use the [forum](http://groups.google.com/forum/#!forum/maxscale) interface or use the [forum](http://groups.google.com/forum/#!forum/maxscale) interface
Bugs can be reported in the MariaDB Corporation bugs database Bugs can be reported in the MariaDB Corporation bugs database
[https://mariadb.atlassian.net](https://mariadb.atlassian.net) under project MXS. [https://mariadb.atlassian.net/projects/MXS/issues](https://mariadb.atlassian.net/projects/MXS/issues)
# Documentation # Documentation

View File

@ -348,7 +348,7 @@ const char* get_err_suffix_default(void)
const char* get_logpath_default(void) const char* get_logpath_default(void)
{ {
return "/tmp"; return "/var/log/maxscale";
} }
static bool logmanager_init_nomutex( static bool logmanager_init_nomutex(

View File

@ -2039,6 +2039,7 @@ static char *monitor_params[] =
"passwd", "passwd",
"script", "script",
"events", "events",
"mysql51_replication",
"monitor_interval", "monitor_interval",
"detect_replication_lag", "detect_replication_lag",
"detect_stale_master", "detect_stale_master",

View File

@ -81,6 +81,7 @@ static void set_master_heartbeat(MYSQL_MONITOR *, MONITOR_SERVERS *);
static void set_slave_heartbeat(MONITOR *, MONITOR_SERVERS *); static void set_slave_heartbeat(MONITOR *, MONITOR_SERVERS *);
static int add_slave_to_master(long *, int, long); static int add_slave_to_master(long *, int, long);
bool isMySQLEvent(monitor_event_t event); bool isMySQLEvent(monitor_event_t event);
static bool report_version_err = true;
static MONITOR_OBJECT MyObject = { static MONITOR_OBJECT MyObject = {
startMonitor, startMonitor,
stopMonitor, stopMonitor,
@ -156,6 +157,7 @@ startMonitor(void *arg, void* opt)
handle->detectStaleMaster = 0; handle->detectStaleMaster = 0;
handle->master = NULL; handle->master = NULL;
handle->script = NULL; handle->script = NULL;
handle->mysql51_replication = false;
memset(handle->events,false,sizeof(handle->events)); memset(handle->events,false,sizeof(handle->events));
spinlock_init(&handle->lock); spinlock_init(&handle->lock);
} }
@ -199,6 +201,10 @@ startMonitor(void *arg, void* opt)
else else
have_events = true; have_events = true;
} }
else if(!strcmp(params->name,"mysql51_replication"))
{
handle->mysql51_replication = config_truth_value(params->value);
}
params = params->next; params = params->next;
} }
if(script_error) if(script_error)
@ -281,43 +287,16 @@ static void diagnostics(DCB *dcb, void *arg)
} }
dcb_printf(dcb, "\n"); dcb_printf(dcb, "\n");
} }
/** /**
* Monitor an individual server * Connect to a database
* * @param mon Monitor
* @param handle The MySQL Monitor object * @param database Monitored database
* @param database The database to probe * @return true if connection was successful, false if there was an error
*/ */
static void static inline bool connect_to_db(MONITOR* mon,MONITOR_SERVERS *database)
monitorDatabase(MONITOR *mon, MONITOR_SERVERS *database)
{ {
MYSQL_MONITOR* handle = mon->handle; char *uname = mon->user;
MYSQL_ROW row; char *passwd = mon->password;
MYSQL_RES *result;
int isslave = 0;
char *uname = mon->user;
char *passwd = mon->password;
unsigned long int server_version = 0;
char *server_string;
if (database->server->monuser != NULL)
{
uname = database->server->monuser;
passwd = database->server->monpw;
}
if (uname == NULL)
return;
/* Don't probe servers in maintenance mode */
if (SERVER_IN_MAINT(database->server))
return;
/** Store previous status */
database->mon_prev_status = database->server->status;
if (database->con == NULL || mysql_ping(database->con) != 0)
{
char *dpwd = decryptPassword(passwd); char *dpwd = decryptPassword(passwd);
int connect_timeout = mon->connect_timeout; int connect_timeout = mon->connect_timeout;
int read_timeout = mon->read_timeout; int read_timeout = mon->read_timeout;
@ -331,109 +310,21 @@ char *server_string;
mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout); mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout);
mysql_options(database->con, MYSQL_OPT_WRITE_TIMEOUT, (void *)&write_timeout); mysql_options(database->con, MYSQL_OPT_WRITE_TIMEOUT, (void *)&write_timeout);
if (mysql_real_connect(database->con, return (mysql_real_connect(database->con,
database->server->name, database->server->name,
uname, uname,
dpwd, dpwd,
NULL, NULL,
database->server->port, database->server->port,
NULL, NULL,
0) == NULL) 0) != NULL);
{ }
free(dpwd);
/* The current server is not running static inline void monitor_mysql100_db(MONITOR_SERVERS* database)
* {
* Store server NOT running in server and monitor server pending struct bool isslave = false;
* MYSQL_RES* result;
*/ MYSQL_ROW row;
if (mysql_errno(database->con) == ER_ACCESS_DENIED_ERROR)
{
server_set_status(database->server, SERVER_AUTH_ERROR);
monitor_set_pending_status(database, SERVER_AUTH_ERROR);
}
server_clear_status(database->server, SERVER_RUNNING);
monitor_clear_pending_status(database, SERVER_RUNNING);
/* Also clear M/S state in both server and monitor server pending struct */
server_clear_status(database->server, SERVER_SLAVE);
server_clear_status(database->server, SERVER_MASTER);
monitor_clear_pending_status(database, SERVER_SLAVE);
monitor_clear_pending_status(database, SERVER_MASTER);
/* Clean addition status too */
server_clear_status(database->server, SERVER_SLAVE_OF_EXTERNAL_MASTER);
server_clear_status(database->server, SERVER_STALE_STATUS);
monitor_clear_pending_status(database, SERVER_SLAVE_OF_EXTERNAL_MASTER);
monitor_clear_pending_status(database, SERVER_STALE_STATUS);
/* Log connect failure only once */
if (mon_status_changed(database) && mon_print_fail_status(database))
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Monitor was unable to connect to "
"server %s:%d : \"%s\"",
database->server->name,
database->server->port,
mysql_error(database->con))));
}
return;
}
else
{
server_clear_status(database->server, SERVER_AUTH_ERROR);
monitor_clear_pending_status(database, SERVER_AUTH_ERROR);
}
free(dpwd);
}
/* Store current status in both server and monitor server pending struct */
server_set_status(database->server, SERVER_RUNNING);
monitor_set_pending_status(database, SERVER_RUNNING);
/* get server version from current server */
server_version = mysql_get_server_version(database->con);
/* get server version string */
server_string = (char *)mysql_get_server_info(database->con);
if (server_string) {
database->server->server_string = realloc(database->server->server_string, strlen(server_string)+1);
if (database->server->server_string)
strcpy(database->server->server_string, server_string);
}
/* get server_id form current node */
if (mysql_query(database->con, "SELECT @@server_id") == 0
&& (result = mysql_store_result(database->con)) != NULL)
{
long server_id = -1;
if(mysql_field_count(database->con) != 1)
{
mysql_free_result(result);
skygw_log_write(LE,"Error: Unexpected result for \"SELECT @@server_id\". Expected 1 columns."
" MySQL Version: %s",version_str);
return;
}
while ((row = mysql_fetch_row(result)))
{
server_id = strtol(row[0], NULL, 10);
if ((errno == ERANGE && (server_id == LONG_MAX
|| server_id == LONG_MIN)) || (errno != 0 && server_id == 0))
{
server_id = -1;
}
database->server->node_id = server_id;
}
mysql_free_result(result);
}
/* Check if the Slave_SQL_Running and Slave_IO_Running status is
* set to Yes
*/
/* Check first for MariaDB 10.x.x and get status for multimaster replication */
if (server_version >= 100000) {
if (mysql_query(database->con, "SHOW ALL SLAVES STATUS") == 0 if (mysql_query(database->con, "SHOW ALL SLAVES STATUS") == 0
&& (result = mysql_store_result(database->con)) != NULL) && (result = mysql_store_result(database->con)) != NULL)
@ -483,7 +374,34 @@ char *server_string;
else else
isslave = 0; isslave = 0;
} }
/* Remove addition info */
monitor_clear_pending_status(database, SERVER_SLAVE_OF_EXTERNAL_MASTER);
monitor_clear_pending_status(database, SERVER_STALE_STATUS);
/* Please note, the MASTER status and SERVER_SLAVE_OF_EXTERNAL_MASTER
* will be assigned in the monitorMain() via get_replication_tree() routine
*/
/* Set the Slave Role */
if (isslave)
{
monitor_set_pending_status(database, SERVER_SLAVE);
/* Avoid any possible stale Master state */
monitor_clear_pending_status(database, SERVER_MASTER);
} else { } else {
/* Avoid any possible Master/Slave stale state */
monitor_clear_pending_status(database, SERVER_SLAVE);
monitor_clear_pending_status(database, SERVER_MASTER);
}
}
static inline void monitor_mysql55_db(MONITOR_SERVERS* database)
{
bool isslave = false;
MYSQL_RES* result;
MYSQL_ROW row;
if (mysql_query(database->con, "SHOW SLAVE STATUS") == 0 if (mysql_query(database->con, "SHOW SLAVE STATUS") == 0
&& (result = mysql_store_result(database->con)) != NULL) && (result = mysql_store_result(database->con)) != NULL)
{ {
@ -491,23 +409,9 @@ char *server_string;
if(mysql_field_count(database->con) < 40) if(mysql_field_count(database->con) < 40)
{ {
mysql_free_result(result); mysql_free_result(result);
if(server_version < 5*10000 + 5*100)
{
if(database->log_version_err)
{
skygw_log_write(LE,"Error: \"SHOW SLAVE STATUS\" "
" for versions less than 5.5 does not have master_server_id, "
"replication tree cannot be resolved for server %s."
" MySQL Version: %s",database->server->unique_name,version_str);
database->log_version_err = false;
}
}
else
{
skygw_log_write(LE,"Error: \"SHOW SLAVE STATUS\" " skygw_log_write(LE,"Error: \"SHOW SLAVE STATUS\" "
"returned less than the expected amount of columns. Expected 40 columns." "returned less than the expected amount of columns. Expected 40 columns."
" MySQL Version: %s",version_str); " MySQL Version: %s",version_str);
}
return; return;
} }
@ -536,6 +440,56 @@ char *server_string;
mysql_free_result(result); mysql_free_result(result);
} }
/* Remove addition info */
monitor_clear_pending_status(database, SERVER_SLAVE_OF_EXTERNAL_MASTER);
monitor_clear_pending_status(database, SERVER_STALE_STATUS);
/* Please note, the MASTER status and SERVER_SLAVE_OF_EXTERNAL_MASTER
* will be assigned in the monitorMain() via get_replication_tree() routine
*/
/* Set the Slave Role */
if (isslave)
{
monitor_set_pending_status(database, SERVER_SLAVE);
/* Avoid any possible stale Master state */
monitor_clear_pending_status(database, SERVER_MASTER);
} else {
/* Avoid any possible Master/Slave stale state */
monitor_clear_pending_status(database, SERVER_SLAVE);
monitor_clear_pending_status(database, SERVER_MASTER);
}
}
static inline void monitor_mysql51_db(MONITOR_SERVERS* database)
{
bool isslave = false;
MYSQL_RES* result;
MYSQL_ROW row;
if (mysql_query(database->con, "SHOW SLAVE STATUS") == 0
&& (result = mysql_store_result(database->con)) != NULL)
{
if(mysql_field_count(database->con) < 38)
{
mysql_free_result(result);
skygw_log_write(LE,"Error: \"SHOW SLAVE STATUS\" "
"returned less than the expected amount of columns. Expected 38 columns."
" MySQL Version: %s",version_str);
return;
}
while ((row = mysql_fetch_row(result)))
{
/* get Slave_IO_Running and Slave_SQL_Running values*/
if (strncmp(row[10], "Yes", 3) == 0
&& strncmp(row[11], "Yes", 3) == 0) {
isslave = 1;
}
}
mysql_free_result(result);
} }
/* Remove addition info */ /* Remove addition info */
@ -559,6 +513,247 @@ char *server_string;
} }
} }
/**
* Build the replication tree for a MySQL 5.1 cluster
*
* This function queries each server with SHOW SLAVE HOSTS to determine which servers
* have slaves replicating from them.
* @param mon Monitor
* @return Lowest server ID master in the monitor
*/
static MONITOR_SERVERS *build_mysql51_replication_tree(MONITOR *mon)
{
MONITOR_SERVERS* database = mon->databases;
MONITOR_SERVERS *ptr,*rval = NULL;
int i;
while(database)
{
bool ismaster = false;
MYSQL_RES* result;
MYSQL_ROW row;
int nslaves = 0;
if(database->con)
{
if (mysql_query(database->con, "SHOW SLAVE HOSTS") == 0
&& (result = mysql_store_result(database->con)) != NULL)
{
if(mysql_field_count(database->con) < 4)
{
mysql_free_result(result);
skygw_log_write_flush(LE,"Error: \"SHOW SLAVE HOSTS\" "
"returned less than the expected amount of columns. Expected 4 columns."
" MySQL Version: %s",version_str);
return NULL;
}
if(mysql_num_rows(result) > 0)
{
ismaster = true;
while (nslaves < MONITOR_MAX_NUM_SLAVES && (row = mysql_fetch_row(result)))
{
/* get Slave_IO_Running and Slave_SQL_Running values*/
database->server->slaves[nslaves] = atol(row[0]);
nslaves++;
LOGIF(LD,(skygw_log_write_flush(LD,"Found slave at %s:%d",row[1],row[2])));
}
database->server->slaves[nslaves] = 0;
}
mysql_free_result(result);
}
/* Set the Slave Role */
if (ismaster)
{
LOGIF(LD,(skygw_log_write(LD,"Master server found at %s:%d with %d slaves",
database->server->name,
database->server->port,
nslaves)));
monitor_set_pending_status(database, SERVER_MASTER);
if(rval == NULL || rval->server->node_id > database->server->node_id)
rval = database;
}
}
database = database->next;
}
database = mon->databases;
/** Set master server IDs */
while(database)
{
ptr = mon->databases;
while(ptr)
{
for(i = 0;ptr->server->slaves[i];i++)
{
if(ptr->server->slaves[i] == database->server->node_id)
{
database->server->master_id = ptr->server->node_id;
break;
}
}
ptr = ptr->next;
}
if(database->server->master_id <= 0 && SERVER_IS_SLAVE(database->server))
{
monitor_set_pending_status(database, SERVER_SLAVE_OF_EXTERNAL_MASTER);
}
database = database->next;
}
return rval;
}
/**
* Monitor an individual server
*
* @param handle The MySQL Monitor object
* @param database The database to probe
*/
static void
monitorDatabase(MONITOR *mon, MONITOR_SERVERS *database)
{
MYSQL_MONITOR* handle = mon->handle;
MYSQL_ROW row;
MYSQL_RES *result;
int isslave = 0;
char *uname = mon->user;
unsigned long int server_version = 0;
char *server_string;
if (database->server->monuser != NULL)
{
uname = database->server->monuser;
}
if (uname == NULL)
return;
/* Don't probe servers in maintenance mode */
if (SERVER_IN_MAINT(database->server))
return;
/** Store previous status */
database->mon_prev_status = database->server->status;
if (database->con == NULL || mysql_ping(database->con) != 0)
{
if(connect_to_db(mon,database))
{
server_clear_status(database->server, SERVER_AUTH_ERROR);
monitor_clear_pending_status(database, SERVER_AUTH_ERROR);
}
else
{
/* The current server is not running
*
* Store server NOT running in server and monitor server pending struct
*
*/
if (mysql_errno(database->con) == ER_ACCESS_DENIED_ERROR)
{
server_set_status(database->server, SERVER_AUTH_ERROR);
monitor_set_pending_status(database, SERVER_AUTH_ERROR);
}
server_clear_status(database->server, SERVER_RUNNING);
monitor_clear_pending_status(database, SERVER_RUNNING);
/* Also clear M/S state in both server and monitor server pending struct */
server_clear_status(database->server, SERVER_SLAVE);
server_clear_status(database->server, SERVER_MASTER);
monitor_clear_pending_status(database, SERVER_SLAVE);
monitor_clear_pending_status(database, SERVER_MASTER);
/* Clean addition status too */
server_clear_status(database->server, SERVER_SLAVE_OF_EXTERNAL_MASTER);
server_clear_status(database->server, SERVER_STALE_STATUS);
monitor_clear_pending_status(database, SERVER_SLAVE_OF_EXTERNAL_MASTER);
monitor_clear_pending_status(database, SERVER_STALE_STATUS);
/* Log connect failure only once */
if (mon_status_changed(database) && mon_print_fail_status(database))
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Monitor was unable to connect to "
"server %s:%d : \"%s\"",
database->server->name,
database->server->port,
mysql_error(database->con))));
}
return;
}
}
/* Store current status in both server and monitor server pending struct */
server_set_status(database->server, SERVER_RUNNING);
monitor_set_pending_status(database, SERVER_RUNNING);
/* get server version from current server */
server_version = mysql_get_server_version(database->con);
/* get server version string */
server_string = (char *)mysql_get_server_info(database->con);
if (server_string) {
database->server->server_string = realloc(database->server->server_string, strlen(server_string)+1);
if (database->server->server_string)
strcpy(database->server->server_string, server_string);
}
/* get server_id form current node */
if (mysql_query(database->con, "SELECT @@server_id") == 0
&& (result = mysql_store_result(database->con)) != NULL)
{
long server_id = -1;
if(mysql_field_count(database->con) != 1)
{
mysql_free_result(result);
skygw_log_write(LE,"Error: Unexpected result for 'SELECT @@server_id'. Expected 1 column."
" MySQL Version: %s",version_str);
return;
}
while ((row = mysql_fetch_row(result)))
{
server_id = strtol(row[0], NULL, 10);
if ((errno == ERANGE && (server_id == LONG_MAX
|| server_id == LONG_MIN)) || (errno != 0 && server_id == 0))
{
server_id = -1;
}
database->server->node_id = server_id;
}
mysql_free_result(result);
}
/* Check first for MariaDB 10.x.x and get status for multi-master replication */
if (server_version >= 100000)
{
monitor_mysql100_db(database);
}
else if(server_version >= 5*10000 + 5*100)
{
monitor_mysql55_db(database);
}
else
{
if(handle->mysql51_replication)
{
monitor_mysql51_db(database);
}
else if(report_version_err)
{
report_version_err = false;
skygw_log_write(LE,"Error: MySQL version is lower than 5.5 and 'mysql51_replication' option is not enabled,"
" replication tree cannot be resolved. To enable MySQL 5.1 replication detection, "
"add 'mysql51_replication=true' to the monitor section.");
}
}
}
/** /**
* The entry point for the monitoring module thread * The entry point for the monitoring module thread
* *
@ -723,7 +918,11 @@ detect_stale_master = handle->detectStaleMaster;
} }
} else { } else {
/* Compute the replication tree */ /* Compute the replication tree */
if(handle->mysql51_replication)
root_master = build_mysql51_replication_tree(mon);
else
root_master = get_replication_tree(mon, num_servers); root_master = get_replication_tree(mon, num_servers);
} }
/* Update server status from monitor pending status on that server*/ /* Update server status from monitor pending status on that server*/

View File

@ -67,6 +67,7 @@ typedef struct {
int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */ int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */
int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */ int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */
int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */ int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */
bool mysql51_replication; /**< Use MySQL 5.1 replication */
MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */ MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */
char* script; /*< Script to call when state changes occur on servers */ char* script; /*< Script to call when state changes occur on servers */
bool events[MAX_MONITOR_EVENT]; /*< enabled events */ bool events[MAX_MONITOR_EVENT]; /*< enabled events */

View File

@ -4049,12 +4049,11 @@ static bool execute_sescmd_in_backend(
sescmd_cursor_set_active(scur, true); sescmd_cursor_set_active(scur, true);
} }
buf = sescmd_cursor_clone_querybuf(scur);
switch (scur->scmd_cur_cmd->my_sescmd_packet_type) { switch (scur->scmd_cur_cmd->my_sescmd_packet_type) {
case MYSQL_COM_CHANGE_USER: case MYSQL_COM_CHANGE_USER:
/** This makes it possible to handle replies correctly */ /** This makes it possible to handle replies correctly */
gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD); gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD);
buf = sescmd_cursor_clone_querybuf(scur);
rc = dcb->func.auth( rc = dcb->func.auth(
dcb, dcb,
NULL, NULL,
@ -4087,6 +4086,7 @@ static bool execute_sescmd_in_backend(
*/ */
gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD); gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD);
buf = sescmd_cursor_clone_querybuf(scur);
rc = dcb->func.write( rc = dcb->func.write(
dcb, dcb,
buf); buf);