From 3030d6f39892fbf93bae7712aa7827752c8d5797 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 11 Jan 2016 17:34:36 +0200 Subject: [PATCH 01/18] Moved description of `weightby` to the correct section. The description was in router options instead of optional parameters. --- Documentation/Routers/ReadWriteSplit.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Documentation/Routers/ReadWriteSplit.md b/Documentation/Routers/ReadWriteSplit.md index 11ace959a..83076955d 100644 --- a/Documentation/Routers/ReadWriteSplit.md +++ b/Documentation/Routers/ReadWriteSplit.md @@ -77,6 +77,14 @@ When value all is used, queries reading session variables can be routed to any a In above-mentioned case the user-defined variable would only be updated in the master where query would be routed due to `INSERT` statement. +### `weightby` + +This parameter defines the name of the value which is used to calculate the +weights of the servers. The value should be the name of a parameter in the +server definitions and it should exist in all the servers used by this router. +For more information, see the description of the `weightby` parameter in +the [Configuration Guide](../Getting-Started/Configuration-Guide.md). + ## Router options **`router_options`** may include multiple **readwritesplit**-specific options. All the options are parameter-value pairs. All parameters listed in this section must be configured as a value in `router_options`. @@ -135,14 +143,6 @@ disable_sescmd_history=true master_accept_reads=true ``` -### `weightby` - -This parameter defines the name of the value which is used to calculate the -weights of the servers. The value should be the name of a parameter in the -server definitions and it should exist in all the servers used by this router. -For more information, see the description of the `weightby` parameter in -the [Configuration Guide](../Getting-Started/Configuration-Guide.md). - ## Routing hints The readwritesplit router supports routing hints. For a detailed guide on hint syntax and functionality, please read [this](../Reference/Hint-Syntax.md) document. From c1a906a60d17a444e0b69b49e01bf7c6c94d8788 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 19 Jan 2016 13:51:28 +0200 Subject: [PATCH 02/18] Remove beta status. Remove all references to beta. This is now 1.3.0. --- .../MaxScale-1.3.0-Release-Notes.md | 122 +++++++++--------- cmake/macros.cmake | 2 +- 2 files changed, 63 insertions(+), 61 deletions(-) diff --git a/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md index f4e7426db..9a8a45f05 100644 --- a/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md @@ -3,11 +3,7 @@ This document describes the changes in release 1.3, when compared to release 1.2.1. -## 1.3.0 Beta - -**NOTE** This is a beta release. We think it is better than 1.2.1, -but there may still be rough edges. Keep that in mind when trying it -out. +## 1.3.0 For any problems you encounter, please consider submitting a bug report at [Jira](https://mariadb.atlassian.net). @@ -149,85 +145,91 @@ details, please read the [Monitor Common](../Monitors/Monitor-Common.md) documen ## Bug fixes -Here is a list of bugs fixed since the release of MaxScale 1.2.1. +[Here is a list of bugs fixed since the release of MaxScale 1.2.1.](https://mariadb.atlassian.net/browse/MXS-550?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20resolution%20in%20(Fixed%2C%20Done)%20AND%20fixVersion%20%3D%201.3.0) - * [MXS-414](https://mariadb.atlassian.net/browse/MXS-414): Maxscale crashed every day! - * [MXS-415](https://mariadb.atlassian.net/browse/MXS-415): MaxScale 1.2.1 crashed with Signal 6 and 11 - * [MXS-351](https://mariadb.atlassian.net/browse/MXS-351): Router error handling can cause crash by leaving dangling DCB pointer - * [MXS-428](https://mariadb.atlassian.net/browse/MXS-428): Maxscale crashes at startup. - * [MXS-376](https://mariadb.atlassian.net/browse/MXS-376): MaxScale terminates with SIGABRT. - * [MXS-269](https://mariadb.atlassian.net/browse/MXS-269): Crash in MySQL backend protocol - * [MXS-500](https://mariadb.atlassian.net/browse/MXS-500): Tee filter hangs when statement aren't duplicated. - * [MXS-447](https://mariadb.atlassian.net/browse/MXS-447): Monitors are started before they have been fully configured - * [MXS-417](https://mariadb.atlassian.net/browse/MXS-417): Single character wildcard doesn't work in MaxScale - * [MXS-409](https://mariadb.atlassian.net/browse/MXS-409): prepare should not hit all servers - * [MXS-405](https://mariadb.atlassian.net/browse/MXS-405): Maxscale bin router crash - * [MXS-412](https://mariadb.atlassian.net/browse/MXS-412): show dbusers segmentation fault - * [MXS-289](https://mariadb.atlassian.net/browse/MXS-289): Corrupted memory or empty value are in Master_host field of SHOW SLAVE STATUS when master connection is broken - * [MXS-283](https://mariadb.atlassian.net/browse/MXS-283): SSL connections leak memory - * [MXS-54](https://mariadb.atlassian.net/browse/MXS-54): Write failed auth attempt to trace log - * [MXS-501](https://mariadb.atlassian.net/browse/MXS-501): Use hangs when Tee filter uses matching + * [MXS-508](https://mariadb.atlassian.net/browse/MXS-508): regex filter ignores username + * [MXS-505](https://mariadb.atlassian.net/browse/MXS-505): if Maxscale fails to start it goes to infinite "try-to-start and fail" loop + * [MXS-501](https://mariadb.atlassian.net/browse/MXS-501): USE hangs when Tee filter uses matching + * [MXS-500](https://mariadb.atlassian.net/browse/MXS-500): Tee filter hangs when statements aren't duplicated. * [MXS-499](https://mariadb.atlassian.net/browse/MXS-499): Init script error on Debian Wheezy - * [MXS-323](https://mariadb.atlassian.net/browse/MXS-323): mysql_client readwritesplit handleError seems using wrong dcb and cause wrong behavior * [MXS-494](https://mariadb.atlassian.net/browse/MXS-494): Weight calculation favors servers without connections * [MXS-493](https://mariadb.atlassian.net/browse/MXS-493): SIGFPE when weightby parameter is 0 and using LEAST_GLOBAL_CONNECTIONS * [MXS-492](https://mariadb.atlassian.net/browse/MXS-492): Segfault if server is missing weighting parameter - * [MXS-360](https://mariadb.atlassian.net/browse/MXS-360): Persistent connections: maxadmin reports 0 all the time even if connections are created - * [MXS-429](https://mariadb.atlassian.net/browse/MXS-429): Binlog Router crashes due to segmentation fault with no meaningful error if no listener is configured - * [MXS-416](https://mariadb.atlassian.net/browse/MXS-416): Orphan sessions appear after many network errors - * [MXS-472](https://mariadb.atlassian.net/browse/MXS-472): Monitors update status in multiple steps - * [MXS-361](https://mariadb.atlassian.net/browse/MXS-361): crash on backend restart if persistent connections are in use - * [MXS-403](https://mariadb.atlassian.net/browse/MXS-403): Monitor callback to DCBs evades thread control causing crashes - * [MXS-392](https://mariadb.atlassian.net/browse/MXS-392): Update to "Rabbit MQ setup and MaxScale Integration" document * [MXS-491](https://mariadb.atlassian.net/browse/MXS-491): MaxScale can time out systemd if startup of services takes too long - * [MXS-329](https://mariadb.atlassian.net/browse/MXS-329): The session pointer in a DCB can be null unexpectedly - * [MXS-479](https://mariadb.atlassian.net/browse/MXS-479): localtime must not be used in the multi-threaded program. * [MXS-480](https://mariadb.atlassian.net/browse/MXS-480): Readwritesplit defaults cause connection pileup + * [MXS-479](https://mariadb.atlassian.net/browse/MXS-479): localtime must not be used in the multi-threaded program. + * [MXS-472](https://mariadb.atlassian.net/browse/MXS-472): Monitors update status in multiple steps * [MXS-464](https://mariadb.atlassian.net/browse/MXS-464): Upgrade 1.2.0 to 1.2.1 blocking start of `maxscale` service - * [MXS-365](https://mariadb.atlassian.net/browse/MXS-365): Load data local infile connection abort when loading certain files + * [MXS-450](https://mariadb.atlassian.net/browse/MXS-450): Syslog default prefix is MaxScale not maxscale + * [MXS-447](https://mariadb.atlassian.net/browse/MXS-447): Monitors are started before they have been fully configured + * [MXS-436](https://mariadb.atlassian.net/browse/MXS-436): Invalid threads argument is ignored and MaxScale starts with one thread * [MXS-431](https://mariadb.atlassian.net/browse/MXS-431): Backend authentication fails with schemarouter - * [MXS-394](https://mariadb.atlassian.net/browse/MXS-394): Faults in regex_replace function of regexfilter.c - * [MXS-379](https://mariadb.atlassian.net/browse/MXS-379): Incorrect handing of a GWBUF may cause SIGABRT. - * [MXS-321](https://mariadb.atlassian.net/browse/MXS-321): Incorrect number of connections in maxadmin list view + * [MXS-429](https://mariadb.atlassian.net/browse/MXS-429): Binlog Router crashes due to segmentation fault with no meaningful error if no listener is configured + * [MXS-428](https://mariadb.atlassian.net/browse/MXS-428): Maxscale crashes at startup. + * [MXS-427](https://mariadb.atlassian.net/browse/MXS-427): Logging a large string causes a segmentation fault + * [MXS-417](https://mariadb.atlassian.net/browse/MXS-417): Single character wildcard doesn't work in MaxScale + * [MXS-416](https://mariadb.atlassian.net/browse/MXS-416): Orphan sessions appear after many network errors + * [MXS-415](https://mariadb.atlassian.net/browse/MXS-415): MaxScale 1.2.1 crashed with Signal 6 and 11 + * [MXS-414](https://mariadb.atlassian.net/browse/MXS-414): Maxscale crashed every day! * [MXS-413](https://mariadb.atlassian.net/browse/MXS-413): MaxAdmin hangs with show session + * [MXS-412](https://mariadb.atlassian.net/browse/MXS-412): show dbusers segmentation fault + * [MXS-409](https://mariadb.atlassian.net/browse/MXS-409): prepare should not hit all servers * [MXS-408](https://mariadb.atlassian.net/browse/MXS-408): Connections to backend databases do not clear promptly - * [MXS-385](https://mariadb.atlassian.net/browse/MXS-385): disable_sescmd_history can cause false data to be read. + * [MXS-407](https://mariadb.atlassian.net/browse/MXS-407): Maxscale binlogrouter binlog names are unncessarily length-limited + * [MXS-405](https://mariadb.atlassian.net/browse/MXS-405): Maxscale bin router crash + * [MXS-403](https://mariadb.atlassian.net/browse/MXS-403): Monitor callback to DCBs evades thread control causing crashes + * [MXS-394](https://mariadb.atlassian.net/browse/MXS-394): Faults in regex_replace function of regexfilter.c + * [MXS-392](https://mariadb.atlassian.net/browse/MXS-392): Update to "Rabbit MQ setup and MaxScale Integration" document * [MXS-386](https://mariadb.atlassian.net/browse/MXS-386): max_sescmd_history should not close connections + * [MXS-385](https://mariadb.atlassian.net/browse/MXS-385): disable_sescmd_history can cause false data to be read. + * [MXS-379](https://mariadb.atlassian.net/browse/MXS-379): Incorrect handing of a GWBUF may cause SIGABRT. + * [MXS-376](https://mariadb.atlassian.net/browse/MXS-376): MaxScale terminates with SIGABRT. * [MXS-373](https://mariadb.atlassian.net/browse/MXS-373): If config file is non-existent, maxscale crashes. * [MXS-366](https://mariadb.atlassian.net/browse/MXS-366): Multi-source slave servers are not detected. - * [MXS-271](https://mariadb.atlassian.net/browse/MXS-271): Schemarouter and unknown databases + * [MXS-365](https://mariadb.atlassian.net/browse/MXS-365): Load data local infile connection abort when loading certain files + * [MXS-363](https://mariadb.atlassian.net/browse/MXS-363): rpm building seems to do something wrong with maxscale libraries + * [MXS-361](https://mariadb.atlassian.net/browse/MXS-361): crash on backend restart if persistent connections are in use + * [MXS-360](https://mariadb.atlassian.net/browse/MXS-360): Persistent connections: maxadmin reports 0 all the time even if connections are created + * [MXS-358](https://mariadb.atlassian.net/browse/MXS-358): Crash, Error in `/usr/bin/maxscale': free(): invalid next size (fast) + * [MXS-352](https://mariadb.atlassian.net/browse/MXS-352): With no backend connection, services aren't started + * [MXS-351](https://mariadb.atlassian.net/browse/MXS-351): Router error handling can cause crash by leaving dangling DCB pointer + * [MXS-345](https://mariadb.atlassian.net/browse/MXS-345): maxscale.conf in /etc/init.d prevents puppet from starting maxscale + * [MXS-342](https://mariadb.atlassian.net/browse/MXS-342): When ini_parse fails to parse config file, no log messages are printed. + * [MXS-333](https://mariadb.atlassian.net/browse/MXS-333): use_sql_variables_in=master doesn't work + * [MXS-329](https://mariadb.atlassian.net/browse/MXS-329): The session pointer in a DCB can be null unexpectedly + * [MXS-323](https://mariadb.atlassian.net/browse/MXS-323): mysql_client readwritesplit handleError seems using wrong dcb and cause wrong behavior + * [MXS-321](https://mariadb.atlassian.net/browse/MXS-321): Incorrect number of connections in maxadmin list view + * [MXS-310](https://mariadb.atlassian.net/browse/MXS-310): MaxScale 1.2 does not completely cleanly change to the maxscale user + * [MXS-297](https://mariadb.atlassian.net/browse/MXS-297): postinstall on debian copies wrong file in /etc/init.d + * [MXS-293](https://mariadb.atlassian.net/browse/MXS-293): Bug in init script, and maxscale --user=maxscale does run as root + * [MXS-291](https://mariadb.atlassian.net/browse/MXS-291): Random number generation has flaws + * [MXS-289](https://mariadb.atlassian.net/browse/MXS-289): Corrupted memory or empty value are in Master_host field of SHOW SLAVE STATUS when master connection is broken * [MXS-286](https://mariadb.atlassian.net/browse/MXS-286): Fix the content and format of MaxScale-HA-with-Corosync-Pacemaker document + * [MXS-283](https://mariadb.atlassian.net/browse/MXS-283): SSL connections leak memory + * [MXS-282](https://mariadb.atlassian.net/browse/MXS-282): Add example to "Routing Hints" document + * [MXS-281](https://mariadb.atlassian.net/browse/MXS-281): SELECT INTO OUTFILE query goes several times to one slave + * [MXS-280](https://mariadb.atlassian.net/browse/MXS-280): SELECT INTO OUTFILE query succeeds even if backed fails + * [MXS-276](https://mariadb.atlassian.net/browse/MXS-276): Memory leak of buffer in connection router readQuery * [MXS-274](https://mariadb.atlassian.net/browse/MXS-274): Memory Leak + * [MXS-271](https://mariadb.atlassian.net/browse/MXS-271): Schemarouter and unknown databases + * [MXS-269](https://mariadb.atlassian.net/browse/MXS-269): Crash in MySQL backend protocol + * [MXS-260](https://mariadb.atlassian.net/browse/MXS-260): Multiple MaxScale processes + * [MXS-258](https://mariadb.atlassian.net/browse/MXS-258): ERR_error_string could overflow in future * [MXS-254](https://mariadb.atlassian.net/browse/MXS-254): Failure to read configuration file results in no error log messages * [MXS-251](https://mariadb.atlassian.net/browse/MXS-251): Non-thread safe strerror - * [MXS-291](https://mariadb.atlassian.net/browse/MXS-291): Random number generation has flaws - * [MXS-342](https://mariadb.atlassian.net/browse/MXS-342): When ini_parse fails to parse config file, no log messages are printed. - * [MXS-345](https://mariadb.atlassian.net/browse/MXS-345): maxscale.conf in /etc/init.d prevents puppet from starting maxscale - * [MXS-333](https://mariadb.atlassian.net/browse/MXS-333): use_sql_variables_in=master doesn't work - * [MXS-260](https://mariadb.atlassian.net/browse/MXS-260): Multiple MaxScale processes - * [MXS-184](https://mariadb.atlassian.net/browse/MXS-184): init script issues in CentOS 7 - * [MXS-280](https://mariadb.atlassian.net/browse/MXS-280): SELECT INTO OUTFILE query succeeds even if backed fails - * [MXS-202](https://mariadb.atlassian.net/browse/MXS-202): User password not handled correctly - * [MXS-282](https://mariadb.atlassian.net/browse/MXS-282): Add example to "Routing Hints" document * [MXS-220](https://mariadb.atlassian.net/browse/MXS-220): LAST_INSERT_ID() query is redirect to slave if function call is in where clause - * [MXS-196](https://mariadb.atlassian.net/browse/MXS-196): DCB state is changed prior to polling operation - * [MXS-281](https://mariadb.atlassian.net/browse/MXS-281): SELECT INTO OUTFILE query goes several times to one slave + * [MXS-210](https://mariadb.atlassian.net/browse/MXS-210): Check MaxScale user privileges + * [MXS-202](https://mariadb.atlassian.net/browse/MXS-202): User password not handled correctly * [MXS-197](https://mariadb.atlassian.net/browse/MXS-197): Incorrect sequence of operations with DCB + * [MXS-196](https://mariadb.atlassian.net/browse/MXS-196): DCB state is changed prior to polling operation * [MXS-195](https://mariadb.atlassian.net/browse/MXS-195): maxscaled.c ineffective DCB disposal - * [MXS-363](https://mariadb.atlassian.net/browse/MXS-363): rpm building seems to do something wrong with maxscale libraries + * [MXS-184](https://mariadb.atlassian.net/browse/MXS-184): init script issues in CentOS 7 + * [MXS-183](https://mariadb.atlassian.net/browse/MXS-183): MaxScale crash after 'reload config' + * [MXS-111](https://mariadb.atlassian.net/browse/MXS-111): maxscale binlog events shown in show services seems to be double-counted for the master connection + * [MXS-54](https://mariadb.atlassian.net/browse/MXS-54): Write failed auth attempt to trace log * [MXS-35](https://mariadb.atlassian.net/browse/MXS-35): bugzillaId-451: maxscale main() exit code is always 0 after it daemonizes * [MXS-29](https://mariadb.atlassian.net/browse/MXS-29): bugzillaId-589: detect if MAXSCALE_SCHEMA.HEARTBEAT table is not replicated - * [MXS-436](https://mariadb.atlassian.net/browse/MXS-436): Invalid threads argument is ignored and MaxScale starts with one thread - * [MXS-427](https://mariadb.atlassian.net/browse/MXS-427): Logging a large string causes a segmentation fault - * [MXS-352](https://mariadb.atlassian.net/browse/MXS-352): With no backend connection, services aren't started - * [MXS-293](https://mariadb.atlassian.net/browse/MXS-293): Bug in init script, and maxscale --user=maxscale does run as root - * [MXS-210](https://mariadb.atlassian.net/browse/MXS-210): Check MaxScale user privileges - * [MXS-111](https://mariadb.atlassian.net/browse/MXS-111): maxscale binlog events shown in show services seems to be double-counted for the master connection * [MXS-3](https://mariadb.atlassian.net/browse/MXS-3): Remove code for atomic_add in skygw_utils.cc - * [MXS-258](https://mariadb.atlassian.net/browse/MXS-258): ERR_error_string could overflow in future - * [MXS-310](https://mariadb.atlassian.net/browse/MXS-310): MaxScale 1.2 does not completely cleanly change to the maxscale user - * [MXS-450](https://mariadb.atlassian.net/browse/MXS-450): Syslog default prefix is MaxScale not maxscale - * [MXS-297](https://mariadb.atlassian.net/browse/MXS-297): postinstall on debian copies wrong file in /etc/init.d ## Known Issues and Limitations diff --git a/cmake/macros.cmake b/cmake/macros.cmake index 112e8dd37..f64654c6b 100644 --- a/cmake/macros.cmake +++ b/cmake/macros.cmake @@ -12,7 +12,7 @@ macro(set_maxscale_version) set(MAXSCALE_VERSION_MINOR "3") set(MAXSCALE_VERSION_PATCH "0") set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}") - set(MAXSCALE_VERSION "beta-${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}") + set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}") # This should be incremented each time a package is rebuilt set(MAXSCALE_BUILD_NUMBER 1) From b470ebe7325235a8440c7fdb11e4d9110e99810c Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 15 Jan 2016 16:38:15 +0200 Subject: [PATCH 03/18] Disabled `connection_timeout` because it's unsafe to use The current implementation of the session timeout functionality is not safe to use. Added a warning to the documentation and disabled the code. If the user tries to use it, a warning is logged. --- Documentation/Getting-Started/Configuration-Guide.md | 2 ++ .../Release-Notes/MaxScale-1.3.0-Release-Notes.md | 2 ++ server/core/service.c | 7 ++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index b8d836477..0eaccf800 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -467,6 +467,8 @@ MaxScale normally suppresses warning messages about failed authentication. Enabl #### `connection_timeout` +**NOTE**: This parameter is not safe to use in version 1.3.0. Please do not use it. + The connection_timeout parameter is used to disconnect sessions to MaxScale that have been idle for too long. The session timeouts are disabled by default. To enable them, define the timeout in seconds in the service's configuration section. Example: diff --git a/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md index 9a8a45f05..a19e76638 100644 --- a/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md @@ -236,6 +236,8 @@ details, please read the [Monitor Common](../Monitors/Monitor-Common.md) documen There are a number bugs and known limitations within this version of MaxScale, the most serious of this are listed below. +* The `connection_timeout` service parameter is not safe to use in version 1.3.0. + * 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. * 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. diff --git a/server/core/service.c b/server/core/service.c index 99674cf79..6c37a403f 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -66,6 +66,7 @@ #include #include #include +#include static RSA *rsa_512 = NULL; static RSA *rsa_1024 = NULL; @@ -1103,8 +1104,12 @@ serviceSetTimeout(SERVICE *service, int val) { return 0; } +#ifdef UNSAFE_CODE service->conn_timeout = val; - +#else + MXS_WARNING("The `connection_timeout` parameter is not safe for use. " + "The functionality is disabled for MaxScale "MAXSCALE_VERSION"."); +#endif return 1; } From e67ebffaff50bb8e1d39b522d062424d576ea6bf Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 19 Jan 2016 18:36:01 +0200 Subject: [PATCH 04/18] Updated help messages and manpage The manpage was out of date and was missing a BUGS section. The `--help` output of MaxScale wrongly stated that the default is to log to shared memory as did the documentation. --- .../Tutorials/Administration-Tutorial.md | 4 +-- Documentation/maxscale.1 | 29 ++++++++++++++----- server/core/gateway.c | 25 +++++++--------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/Documentation/Tutorials/Administration-Tutorial.md b/Documentation/Tutorials/Administration-Tutorial.md index bb05eb68d..1a9351775 100644 --- a/Documentation/Tutorials/Administration-Tutorial.md +++ b/Documentation/Tutorials/Administration-Tutorial.md @@ -33,7 +33,7 @@ Switch|Long Option|Description ------|-----------|----------- `-d`|`--nodaemon`|enable running in terminal process (default:disabled) `-f FILE`|`--config=FILE`|relative or absolute pathname of MaxScale configuration file (default:/etc/maxscale.cnf) -`-l[file shm]`|`--log=[file shm]`|log to file or shared memory (default: shm) +`-l[file shm]`|`--log=[file shm]`|log to file or shared memory (default: file) `-L PATH`|`--logdir=PATH`|path to log file directory (default: /var/log/maxscale) `-D PATH`|`--datadir=PATH`|path to data directory, stored embedded mysql tables (default: /var/cache/maxscale) `-C PATH`|`--configdir=PATH`|path to configuration file directory (default: /etc/) @@ -42,7 +42,7 @@ Switch|Long Option|Description `P PATH`|`--piddir=PATH`|PID file directory `-U USER`|`--user=USER`|run MaxScale as another user. The user ID and group ID of this user are used to run MaxScale. `-s [yes no]`|`--syslog=[yes no]`|log messages to syslog (default:yes) -`-S [yes no]`|`--maxscalelog=[yes no]`|log messages to MaxScale log (default: yes) +`-S [yes no]`|`--maxlog=[yes no]`|log messages to MaxScale log (default: yes) `-G [0 1]`|`--log_augmentation=[0 1]`|augment messages with the name of the function where the message was logged (default: 0). Primarily for development purposes. `-v`|`--version`|print version info and exit `-V`|`--version-full`|print version info and the commit ID the binary was built from diff --git a/Documentation/maxscale.1 b/Documentation/maxscale.1 index d24b3b47e..c835ad265 100644 --- a/Documentation/maxscale.1 +++ b/Documentation/maxscale.1 @@ -24,7 +24,7 @@ Run MaxScale in the terminal process Relative or absolute pathname of MaxScale configuration file to load. .TP .BR -l "[\fIfile|shm\fB], --log=[\fIfile|shm\fB]" -Log trace and debug logs to file or shared memory. The debug and trace logs are disabled by default and if enabled, will log to shared memory. +Log to file or shared memory. The default is to log to file. .TP .BR -L " \fIPATH\fB, --logdir=\fIPATH\fB" Path to log file directory. @@ -50,7 +50,7 @@ Run MaxScale as another user. The user ID and group ID of this user are used to .BR -s " [\fIyes\fB|\fIno\fB], --syslog=[\fIyes\fB|\fIno\fB]" Log messages to syslog. .TP -.BR -S " [\fIyes\fB|\fIno\fB], \fB--maxscalelog=[\fIyes\fB|\fIno\fB]" +.BR -S " [\fIyes\fB|\fIno\fB], \fB--maxlog=[\fIyes\fB|\fIno\fB]" Log messages to MaxScale's own log files. .TP .BR "-v, --version" @@ -61,12 +61,27 @@ Print full version information including the Git commit the binary was built fro .TP .BR "-?, --help" Show the help information for MaxScale and exit. - .SH EXAMPLES Tutorials on GitHub: -.UR https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Documentation-Contents.md#tutorials -.UE + +.RS +.I https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Documentation-Contents.md#tutorials +.RE .SH SEE ALSO +The MaxScale documentation on the MariaDB Knowledge Base: + +.RS +.I https://mariadb.com/kb/en/mariadb-enterprise/mariadb-maxscale/ +.RE + The MaxScale documentation on GitHub: -.UR https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Documentation-Contents.md -.UE + +.RS +.I https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Documentation-Contents.md +.RE +.SH BUGS +You can see a list of known bugs and report new bugs at: + +.RS +.I https://mariadb.atlassian.net/browse/MXS +.RE diff --git a/server/core/gateway.c b/server/core/gateway.c index 5aadda73f..0b6fadd6a 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -955,27 +955,24 @@ static void usage(void) fprintf(stderr, "\nUsage : %s [OPTION]...\n\n" " -d, --nodaemon enable running in terminal process (default:disabled)\n" - " -f, --config=FILE relative|absolute pathname of MaxScale configuration file\n" + " -f, --config=FILE relative or absolute pathname of MaxScale configuration file\n" " (default:/etc/maxscale.cnf)\n" - " -l, --log=[file|shm] log to file or shared memory (default: shm)\n" - " -L, --logdir=PATH path to log file directory\n" - " (default: /var/log/maxscale)\n" - " -A, --cachedir=PATH path to cache directory\n" - " (default: /var/cache/maxscale)\n" - " -B, --libdir=PATH path to module directory\n" - " (default: /usr/lib64/maxscale)\n" - " -C, --configdir=PATH path to configuration file directory\n" - " (default: /etc/)\n" + " -l, --log=[file|shm] log to file or shared memory (default: file)\n" + " -L, --logdir=PATH path to log file directory (default: /var/log/maxscale)\n" + " -A, --cachedir=PATH path to cache directory (default: /var/cache/maxscale)\n" + " -B, --libdir=PATH path to module directory (default: /usr/lib64/maxscale)\n" + " -C, --configdir=PATH path to configuration file directory (default: /etc/)\n" " -D, --datadir=PATH path to data directory, stored embedded mysql tables\n" " (default: /var/cache/maxscale)\n" - " -N, --language=PATH path to errmsg.sys file\n" - " (default: /var/lib/maxscale)\n" - " -P, --piddir=PATH path to PID file directory\n" - " (default: /var/run/maxscale)\n" + " -N, --language=PATH path to errmsg.sys file (default: /var/lib/maxscale)\n" + " -P, --piddir=PATH path to PID file directory (default: /var/run/maxscale)\n" " -U, --user=USER run MaxScale as another user.\n" " The user ID and group ID of this user are used to run MaxScale.\n" " -s, --syslog=[yes|no] log messages to syslog (default:yes)\n" " -S, --maxlog=[yes|no] log messages to MaxScale log (default: yes)\n" + " -G, --log_augmentation=0|1 augment messages with the name of the function where\n" + " the message was logged (default: 0). Primarily for \n" + " development purposes.\n" " -v, --version print version info and exit\n" " -V, --version-full print full version info and exit\n" " -?, --help show this help\n" From 8ba14ee4ee659d9387d34d6b407515db935d9955 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 19 Jan 2016 19:05:48 +0200 Subject: [PATCH 05/18] Fixed init script issue on Ubuntu The init script split the command and the arguments with double quotes causing the service to run as root instead of the maxscale user. --- etc/ubuntu/init.d/maxscale.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/ubuntu/init.d/maxscale.in b/etc/ubuntu/init.d/maxscale.in index 1589bac32..dd16a0f1f 100755 --- a/etc/ubuntu/init.d/maxscale.in +++ b/etc/ubuntu/init.d/maxscale.in @@ -48,7 +48,7 @@ _RETVAL_STATUS_NOT_RUNNING=3 ################################# NAME=maxscale DAEMON=@CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale -DAEMON_OPTS='"--user=maxscale" "$MAXSCALE_OPTIONS"' +DAEMON_OPTS="--user=maxscale $MAXSCALE_OPTIONS" # Source function library. . /lib/lsb/init-functions @@ -91,7 +91,7 @@ start() { chmod 0755 @MAXSCALE_VARDIR@/run/maxscale log_daemon_msg "Starting MaxScale" - start_daemon -p "$MAXSCALE_PIDFILE" "$DAEMON" "$DAEMON_OPTS" 2> /dev/null > /dev/null + start_daemon -p "$MAXSCALE_PIDFILE" $DAEMON $DAEMON_OPTS 2> /dev/null > /dev/null sleep 2 From 99f39cb213511b95552c49052e77a12e46090129 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 21 Jan 2016 10:02:59 +0200 Subject: [PATCH 06/18] MXS-548: Added missing locks to shared session data The shared session data was accessed and modified without a lock. --- server/modules/protocol/mysql_backend.c | 171 +++++++++++++----------- 1 file changed, 91 insertions(+), 80 deletions(-) diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 94e59f25a..64e7c3d38 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -77,7 +77,7 @@ static bool sescmd_response_complete(DCB* dcb); #if defined(NOT_USED) static int gw_session(DCB *backend_dcb, void *data); #endif -static MYSQL_session* gw_get_shared_session_auth_info(DCB* dcb); +static bool gw_get_shared_session_auth_info(DCB* dcb, MYSQL_session* session); static GWPROTOCOL MyObject = { gw_read_backend_event, /* Read - EPOLLIN handler */ @@ -128,28 +128,35 @@ GetModuleObject() } -static MYSQL_session* gw_get_shared_session_auth_info( - DCB* dcb) +/** + * Copy shared session authentication info + * + * @param dcb A backend DCB + * @param session Destination where authentication data is copied + */ +static bool gw_get_shared_session_auth_info(DCB* dcb, MYSQL_session* session) { - MYSQL_session* auth_info = NULL; - CHK_DCB(dcb); - CHK_SESSION(dcb->session); + bool rval = true; + CHK_DCB(dcb); + CHK_SESSION(dcb->session); - spinlock_acquire(&dcb->session->ses_lock); + spinlock_acquire(&dcb->session->ses_lock); - if (dcb->session->state != SESSION_STATE_ALLOC && dcb->session->state != SESSION_STATE_DUMMY) { - auth_info = dcb->session->data; - } else { - MXS_ERROR("%lu [gw_get_shared_session_auth_info] Couldn't get " - "session authentication info. Session in a wrong state %d.", - pthread_self(), - dcb->session->state); - } - spinlock_release(&dcb->session->ses_lock); - - return auth_info; + if (dcb->session->state != SESSION_STATE_ALLOC && + dcb->session->state != SESSION_STATE_DUMMY) + { + memcpy(session, dcb->session->data, sizeof(MYSQL_session)); + } + else + { + MXS_ERROR("%lu [gw_get_shared_session_auth_info] Couldn't get " + "session authentication info. Session in a wrong state %d.", + pthread_self(), dcb->session->state); + rval = false; + } + spinlock_release(&dcb->session->ses_lock); + return rval; } - /** * Backend Read Event for EPOLLIN on the MySQL backend protocol module * @param dcb The backend Descriptor Control Block @@ -158,7 +165,7 @@ static MYSQL_session* gw_get_shared_session_auth_info( static int gw_read_backend_event(DCB *dcb) { MySQLProtocol *client_protocol = NULL; MySQLProtocol *backend_protocol = NULL; - MYSQL_session *current_session = NULL; + MYSQL_session local_session; int rc = 0; CHK_DCB(dcb); @@ -176,8 +183,10 @@ static int gw_read_backend_event(DCB *dcb) { CHK_SESSION(dcb->session); /*< return only with complete session */ - current_session = gw_get_shared_session_auth_info(dcb); - ss_dassert(current_session != NULL); + if (!gw_get_shared_session_auth_info(dcb, &local_session)) + { + goto return_rc; + } backend_protocol = (MySQLProtocol *) dcb->protocol; CHK_PROTOCOL(backend_protocol); @@ -229,9 +238,9 @@ static int gw_read_backend_event(DCB *dcb) { * to backend. */ if (gw_send_authentication_to_backend( - current_session->db, - current_session->user, - current_session->client_sha1, + local_session.db, + local_session.user, + local_session.client_sha1, backend_protocol) != 0) { backend_protocol->protocol_auth_state = MYSQL_AUTH_FAILED; @@ -304,7 +313,7 @@ static int gw_read_backend_event(DCB *dcb) { MXS_ERROR("Backend server didn't " "accept authentication for user " "%s.", - current_session->user); + local_session.user); break; case 1: backend_protocol->protocol_auth_state = MYSQL_IDLE; @@ -315,7 +324,7 @@ static int gw_read_backend_event(DCB *dcb) { pthread_self(), dcb, dcb->fd, - current_session->user); + local_session.user); break; default: ss_dassert(receive_rc == 0); @@ -326,7 +335,7 @@ static int gw_read_backend_event(DCB *dcb) { pthread_self(), dcb, dcb->fd, - current_session->user); + local_session.user); rc = 0; goto return_with_lock; break; @@ -416,7 +425,7 @@ static int gw_read_backend_event(DCB *dcb) { "user %s.", pthread_self(), dcb->fd, - current_session->user); + local_session.user); /* check the delay queue and flush the data */ if (dcb->delayq) @@ -540,7 +549,7 @@ static int gw_read_backend_event(DCB *dcb) { "Read buffer unexpectedly null, even though response " "not marked as complete. User: %s", pthread_self(), - current_session->user); + local_session.user); rc = 0; goto return_rc; } @@ -1236,23 +1245,21 @@ static int backend_write_delayqueue(DCB *dcb) dcb->delayq = NULL; spinlock_release(&dcb->delayqlock); - if (MYSQL_IS_CHANGE_USER(((uint8_t *)GWBUF_DATA(localq)))) - { - MYSQL_session* mses; - GWBUF* new_packet; - - mses = (MYSQL_session *)dcb->session->client->data; - new_packet = gw_create_change_user_packet( - mses, - (MySQLProtocol *)dcb->protocol); - /** - * Remove previous packet which lacks scramble - * and append the new. - */ - localq = gwbuf_consume(localq, GWBUF_LENGTH(localq)); - localq = gwbuf_append(localq, new_packet); - } - rc = dcb_write(dcb, localq); + if (MYSQL_IS_CHANGE_USER(((uint8_t *)GWBUF_DATA(localq)))) + { + MYSQL_session mses; + GWBUF* new_packet; + + gw_get_shared_session_auth_info(dcb, &mses); + new_packet = gw_create_change_user_packet( &mses, dcb->protocol); + /** + * Remove previous packet which lacks scramble + * and append the new. + */ + localq = gwbuf_consume(localq, GWBUF_LENGTH(localq)); + localq = gwbuf_append(localq, new_packet); + } + rc = dcb_write(dcb, localq); } if (rc == 0) @@ -1366,43 +1373,47 @@ static int gw_change_user( if (client_auth_packet && *client_auth_packet) memcpy(&backend_protocol->charset, client_auth_packet, sizeof(int)); - /* save current_database name */ - strncpy(current_database, current_session->db,MYSQL_DATABASE_MAXLEN); + spinlock_acquire(&in_session->ses_lock); - /* - * Now clear database name in dcb as we don't do local authentication on db name for change user. - * Local authentication only for user@host and if successful the database name change is sent to backend. - */ - strcpy(current_session->db, ""); + /* save current_database name */ + strncpy(current_database, current_session->db, MYSQL_DATABASE_MAXLEN); - /* - * decode the token and check the password. - * Note: if auth_token_len == 0 && auth_token == NULL, user is without password - */ - auth_ret = gw_check_mysql_scramble_data(backend->session->client, - auth_token, - auth_token_len, - client_protocol->scramble, - sizeof(client_protocol->scramble), - username, - client_sha1); + /* + * Now clear database name in dcb as we don't do local authentication on db name for change user. + * Local authentication only for user@host and if successful the database name change is sent to backend. + */ + strncpy(current_session->db, "", MYSQL_DATABASE_MAXLEN); - if (auth_ret != 0) { - if (!service_refresh_users(backend->session->client->service)) { - /* Try authentication again with new repository data */ - /* Note: if no auth client authentication will fail */ - auth_ret = gw_check_mysql_scramble_data( - backend->session->client, - auth_token, auth_token_len, - client_protocol->scramble, - sizeof(client_protocol->scramble), - username, - client_sha1); - } - } + /* + * Decode the token and check the password. + * Note: if auth_token_len == 0 && auth_token == NULL, user is without password + */ + auth_ret = gw_check_mysql_scramble_data(backend->session->client, + auth_token, auth_token_len, + client_protocol->scramble, + sizeof (client_protocol->scramble), + username, client_sha1); + strncpy(current_session->db, current_database, MYSQL_DATABASE_MAXLEN); + spinlock_release(&in_session->ses_lock); - /* copy back current datbase to client session */ - strcpy(current_session->db, current_database); + if (auth_ret != 0) + { + if (service_refresh_users(backend->session->client->service) == 0) + { + /* Try authentication again with new repository data */ + /* Note: if no auth client authentication will fail */ + spinlock_acquire(&in_session->ses_lock); + strncpy(current_session->db, "", MYSQL_DATABASE_MAXLEN); + auth_ret = gw_check_mysql_scramble_data( + backend->session->client, + auth_token, auth_token_len, + client_protocol->scramble, + sizeof (client_protocol->scramble), + username, client_sha1); + strncpy(current_session->db, current_database, MYSQL_DATABASE_MAXLEN); + spinlock_release(&in_session->ses_lock); + } + } /* let's free the auth_token now */ if (auth_token) From 087ab202c28131e1f571d8cdb24e3a1febb4eac1 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 26 Jan 2016 14:48:01 +0200 Subject: [PATCH 07/18] MXS-559: Fixed unsafe use of the master DCB in readwritesplit The master DCB was used without checking if it was still open. It was possible that the master DCB was closed and processed before the client had fully processed all queries which caused it to fail at a debug assertion. The fix to this is to use the client's DCB to get access to the shared session authentication data as it is protected by additional locks. --- .../routing/readwritesplit/readwritesplit.c | 63 +++---------------- 1 file changed, 10 insertions(+), 53 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 6be727e56..f1f5eb72d 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -1567,8 +1567,6 @@ void check_drop_tmp_table( char** tbl = NULL; char *hkey,*dbname; MYSQL_session* data; - - DCB* master_dcb = NULL; rses_property_t* rses_prop_tmp; if(router_cli_ses == NULL || querybuf == NULL) @@ -1578,27 +1576,14 @@ void check_drop_tmp_table( return; } - if(router_cli_ses->rses_master_ref == NULL) + if(router_cli_ses->client_dcb == NULL) { - MXS_ERROR("[%s] Error: Master server reference is NULL.", - __FUNCTION__); + MXS_ERROR("[%s] Error: Client DCB is NULL.", __FUNCTION__); return; } rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES]; - master_dcb = router_cli_ses->rses_master_ref->bref_dcb; - - if(master_dcb == NULL || master_dcb->session == NULL) - { - MXS_ERROR("[%s] Error: Master server DBC is NULL. " - "This means that the connection to the master server is already " - "closed while a query is still being routed.",__FUNCTION__); - return; - } - - CHK_DCB(master_dcb); - - data = (MYSQL_session*)master_dcb->session->data; + data = (MYSQL_session*)router_cli_ses->client_dcb->session->data; if(data == NULL) { @@ -1657,8 +1642,6 @@ static skygw_query_type_t is_read_tmp_table( char *dbname; char hkey[MYSQL_DATABASE_MAXLEN+MYSQL_TABLE_MAXLEN+2]; MYSQL_session* data; - - DCB* master_dcb = NULL; skygw_query_type_t qtype = type; rses_property_t* rses_prop_tmp; @@ -1669,30 +1652,18 @@ static skygw_query_type_t is_read_tmp_table( return type; } - if(router_cli_ses->rses_master_ref == NULL) + if(router_cli_ses->client_dcb == NULL) { - MXS_ERROR("[%s] Error: Master server reference is NULL.", - __FUNCTION__); + MXS_ERROR("[%s] Error: Client DCB is NULL.", __FUNCTION__); return type; } rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES]; - master_dcb = router_cli_ses->rses_master_ref->bref_dcb; - - if(master_dcb == NULL || master_dcb->session == NULL) - { - MXS_ERROR("[%s] Error: Master server DBC is NULL. " - "This means that the connection to the master server is already " - "closed while a query is still being routed.",__FUNCTION__); - return qtype; - } - CHK_DCB(master_dcb); - - data = (MYSQL_session*)master_dcb->session->data; + data = (MYSQL_session*)router_cli_ses->client_dcb->session->data; if(data == NULL) { - MXS_ERROR("[%s] Error: User data in master server DBC is NULL.",__FUNCTION__); + MXS_ERROR("[%s] Error: User data in client DBC is NULL.",__FUNCTION__); return qtype; } @@ -1758,7 +1729,6 @@ static void check_create_tmp_table( int klen = 0; char *hkey,*dbname; MYSQL_session* data; - DCB* master_dcb = NULL; rses_property_t* rses_prop_tmp; HASHTABLE* h; @@ -1769,27 +1739,14 @@ static void check_create_tmp_table( return; } - if(router_cli_ses->rses_master_ref == NULL) + if(router_cli_ses->client_dcb == NULL) { - MXS_ERROR("[%s] Error: Master server reference is NULL.", - __FUNCTION__); + MXS_ERROR("[%s] Error: Client DCB is NULL.", __FUNCTION__); return; } rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES]; - master_dcb = router_cli_ses->rses_master_ref->bref_dcb; - - if(master_dcb == NULL || master_dcb->session == NULL) - { - MXS_ERROR("[%s] Error: Master server DCB is NULL. " - "This means that the connection to the master server is already " - "closed while a query is still being routed.",__FUNCTION__); - return; - } - - CHK_DCB(master_dcb); - - data = (MYSQL_session*)master_dcb->session->data; + data = (MYSQL_session*)router_cli_ses->client_dcb->session->data; if(data == NULL) { From e6d18f0b664840b529676ad285c12de29968dd88 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 28 Jan 2016 10:46:55 +0200 Subject: [PATCH 08/18] Fixed debug assertion causing a crash in readwritesplit A debug assertion in the readwritesplit would always fail when the master DCB was NULL. This was caused by the fact that the debug assertion assumes that the pointer that is passed to it is a valid pointer. --- 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 f1f5eb72d..fd78ad720 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -2052,7 +2052,6 @@ static bool route_single_stmt( if ((master_dcb = rses->rses_master_ref->bref_dcb) == NULL) { char* query_str = modutil_get_query(querybuf); - CHK_DCB(master_dcb); MXS_ERROR("Can't route %s:%s:\"%s\" to " "backend server. Session doesn't have a Master " "node", @@ -2064,6 +2063,7 @@ static bool route_single_stmt( goto retblock; } + CHK_DCB(master_dcb); packet = GWBUF_DATA(querybuf); packet_len = gw_mysql_get_byte3(packet); From 379004a2a45ac2fa0713700b994a96ea6b11d9ff Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 28 Jan 2016 13:04:23 +0200 Subject: [PATCH 09/18] Removed corrupted error messages from readwritesplit When a slave server fails to execute a session command, the log message printed the command that was being executed as if the ERR packet was a COM_QUERY packet. This caused corrupt strings to be printed into the error logs. --- server/modules/routing/readwritesplit/readwritesplit.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index fd78ad720..feb908e59 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -2793,21 +2793,17 @@ static void clientReply ( uint8_t* replybuf = (uint8_t *)GWBUF_DATA(writebuf); size_t len = MYSQL_GET_PACKET_LEN(buf); size_t replylen = MYSQL_GET_PACKET_LEN(replybuf); - char* cmdstr = strndup(&((char *)buf)[5], len-4); char* err = strndup(&((char *)replybuf)[8], 5); char* replystr = strndup(&((char *)replybuf)[13], replylen-4-5); ss_dassert(len+4 == GWBUF_LENGTH(scur->scmd_cur_cmd->my_sescmd_buf)); - MXS_ERROR("Failed to execute %s in %s:%d. %s %s", - cmdstr, + MXS_ERROR("Failed to execute session command in %s:%d. Error was: %s %s", bref->bref_backend->backend_server->name, bref->bref_backend->backend_server->port, err, replystr); - - free(cmdstr); free(err); free(replystr); } From 74281401d8e3e329abbfa207ec955fce41b81981 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 28 Jan 2016 18:52:46 +0200 Subject: [PATCH 10/18] Added missing option for getopt The --language short option -N did not work and the errmsg.sys file was always searched for in the wrong place. --- server/core/gateway.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/core/gateway.c b/server/core/gateway.c index 0b6fadd6a..6f07e4895 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -1079,7 +1079,7 @@ int main(int argc, char **argv) } } - while ((opt = getopt_long(argc, argv, "dc:f:l:vVs:S:?L:D:C:B:U:A:P:G:", + while ((opt = getopt_long(argc, argv, "dc:f:l:vVs:S:?L:D:C:B:U:A:P:G:N:", long_options, &option_index)) != -1) { bool succp = true; From e3ebf19ca0d7a719d96b96bfa060551b4a6cf2f3 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 29 Jan 2016 10:59:25 +0200 Subject: [PATCH 11/18] Moved HA tutorials to the Tutorials folder The Corosync/Pacemaker and Lsyncd tutorials were in the reference folder even though they are tutorials. --- Documentation/Documentation-Contents.md | 9 ++++++--- .../MaxScale-HA-with-Corosync-Pacemaker.md | 4 ++-- .../{Reference => Tutorials}/MaxScale-HA-with-lsyncd.md | 0 3 files changed, 8 insertions(+), 5 deletions(-) rename Documentation/{Reference => Tutorials}/MaxScale-HA-with-Corosync-Pacemaker.md (98%) rename Documentation/{Reference => Tutorials}/MaxScale-HA-with-lsyncd.md (100%) diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index 5e4105f69..666589988 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -27,8 +27,6 @@ ## Reference - [MaxAdmin](Reference/MaxAdmin.md) - - [MaxScale HA with Corosync-Pacemaker](Reference/MaxScale-HA-with-Corosync-Pacemaker.md) - - [MaxScale HA with Lsyncd](Reference/MaxScale-HA-with-lsyncd.md) - [How Errors are Handled in MaxScale](Reference/How-errors-are-handled-in-MaxScale.md) - [Debug and Diagnostic Support](Reference/Debug-And-Diagnostic-Support.md) - [Routing Hints](Reference/Hint-Syntax.md) @@ -48,9 +46,14 @@ These tutorials are for specific use cases and module combinations. - [Replication Proxy with the Binlog Router Tutorial](Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md) - [RabbitMQ Setup and MaxScale Integration Tutorial](Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md) - [RabbitMQ and Tee Filter Data Archiving Tutorial](Tutorials/RabbitMQ-And-Tee-Archiving.md) - - [Nagios Plugins for MaxScale Tutorial](Tutorials/Nagios-Plugins.md) - [Simple Schema Sharding Tutorial](Tutorials/Simple-Sharding-Tutorial.md) +Here are tutorials on monitoring and managing MaxScale in cluster envoronments. + + - [Nagios Plugins for MaxScale Tutorial](Tutorials/Nagios-Plugins.md) + - [MaxScale HA with Corosync-Pacemaker](Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md) + - [MaxScale HA with Lsyncd](Tutorials/MaxScale-HA-with-lsyncd.md) + ## Routers The routing module is the core of a MaxScale service. The router documentation diff --git a/Documentation/Reference/MaxScale-HA-with-Corosync-Pacemaker.md b/Documentation/Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md similarity index 98% rename from Documentation/Reference/MaxScale-HA-with-Corosync-Pacemaker.md rename to Documentation/Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md index 873af6b68..75ffe34dd 100644 --- a/Documentation/Reference/MaxScale-HA-with-Corosync-Pacemaker.md +++ b/Documentation/Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md @@ -79,7 +79,7 @@ On one of the nodes, say node2 run the corosync-keygen utility and follow ``` [root@node2 ~]# corosync-keygen -Corosync Cluster Engine Authentication key generator. Gathering 1024 bits for key from /dev/random. Press keys on your keyboard to generate entropy. +Corosync Cluster Engine Authentication key generator. Gathering 1024 bits for key from /dev/random. Press keys on your keyboard to generate entropy. After completion the key will be found in /etc/corosync/authkey. ``` @@ -141,7 +141,7 @@ name: pacemaker } ``` -**Please note **in this example: +**Please note** in this example: - unicast UDP is used diff --git a/Documentation/Reference/MaxScale-HA-with-lsyncd.md b/Documentation/Tutorials/MaxScale-HA-with-lsyncd.md similarity index 100% rename from Documentation/Reference/MaxScale-HA-with-lsyncd.md rename to Documentation/Tutorials/MaxScale-HA-with-lsyncd.md From 889a90fb42abd1b1dabc894c134508ba139a21ee Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 1 Feb 2016 10:24:35 +0200 Subject: [PATCH 12/18] Update 1.3.0 release note. --- .../Release-Notes/MaxScale-1.3.0-Release-Notes.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md index a19e76638..dcbe0c66a 100644 --- a/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.3.0-Release-Notes.md @@ -147,6 +147,9 @@ details, please read the [Monitor Common](../Monitors/Monitor-Common.md) documen [Here is a list of bugs fixed since the release of MaxScale 1.2.1.](https://mariadb.atlassian.net/browse/MXS-550?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20resolution%20in%20(Fixed%2C%20Done)%20AND%20fixVersion%20%3D%201.3.0) + * [MXS-559](https://mariadb.atlassian.net/browse/MXS-559): Crash due to debug assertion in readwritesplit + * [MXS-551](https://mariadb.atlassian.net/browse/MXS-551): Maxscale BETA 1.3.0 running as root + * [MXS-548](https://mariadb.atlassian.net/browse/MXS-548): Maxscale 1.2.1 crash on Ubuntu 4.04.3 x86_64 * [MXS-508](https://mariadb.atlassian.net/browse/MXS-508): regex filter ignores username * [MXS-505](https://mariadb.atlassian.net/browse/MXS-505): if Maxscale fails to start it goes to infinite "try-to-start and fail" loop * [MXS-501](https://mariadb.atlassian.net/browse/MXS-501): USE hangs when Tee filter uses matching @@ -250,6 +253,10 @@ the most serious of this are listed below. * The SSL support is known to be unstable. +* Importing a large dump via readwritesplit may fail. + + Workaround is to bypass MaxScale when importing or to use the readconn router. + ## Packaging RPM and Debian packages are provided for the Linux distributions supported From ba2dbffdbe43c83b53c5f34fdacb6c3112bc4d00 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 1 Feb 2016 10:52:52 +0200 Subject: [PATCH 13/18] Update authentication limitations. --- Documentation/Getting-Started/Configuration-Guide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index 0eaccf800..9ae2fcf29 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -773,6 +773,8 @@ and short notations 192.%.% 192.168.% +Note that currently wildcards are only supported in conjunction with IP-addresses, not with domain names. + ## Error Reporting MaxScale is designed to be executed as a service, therefore all error reports, including configuration errors, are written to the MaxScale error log file. By default, MaxScale will log to a file in `/var/log/maxscale`, the only exception to this is if the log directory is not writable, in which case a message is sent to the standard error descriptor. From e7fb2640d3accb07ec00057a0d5258d0cb9d8a75 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 3 Feb 2016 00:47:06 +0200 Subject: [PATCH 14/18] Fixed authentication failing due to unknown database even though it exists When the shard maps are being updated they are set into a stale state. This means that one client connection is updating the shard maps and the information in the shard map is not the most recent. This does mean that the information is valid and authentication should succeed even if the shard map is stale. --- server/modules/routing/schemarouter/schemarouter.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index 6173750f3..65af533cc 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -1805,7 +1805,7 @@ bool send_database_list(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client) { bool rval = false; spinlock_acquire(&client->shardmap->lock); - if (client->shardmap->state == SHMAP_READY) + if (client->shardmap->state != SHMAP_UNINIT) { struct string_array strarray; const int size = hashtable_size(client->shardmap->hash); @@ -1888,11 +1888,6 @@ static int routeQuery( char errbuf[26+MYSQL_DATABASE_MAXLEN]; CHK_CLIENT_RSES(router_cli_ses); - /** Dirty read for quick check if router is closed. */ - if (router_cli_ses->rses_closed) - { - rses_is_closed = true; - } ss_dassert(!GWBUF_IS_TYPE_UNDEFINED(querybuf)); if (!rses_begin_locked_router_action(router_cli_ses)) @@ -4398,7 +4393,7 @@ int process_show_shards(ROUTER_CLIENT_SES* rses) int rval = 0; spinlock_acquire(&rses->shardmap->lock); - if(rses->shardmap->state == SHMAP_READY) + if(rses->shardmap->state != SHMAP_UNINIT) { HASHITERATOR* iter = hashtable_iterator(rses->shardmap->hash); struct shard_list sl; @@ -4465,7 +4460,7 @@ bool handle_default_db(ROUTER_CLIENT_SES *router_cli_ses) char* target = NULL; spinlock_acquire(&router_cli_ses->shardmap->lock); - if(router_cli_ses->shardmap->state == SHMAP_READY) + if(router_cli_ses->shardmap->state != SHMAP_UNINIT) { target = hashtable_fetch(router_cli_ses->shardmap->hash, router_cli_ses->connect_db); } From d9eeb72198491496dfb8fcdfc701a82664ff6297 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 2 Feb 2016 21:17:45 +0200 Subject: [PATCH 15/18] Added missing check for closed master backend reference into readwritesplit The master DCB was checked for NULL-ness but the proper way is to check if the backend reference is closed. This will fix a debug assertion in addition to possibly preventing crashes. --- server/modules/routing/readwritesplit/readwritesplit.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index feb908e59..7fae4ee27 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -2049,7 +2049,8 @@ static bool route_single_stmt( * Read stored master DCB pointer. If master is not set, routing must * be aborted */ - if ((master_dcb = rses->rses_master_ref->bref_dcb) == NULL) + if ((master_dcb = rses->rses_master_ref->bref_dcb) == NULL || + BREF_IS_CLOSED(rses->rses_master_ref)) { char* query_str = modutil_get_query(querybuf); MXS_ERROR("Can't route %s:%s:\"%s\" to " @@ -2060,6 +2061,10 @@ static bool route_single_stmt( (query_str == NULL ? "(empty)" : query_str)); free(query_str); succp = false; + while(querybuf) + { + querybuf = GWBUF_CONSUME_ALL(querybuf); + } goto retblock; } From e731f6a29e5f9df72ab5b7e65d28225f58d7700d Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 3 Feb 2016 09:18:11 +0200 Subject: [PATCH 16/18] Fixed double freeing of buffers The buffers in readwritesplit are handled at the routeQuery level and freeing them at lower levels cause a double free of the used buffers. --- server/modules/routing/readwritesplit/readwritesplit.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 7fae4ee27..a8568806e 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -2061,10 +2061,6 @@ static bool route_single_stmt( (query_str == NULL ? "(empty)" : query_str)); free(query_str); succp = false; - while(querybuf) - { - querybuf = GWBUF_CONSUME_ALL(querybuf); - } goto retblock; } From 9432967da59072447c6beb47bfb48134da557a0d Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 3 Feb 2016 17:39:54 +0200 Subject: [PATCH 17/18] Don't assert the master server state when routing query to slave When a query is being routed to the slave, it is not necessary to assert that the master server's state is still master. It is possible that the master server changes states while the query is being routed but that doesn't affect the query being currently routed. --- server/modules/routing/readwritesplit/readwritesplit.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index a8568806e..71f6ce11f 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -2437,8 +2437,6 @@ static bool route_single_stmt( #if defined(SS_EXTRA_DEBUG) MXS_INFO("Found DCB for slave."); #endif - ss_dassert(get_root_master_bref(rses) == - rses->rses_master_ref); atomic_add(&inst->stats.n_slave, 1); } else From 379cb6c781eba2c66ef261beae222463715b938f Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 5 Feb 2016 13:54:24 +0200 Subject: [PATCH 18/18] MXS-564: Slave server states were not properly cleared after session commands When a command that changes the session state is executed on all servers and a slave server goes down, an error message was sent to the client even though one wasn't expected. These appeared as odd connection errors on the client side. --- .../modules/routing/readwritesplit/readwritesplit.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 71f6ce11f..63ef48661 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -2834,11 +2834,9 @@ static void clientReply ( * This applies to session commands only. Counter decrement * for other type of queries is done outside this block. */ - if (writebuf != NULL && client_dcb != NULL) - { - /** Set response status as replied */ - bref_clear_state(bref, BREF_WAITING_RESULT); - } + + /** Set response status as replied */ + bref_clear_state(bref, BREF_WAITING_RESULT); } /** * Clear BREF_QUERY_ACTIVE flag and decrease waiter counter. @@ -3756,8 +3754,8 @@ static GWBUF* sescmd_cursor_process_replies( if(bref->reply_cmd != scmd->reply_cmd) { - MXS_INFO("Backend server '%s' response differs from master's response. " - "Closing connection.", + MXS_ERROR("Slave server '%s': response differs from master's response. " + "Closing connection due to inconsistent session state.", bref->bref_backend->backend_server->unique_name); sescmd_cursor_set_active(scur,false); bref_clear_state(bref,BREF_QUERY_ACTIVE);