From d337aa047620a398a110a95bceb842b279419afe Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 31 Aug 2016 10:44:17 +0300 Subject: [PATCH] Backport hint priority change to 2.0 The change in readwritesplit routing priorities, where hints have the highest priority, gives users more options to control how readwritesplit acts. For example, this allows read-only stored procedures to be routed to slaves by adding a hint to the query: CALL myproc(); -- maxscale route to slave The readwritesplit documentation also warns the user not to use routing hints unless they can be absolutely sure that no damage will be done. --- .../MaxScale-2.0.1-Release-Notes.md | 67 +++++++++++ Documentation/Routers/ReadWriteSplit.md | 9 +- .../routing/readwritesplit/readwritesplit.c | 110 +++++++++--------- 3 files changed, 131 insertions(+), 55 deletions(-) create mode 100644 Documentation/Release-Notes/MaxScale-2.0.1-Release-Notes.md diff --git a/Documentation/Release-Notes/MaxScale-2.0.1-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.0.1-Release-Notes.md new file mode 100644 index 000000000..8cc6d28c6 --- /dev/null +++ b/Documentation/Release-Notes/MaxScale-2.0.1-Release-Notes.md @@ -0,0 +1,67 @@ +# MariaDB MaxScale 2.0.1 Release Notes + +Release 2.0.1 is a GA release. + +This document describes the changes in release 2.0.1, when compared to +[release 2.0.0](MaxScale-2.0.0-Release-Notes.md). + +For any problems you encounter, please consider submitting a bug +report at [Jira](https://jira.mariadb.org). + +## License + +The license of MaxScale has been changed from GPLv2 to MariaDB BSL. + +For more information about MariaDB BSL, please refer to +[MariaDB BSL](https://www.mariadb.com/bsl). + +## Updated Features + +### Routing hint priority change + +Routing hints now have the highest priority when a routing decision is made. If +there is a conflict between the original routing decision made by the +readwritesplit and the routing hint attached to the query, the routing hint +takes higher priority. + +What this change means is that, if a query would normally be routed to the +master but the routing hint instructs the router to route it to the slave, it +would be routed to the slave. + +**WARNING**: This change can alter the way some statements are routed and could + possibly cause data loss, corruption or inconsisteny. Please consult the [Hint + Syntax](../Reference/Hint-Syntax.md) and + [ReadWriteSplit](../Routers/ReadWriteSplit.md) documentation before using + routing hints. + +## Bug fixes + +[Here is a list of bugs fixed since the release of MaxScale 2.0.1.](https://jira.mariadb.org/issues/?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20status%20%3D%20Closed%20AND%20fixVersion%20in%20(2.0.0%2C%202.0.1)%20AND%20resolved%20%3E%3D%20-21d%20ORDER%20BY%20priority%20DESC%2C%20updated%20DESC) + +* [MXS-847](https://jira.mariadb.org/browse/MXS-847): server_down event is executed 8 times due to putting sever into maintenance mode +* [MXS-845](https://jira.mariadb.org/browse/MXS-845): "Server down" event is re-triggered after maintenance mode is repeated +* [MXS-842](https://jira.mariadb.org/browse/MXS-842): Unexpected / undocumented behaviour when multiple available masters from mmmon monitor +* [MXS-846](https://jira.mariadb.org/browse/MXS-846): MMMon: Maintenance mode on slave logs error message every second + + +## Known Issues and Limitations + +There are some limitations and known issues within this version of MaxScale. +For more information, please refer to the [Limitations](../About/Limitations.md) +document. + +## Packaging + +RPM and Debian packages are provided for the Linux distributions supported +by MariaDB Enterprise. + +Packages can be downloaded [here](https://mariadb.com/resources/downloads). + +## Source Code + +The source code of MaxScale is tagged at GitHub with a tag, which is identical +with the version of MaxScale. For instance, the tag of version X.Y.Z of MaxScale +is maxscale-X.Y.Z. Further, *master* always refers to the latest released +non-beta version. + +The source code is available [here](https://github.com/mariadb-corporation/MaxScale). diff --git a/Documentation/Routers/ReadWriteSplit.md b/Documentation/Routers/ReadWriteSplit.md index d59a7c49f..b45f0b4b0 100644 --- a/Documentation/Routers/ReadWriteSplit.md +++ b/Documentation/Routers/ReadWriteSplit.md @@ -150,7 +150,14 @@ reconnecting to MariaDB MaxScale once a new master is available. ## 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. +The readwritesplit router supports routing hints. For a detailed guide on hint +syntax and functionality, please read [this](../Reference/Hint-Syntax.md) document. + +**Note**: Routing hints will always have the highest priority when a routing +decision is made. This means that it is possible to cause inconsistencies in +the session state and the actual data in the database by adding routing hints +to DDL/DML statements which are then directed to slave servers. Only use routing +hints when you are sure that they can cause no harm. ## Limitations diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 7620c939b..0c980a631 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -1375,59 +1375,7 @@ static route_target_t get_route_target(ROUTER_CLIENT_SES *rses, { target = TARGET_MASTER; } - /** process routing hints */ - while (hint != NULL) - { - if (hint->type == HINT_ROUTE_TO_MASTER) - { - target = TARGET_MASTER; /*< override */ - MXS_DEBUG("%lu [get_route_target] Hint: route to master.", - pthread_self()); - break; - } - else if (hint->type == HINT_ROUTE_TO_NAMED_SERVER) - { - /** - * Searching for a named server. If it can't be - * found, the oroginal target is chosen. - */ - target |= TARGET_NAMED_SERVER; - MXS_DEBUG("%lu [get_route_target] Hint: route to " - "named server : ", - pthread_self()); - } - else if (hint->type == HINT_ROUTE_TO_UPTODATE_SERVER) - { - /** not implemented */ - } - else if (hint->type == HINT_ROUTE_TO_ALL) - { - /** not implemented */ - } - else if (hint->type == HINT_PARAMETER) - { - if (strncasecmp((char *)hint->data, "max_slave_replication_lag", - strlen("max_slave_replication_lag")) == 0) - { - target |= TARGET_RLAG_MAX; - } - else - { - MXS_ERROR("Unknown hint parameter " - "'%s' when 'max_slave_replication_lag' " - "was expected.", - (char *)hint->data); - } - } - else if (hint->type == HINT_ROUTE_TO_SLAVE) - { - target = TARGET_SLAVE; - MXS_DEBUG("%lu [get_route_target] Hint: route to " - "slave.", - pthread_self()); - } - hint = hint->next; - } /*< while (hint != NULL) */ + /** If nothing matches then choose the master */ if ((target & (TARGET_ALL | TARGET_SLAVE | TARGET_MASTER)) == 0) { @@ -1436,7 +1384,6 @@ static route_target_t get_route_target(ROUTER_CLIENT_SES *rses, } else { - /** hints don't affect on routing */ ss_dassert(trx_active || (QUERY_IS_TYPE(qtype, QUERY_TYPE_WRITE) || QUERY_IS_TYPE(qtype, QUERY_TYPE_MASTER_READ) || @@ -1460,6 +1407,61 @@ static route_target_t get_route_target(ROUTER_CLIENT_SES *rses, QUERY_IS_TYPE(qtype, QUERY_TYPE_UNKNOWN))); target = TARGET_MASTER; } + + /** process routing hints */ + while (hint != NULL) + { + if (hint->type == HINT_ROUTE_TO_MASTER) + { + target = TARGET_MASTER; /*< override */ + MXS_DEBUG("%lu [get_route_target] Hint: route to master.", + pthread_self()); + break; + } + else if (hint->type == HINT_ROUTE_TO_NAMED_SERVER) + { + /** + * Searching for a named server. If it can't be + * found, the oroginal target is chosen. + */ + target |= TARGET_NAMED_SERVER; + MXS_DEBUG("%lu [get_route_target] Hint: route to " + "named server : ", + pthread_self()); + } + else if (hint->type == HINT_ROUTE_TO_UPTODATE_SERVER) + { + /** not implemented */ + } + else if (hint->type == HINT_ROUTE_TO_ALL) + { + /** not implemented */ + } + else if (hint->type == HINT_PARAMETER) + { + if (strncasecmp((char *)hint->data, "max_slave_replication_lag", + strlen("max_slave_replication_lag")) == 0) + { + target |= TARGET_RLAG_MAX; + } + else + { + MXS_ERROR("Unknown hint parameter " + "'%s' when 'max_slave_replication_lag' " + "was expected.", + (char *)hint->data); + } + } + else if (hint->type == HINT_ROUTE_TO_SLAVE) + { + target = TARGET_SLAVE; + MXS_DEBUG("%lu [get_route_target] Hint: route to " + "slave.", + pthread_self()); + } + hint = hint->next; + } /*< while (hint != NULL) */ + #if defined(SS_EXTRA_DEBUG) MXS_INFO("Selected target \"%s\"", STRTARGET(target)); #endif