diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index a95ee4ec9..61f8776e9 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -39,6 +39,7 @@ For more details, please refer to: the master. There is also limited capability for rejoining nodes. For more details, please refer to: +* [MariaDB MaxScale 2.2.14 Release Notes](Release-Notes/MaxScale-2.2.14-Release-Notes.md) * [MariaDB MaxScale 2.2.13 Release Notes](Release-Notes/MaxScale-2.2.13-Release-Notes.md) * [MariaDB MaxScale 2.2.12 Release Notes](Release-Notes/MaxScale-2.2.12-Release-Notes.md) * [MariaDB MaxScale 2.2.11 Release Notes](Release-Notes/MaxScale-2.2.11-Release-Notes.md) diff --git a/Documentation/Release-Notes/MaxScale-2.2.14-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.2.14-Release-Notes.md index 94dd21839..edbc84b88 100644 --- a/Documentation/Release-Notes/MaxScale-2.2.14-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.2.14-Release-Notes.md @@ -2,8 +2,8 @@ Release 2.2.14 is a GA release. -This document describes the changes in release 2.2.14, when compared to the -previous release in the same series. +This document describes the changes in release 2.2.14, when compared to +release 2.2.13. For any problems you encounter, please consider submitting a bug report on [our Jira](https://jira.mariadb.org/projects/MXS). @@ -14,7 +14,10 @@ report on [our Jira](https://jira.mariadb.org/projects/MXS). ## Bug fixes +* [MXS-2041](https://jira.mariadb.org/browse/MXS-2041) Crash on failure to create schemarouter session +* [MXS-2040](https://jira.mariadb.org/browse/MXS-2040) Default monitor timeouts are too short * [MXS-2037](https://jira.mariadb.org/browse/MXS-2037) % wildcards not working with source in Named Server Filter +* [MXS-2036](https://jira.mariadb.org/browse/MXS-2036) A slave with sql thread stopped causes wrong master after failover * [MXS-2034](https://jira.mariadb.org/browse/MXS-2034) query_retry_timeout was not set * [MXS-2027](https://jira.mariadb.org/browse/MXS-2027) LOAD DATA LOCAL INFILE is not ignored by protocol modules * [MXS-2024](https://jira.mariadb.org/browse/MXS-2024) Crash in reauthenticate_client diff --git a/Documentation/Release-Notes/generate_release_notes.sh b/Documentation/Release-Notes/generate_release_notes.sh index 125cba202..905e90476 100755 --- a/Documentation/Release-Notes/generate_release_notes.sh +++ b/Documentation/Release-Notes/generate_release_notes.sh @@ -1,11 +1,11 @@ #!/bin/bash -major=`cmake -P ../../VERSION.cmake -L|grep 'MAXSCALE_VERSION_MAJOR'|sed 's/.*=//'` -minor=`cmake -P ../../VERSION.cmake -L|grep 'MAXSCALE_VERSION_MINOR'|sed 's/.*=//'` -patch=`cmake -P ../../VERSION.cmake -L|grep 'MAXSCALE_VERSION_PATCH'|sed 's/.*=//'` -maturity=`cmake -P ../../VERSION.cmake -L|grep 'MAXSCALE_MATURITY'|sed 's/.*=//'` +major="`cd ../../ && cmake -P ./VERSION.cmake -L|grep 'MAXSCALE_VERSION_MAJOR'|sed 's/.*=//'`" +minor="`cd ../../ && cmake -P ./VERSION.cmake -L|grep 'MAXSCALE_VERSION_MINOR'|sed 's/.*=//'`" +patch="`cd ../../ && cmake -P ./VERSION.cmake -L|grep 'MAXSCALE_VERSION_PATCH'|sed 's/.*=//'`" +maturity="`cd ../../ && cmake -P ./VERSION.cmake -L|grep 'MAXSCALE_MATURITY'|sed 's/.*=//'`" -VERSION=${major}.${minor}.${patch} +VERSION="${major}.${minor}.${patch}" cat < MaxScale-$VERSION-Release-Notes.md # MariaDB MaxScale ${VERSION} Release Notes diff --git a/maxctrl/CMakeLists.txt b/maxctrl/CMakeLists.txt index cd04841e9..0bb65c6bc 100644 --- a/maxctrl/CMakeLists.txt +++ b/maxctrl/CMakeLists.txt @@ -4,7 +4,7 @@ if (BUILD_MAXCTRL) if (NPM_FOUND AND NODEJS_FOUND AND NODEJS_VERSION VERSION_GREATER "6.0.0") - include(configure_version.cmake) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/lib/version.js.in ${CMAKE_CURRENT_BINARY_DIR}/lib/version.js @ONLY) add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/maxctrl/maxctrl COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build.sh ${CMAKE_SOURCE_DIR} diff --git a/maxctrl/configure_version.cmake b/maxctrl/configure_version.cmake deleted file mode 100644 index cba3ce999..000000000 --- a/maxctrl/configure_version.cmake +++ /dev/null @@ -1,2 +0,0 @@ -include(../VERSION.cmake) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/lib/version.js.in ${CMAKE_CURRENT_BINARY_DIR}/lib/version.js @ONLY) diff --git a/maxctrl/package.json b/maxctrl/package.json index dff7e2364..e8e451a95 100644 --- a/maxctrl/package.json +++ b/maxctrl/package.json @@ -6,7 +6,7 @@ "main": "maxctrl.js", "scripts": { "test": "nyc mocha --exit --timeout 15000 --slow 10000", - "preinstall": "cmake -P configure_version.cmake" + "preinstall": "test -f lib/version.js || cp lib/version.js.in lib/version.js" }, "keywords": [ "maxscale" diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index fb91498e6..6f30dd142 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -1058,5 +1058,9 @@ add_test_executable(mxs1985_kill_hang.cpp mxs1985_kill_hang replication LABELS R # https://jira.mariadb.org/browse/MXS-1113 add_test_executable(mxs1113_schemarouter_ps.cpp mxs1113_schemarouter_ps mxs1113_schemarouter_ps LABELS schemarouter BREAKS_REPL) +# MXS-2037: Wildcards not working with source in Named Server Filter +# https://jira.mariadb.org/browse/MXS-2037 +add_test_executable(mxs2037_namedserver_wildcards.cpp mxs2037_namedserver_wildcards mxs2037_namedserver_wildcards LABELS namedserverfilter LIGHT REPL_BACKEND) + configure_file(templates.h.in ${CMAKE_CURRENT_BINARY_DIR}/templates.h @ONLY) diff --git a/maxscale-system-test/cnf/maxscale.cnf.template.mxs2037_namedserver_wildcards b/maxscale-system-test/cnf/maxscale.cnf.template.mxs2037_namedserver_wildcards new file mode 100644 index 000000000..831d968a4 --- /dev/null +++ b/maxscale-system-test/cnf/maxscale.cnf.template.mxs2037_namedserver_wildcards @@ -0,0 +1,95 @@ +[maxscale] +threads=###threads### +log_warning=1 + +[namedserverfilter] +type=filter +module=namedserverfilter +match01=SELECT +target01=server1 +source=127.%.%.% + +[MySQL Monitor] +type=monitor +module=mysqlmon +###repl51### +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql +monitor_interval=1000 + +[RW Split Router] +type=service +router=readwritesplit +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql +filters=namedserverfilter + +[CLI] +type=service +router=cli + +[CLI Listener] +type=listener +service=CLI +protocol=maxscaled +socket=default + +[Read Connection Router Slave] +type=service +router=readconnroute +router_options=slave +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql + +[Read Connection Router Master] +type=service +router=readconnroute +router_options=master +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql + +[RW Split Listener] +type=listener +service=RW Split Router +protocol=MySQLClient +port=4006 + +[Read Connection Listener Slave] +type=listener +service=Read Connection Router Slave +protocol=MySQLClient +port=4009 + +[Read Connection Listener Master] +type=listener +service=Read Connection Router Master +protocol=MySQLClient +port=4008 + +[server1] +type=server +address=###node_server_IP_1### +port=###node_server_port_1### +protocol=MySQLBackend + +[server2] +type=server +address=###node_server_IP_2### +port=###node_server_port_2### +protocol=MySQLBackend + +[server3] +type=server +address=###node_server_IP_3### +port=###node_server_port_3### +protocol=MySQLBackend + +[server4] +type=server +address=###node_server_IP_4### +port=###node_server_port_4### +protocol=MySQLBackend diff --git a/maxscale-system-test/keepalived.cpp b/maxscale-system-test/keepalived.cpp index c72f53ef9..9cbd99c5d 100644 --- a/maxscale-system-test/keepalived.cpp +++ b/maxscale-system-test/keepalived.cpp @@ -22,6 +22,7 @@ int main(int argc, char* argv[]) char* version; + TestConnections::multiple_maxscales(true); TestConnections* Test = new TestConnections(argc, argv); Test->set_timeout(10); diff --git a/maxscale-system-test/keepalived_masterdown.cpp b/maxscale-system-test/keepalived_masterdown.cpp index ff7735196..8f3db2759 100644 --- a/maxscale-system-test/keepalived_masterdown.cpp +++ b/maxscale-system-test/keepalived_masterdown.cpp @@ -39,6 +39,7 @@ int main(int argc, char* argv[]) bool passive; char str[1024]; + TestConnections::multiple_maxscales(true); TestConnections* Test = new TestConnections(argc, argv); // Test->set_timeout(10); diff --git a/maxscale-system-test/mxs2037_namedserver_wildcards.cpp b/maxscale-system-test/mxs2037_namedserver_wildcards.cpp new file mode 100644 index 000000000..2f73280fb --- /dev/null +++ b/maxscale-system-test/mxs2037_namedserver_wildcards.cpp @@ -0,0 +1,23 @@ +/** + * MXS-2037: Wildcards not working with source in NamedServerFilter + * + * https://jira.mariadb.org/browse/MXS-2037 + * + * This test only tests that ip addresses with wildcards are accepted by + * NamedServerFilter. The actual matching functionality is not tested + * because the client IPs can change with the different test environments + * and that would make it complicated to check if the matching is correct. + */ + + +#include "testconnections.h" + +int main(int argc, char** argv) +{ + TestConnections test(argc, argv); + test.set_timeout(10); + test.maxscales->connect_maxscale(0); + test.add_result(execute_query(test.maxscales->conn_rwsplit[0], "select 1"), "Can't connect to backend"); + test.maxscales->close_maxscale_connections(0); + return test.global_result; +} diff --git a/maxscale-system-test/mysqlmon_failover_auto.cpp b/maxscale-system-test/mysqlmon_failover_auto.cpp index 91b808907..84730fca2 100644 --- a/maxscale-system-test/mysqlmon_failover_auto.cpp +++ b/maxscale-system-test/mysqlmon_failover_auto.cpp @@ -21,13 +21,13 @@ int main(int argc, char** argv) test.repl->connect(); delete_slave_binlogs(test); - test.maxscales->wait_for_monitor(); + test.maxscales->wait_for_monitor(2); basic_test(test); print_gtids(test); // Part 1 int node0_id = prepare_test_1(test); - test.maxscales->wait_for_monitor(); + test.maxscales->wait_for_monitor(2); check_test_1(test, node0_id); if (test.global_result != 0) @@ -37,7 +37,7 @@ int main(int argc, char** argv) // Part 2 prepare_test_2(test); - test.maxscales->wait_for_monitor(); + test.maxscales->wait_for_monitor(2); check_test_2(test); if (test.global_result != 0) @@ -47,7 +47,7 @@ int main(int argc, char** argv) // Part 3 prepare_test_3(test); - test.maxscales->wait_for_monitor(); + test.maxscales->wait_for_monitor(2); check_test_3(test); return test.global_result; diff --git a/maxscale-system-test/testconnections.cpp b/maxscale-system-test/testconnections.cpp index 4efcbd5a8..8f1840fbe 100644 --- a/maxscale-system-test/testconnections.cpp +++ b/maxscale-system-test/testconnections.cpp @@ -25,6 +25,7 @@ static bool manual_debug = false; static std::string required_repl_version; static std::string required_galera_version; static bool restart_galera = false; +static bool multiple_maxscales = false; } static void signal_set(int sig, void (* handler)(int)) @@ -57,6 +58,11 @@ void TestConnections::skip_maxscale_start(bool value) maxscale::start = !value; } +void TestConnections::multiple_maxscales(bool value) +{ + maxscale::multiple_maxscales = value; +} + void TestConnections::require_repl_version(const char* version) { maxscale::required_repl_version = version; @@ -666,9 +672,15 @@ void TestConnections::process_template(int m, const char* template_name, const c void TestConnections::init_maxscales() { - for (int i = 0; i < maxscales->N; i++) + // Always initialize the first MaxScale + init_maxscale(0); + + if (maxscale::multiple_maxscales) { - init_maxscale(i); + for (int i = 1; i < maxscales->N; i++) + { + init_maxscale(i); + } } } diff --git a/maxscale-system-test/testconnections.h b/maxscale-system-test/testconnections.h index 03f84e98d..ff5a5eae4 100644 --- a/maxscale-system-test/testconnections.h +++ b/maxscale-system-test/testconnections.h @@ -250,6 +250,9 @@ public: /** Skip initial start of MaxScale */ static void skip_maxscale_start(bool value); + /** Prepare multiple maxscale instances */ + static void multiple_maxscales(bool value); + /** Test requires a certain backend version */ static void require_repl_version(const char* version); static void require_galera_version(const char* version); diff --git a/server/core/filter.cc b/server/core/filter.cc index fe04b49b8..8073f777e 100644 --- a/server/core/filter.cc +++ b/server/core/filter.cc @@ -344,6 +344,7 @@ MXS_DOWNSTREAM* filter_apply(const SFilterDef& filter, MXS_SESSION* session, MXS if ((me = (MXS_DOWNSTREAM*)MXS_CALLOC(1, sizeof(MXS_DOWNSTREAM))) == NULL) { + MXS_OOM(); return NULL; } me->instance = filter->filter; @@ -351,6 +352,7 @@ MXS_DOWNSTREAM* filter_apply(const SFilterDef& filter, MXS_SESSION* session, MXS if ((me->session = filter->obj->newSession(me->instance, session)) == NULL) { + MXS_ERROR("Failed to create filter session for '%s'", filter->name.c_str()); MXS_FREE(me); return NULL; } diff --git a/server/core/internal/monitor.h b/server/core/internal/monitor.h index 9d798cf98..1f8956c94 100644 --- a/server/core/internal/monitor.h +++ b/server/core/internal/monitor.h @@ -23,9 +23,9 @@ MXS_BEGIN_DECLS #define MON_ARG_MAX 8192 -#define DEFAULT_CONNECT_TIMEOUT 3 -#define DEFAULT_READ_TIMEOUT 3 -#define DEFAULT_WRITE_TIMEOUT 3 +#define DEFAULT_CONNECT_TIMEOUT 3 +#define DEFAULT_READ_TIMEOUT 3 +#define DEFAULT_WRITE_TIMEOUT 3 #define DEFAULT_CONNECTION_ATTEMPTS 1 #define DEFAULT_MONITOR_INTERVAL 2000 // in milliseconds diff --git a/server/modules/authenticator/MySQLAuth/dbusers.cc b/server/modules/authenticator/MySQLAuth/dbusers.cc index 47ff77ab9..44ea9dd0c 100644 --- a/server/modules/authenticator/MySQLAuth/dbusers.cc +++ b/server/modules/authenticator/MySQLAuth/dbusers.cc @@ -44,7 +44,8 @@ #define MYSQL57_PASSWORD "authentication_string" // Query used with 10.0 or older -#define NEW_LOAD_DBUSERS_QUERY "SELECT u.user, u.host, d.db, u.select_priv, u.%s \ +#define NEW_LOAD_DBUSERS_QUERY \ + "SELECT u.user, u.host, d.db, u.select_priv, u.%s \ FROM mysql.user AS u LEFT JOIN mysql.db AS d \ ON (u.user = d.user AND u.host = d.host) WHERE u.plugin IN ('', 'mysql_native_password') %s \ UNION \ @@ -53,87 +54,87 @@ ON (u.user = t.user AND u.host = t.host) WHERE u.plugin IN ('', 'mysql_native_password') %s" // Used with 10.2 or newer, supports composite roles -const char* mariadb_102_users_query = - // `t` is users that are not roles - "WITH RECURSIVE t AS ( " - " SELECT u.user, u.host, d.db, u.select_priv, u.password AS password, u.is_role, u.default_role" - " FROM mysql.user AS u LEFT JOIN mysql.db AS d " - " ON (u.user = d.user AND u.host = d.host) " - " UNION " - " SELECT u.user, u.host, t.db, u.select_priv, u.password AS password, u.is_role, u.default_role " - " FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t " - " ON (u.user = t.user AND u.host = t.host)" - "), users AS (" - // Select the root row, the actual user - " SELECT t.user, t.host, t.db, t.select_priv, t.password, t.default_role AS role FROM t" - " WHERE t.is_role <> 'Y'" - " UNION" - // Recursively select all roles for the users - " SELECT u.user, u.host, t.db, t.select_priv, u.password, r.role FROM t" - " JOIN users AS u" - " ON (t.user = u.role)" - " LEFT JOIN mysql.roles_mapping AS r" - " ON (t.user = r.user)" - ")" - "SELECT DISTINCT t.user, t.host, t.db, t.select_priv, t.password FROM users AS t %s"; +const char* mariadb_102_users_query + = // `t` is users that are not roles + "WITH RECURSIVE t AS ( " + " SELECT u.user, u.host, d.db, u.select_priv, u.password AS password, u.is_role, u.default_role" + " FROM mysql.user AS u LEFT JOIN mysql.db AS d " + " ON (u.user = d.user AND u.host = d.host) " + " UNION " + " SELECT u.user, u.host, t.db, u.select_priv, u.password AS password, u.is_role, u.default_role " + " FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t " + " ON (u.user = t.user AND u.host = t.host)" + "), users AS (" + // Select the root row, the actual user + " SELECT t.user, t.host, t.db, t.select_priv, t.password, t.default_role AS role FROM t" + " WHERE t.is_role <> 'Y'" + " UNION" + // Recursively select all roles for the users + " SELECT u.user, u.host, t.db, t.select_priv, u.password, r.role FROM t" + " JOIN users AS u" + " ON (t.user = u.role)" + " LEFT JOIN mysql.roles_mapping AS r" + " ON (t.user = r.user)" + ")" + "SELECT DISTINCT t.user, t.host, t.db, t.select_priv, t.password FROM users AS t %s"; // Query used with MariaDB 10.1, supports basic roles -const char* mariadb_users_query = - // First, select all users - "SELECT t.user, t.host, t.db, t.select_priv, t.password FROM " - "( " - " SELECT u.user, u.host, d.db, u.select_priv, u.password AS password, u.is_role " - " FROM mysql.user AS u LEFT JOIN mysql.db AS d " - " ON (u.user = d.user AND u.host = d.host) " - " UNION " - " SELECT u.user, u.host, t.db, u.select_priv, u.password AS password, u.is_role " - " FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t " - " ON (u.user = t.user AND u.host = t.host) " - ") AS t " - // Discard any users that are roles - "WHERE t.is_role <> 'Y' %s " - "UNION " - // Then select all users again - "SELECT r.user, r.host, u.db, u.select_priv, t.password FROM " - "( " - " SELECT u.user, u.host, d.db, u.select_priv, u.password AS password, u.default_role " - " FROM mysql.user AS u LEFT JOIN mysql.db AS d " - " ON (u.user = d.user AND u.host = d.host) " - " UNION " - " SELECT u.user, u.host, t.db, u.select_priv, u.password AS password, u.default_role " - " FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t " - " ON (u.user = t.user AND u.host = t.host) " - ") AS t " - // Join it to the roles_mapping table to only have users with roles - "JOIN mysql.roles_mapping AS r " - "ON (r.user = t.user AND r.host = t.host) " - // Then join it into itself to get the privileges of the role with the name of the user - "JOIN " - "( " - " SELECT u.user, u.host, d.db, u.select_priv, u.password AS password, u.is_role " - " FROM mysql.user AS u LEFT JOIN mysql.db AS d " - " ON (u.user = d.user AND u.host = d.host) " - " UNION " - " SELECT u.user, u.host, t.db, u.select_priv, u.password AS password, u.is_role " - " FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t " - " ON (u.user = t.user AND u.host = t.host) " - ") AS u " - "ON (u.user = r.role AND u.is_role = 'Y') " - // We only care about users that have a default role assigned - "WHERE t.default_role = u.user %s;"; +const char* mariadb_users_query + = // First, select all users + "SELECT t.user, t.host, t.db, t.select_priv, t.password FROM " + "( " + " SELECT u.user, u.host, d.db, u.select_priv, u.password AS password, u.is_role " + " FROM mysql.user AS u LEFT JOIN mysql.db AS d " + " ON (u.user = d.user AND u.host = d.host) " + " UNION " + " SELECT u.user, u.host, t.db, u.select_priv, u.password AS password, u.is_role " + " FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t " + " ON (u.user = t.user AND u.host = t.host) " + ") AS t " + // Discard any users that are roles + "WHERE t.is_role <> 'Y' %s " + "UNION " + // Then select all users again + "SELECT r.user, r.host, u.db, u.select_priv, t.password FROM " + "( " + " SELECT u.user, u.host, d.db, u.select_priv, u.password AS password, u.default_role " + " FROM mysql.user AS u LEFT JOIN mysql.db AS d " + " ON (u.user = d.user AND u.host = d.host) " + " UNION " + " SELECT u.user, u.host, t.db, u.select_priv, u.password AS password, u.default_role " + " FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t " + " ON (u.user = t.user AND u.host = t.host) " + ") AS t " + // Join it to the roles_mapping table to only have users with roles + "JOIN mysql.roles_mapping AS r " + "ON (r.user = t.user AND r.host = t.host) " + // Then join it into itself to get the privileges of the role with the name of the user + "JOIN " + "( " + " SELECT u.user, u.host, d.db, u.select_priv, u.password AS password, u.is_role " + " FROM mysql.user AS u LEFT JOIN mysql.db AS d " + " ON (u.user = d.user AND u.host = d.host) " + " UNION " + " SELECT u.user, u.host, t.db, u.select_priv, u.password AS password, u.is_role " + " FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t " + " ON (u.user = t.user AND u.host = t.host) " + ") AS u " + "ON (u.user = r.role AND u.is_role = 'Y') " + // We only care about users that have a default role assigned + "WHERE t.default_role = u.user %s;"; -static int get_users(SERV_LISTENER *listener, bool skip_local); -static MYSQL *gw_mysql_init(void); -static int gw_mysql_set_timeouts(MYSQL* handle); -static char *mysql_format_user_entry(void *data); -static bool get_hostname(DCB *dcb, char *client_hostname, size_t size); +static int get_users(SERV_LISTENER* listener, bool skip_local); +static MYSQL* gw_mysql_init(void); +static int gw_mysql_set_timeouts(MYSQL* handle); +static char* mysql_format_user_entry(void* data); +static bool get_hostname(DCB* dcb, char* client_hostname, size_t size); static char* get_mariadb_102_users_query(bool include_root) { - const char *root = include_root ? "" : " WHERE t.user <> 'root'"; + const char* root = include_root ? "" : " WHERE t.user <> 'root'"; size_t n_bytes = snprintf(NULL, 0, mariadb_102_users_query, root); - char *rval = static_cast(MXS_MALLOC(n_bytes + 1)); + char* rval = static_cast(MXS_MALLOC(n_bytes + 1)); MXS_ABORT_IF_NULL(rval); snprintf(rval, n_bytes + 1, mariadb_102_users_query, root); @@ -152,13 +153,13 @@ static char* get_mariadb_users_query(bool include_root) return rval; } -static char* get_users_query(const char *server_version, int version, bool include_root, bool is_mariadb) +static char* get_users_query(const char* server_version, int version, bool include_root, bool is_mariadb) { if (is_mariadb) // 10.1.1 or newer, supports default roles { - return version >= 100202 ? - get_mariadb_102_users_query(include_root) : - get_mariadb_users_query(include_root); + return version >= 100202 + ? get_mariadb_102_users_query(include_root) + : get_mariadb_users_query(include_root); } // Either an older MariaDB version or a MySQL variant, use the legacy query @@ -935,7 +936,7 @@ int get_users_from_server(MYSQL* con, SERVER_REF* server_ref, SERVICE* service, mxs_mysql_set_server_version(con, server_ref->server); } - char *query = get_users_query(server_ref->server->version_string, + char* query = get_users_query(server_ref->server->version_string, server_ref->server->version, service->enable_root, roles_are_available(con, service, server_ref->server)); @@ -946,8 +947,8 @@ int get_users_from_server(MYSQL* con, SERVER_REF* server_ref, SERVICE* service, if (query) { - if (mxs_mysql_query(con, "USE mysql") == 0 && // Set default database in case we use CTEs - mxs_mysql_query(con, query) == 0) + if (mxs_mysql_query(con, "USE mysql") == 0 // Set default database in case we use CTEs + && mxs_mysql_query(con, query) == 0) { MYSQL_RES* result = mysql_store_result(con); diff --git a/server/modules/filter/tee/teesession.cc b/server/modules/filter/tee/teesession.cc index fab9c61cb..243b70247 100644 --- a/server/modules/filter/tee/teesession.cc +++ b/server/modules/filter/tee/teesession.cc @@ -52,6 +52,7 @@ TeeSession* TeeSession::create(Tee* my_instance, MXS_SESSION* session) if ((match && (md_match = pcre2_match_data_create_from_pattern(match, NULL)) == NULL) || (exclude && (md_exclude = pcre2_match_data_create_from_pattern(exclude, NULL)) == NULL)) { + MXS_OOM(); return NULL; } @@ -59,6 +60,9 @@ TeeSession* TeeSession::create(Tee* my_instance, MXS_SESSION* session) (MySQLProtocol*)session->client_dcb->protocol, my_instance->get_service())) == NULL) { + MXS_ERROR("Failed to create local client connection to '%s'%s", + my_instance->get_service()->name, + my_instance->get_service()->ports ? "" : ": Service has no network listeners"); return NULL; } } diff --git a/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc b/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc index e9dc814c2..6f72bbf5e 100644 --- a/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc +++ b/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc @@ -667,7 +667,7 @@ static inline bool session_ok_to_route(DCB* dcb) return rval; } -static inline bool expecting_resultset(MySQLProtocol* proto) +static inline bool expecting_text_result(MySQLProtocol* proto) { return proto->current_command == MXS_COM_QUERY || proto->current_command == MXS_COM_STMT_EXECUTE @@ -861,7 +861,7 @@ static int gw_read_and_write(DCB* dcb) if (collecting_resultset(proto, capabilities)) { - if (expecting_resultset(proto)) + if (expecting_text_result(proto)) { if (mxs_mysql_is_result_set(read_buffer)) { diff --git a/server/modules/routing/readwritesplit/rwsplit_session_cmd.cc b/server/modules/routing/readwritesplit/rwsplit_session_cmd.cc index 6418137c4..562e272b7 100644 --- a/server/modules/routing/readwritesplit/rwsplit_session_cmd.cc +++ b/server/modules/routing/readwritesplit/rwsplit_session_cmd.cc @@ -37,7 +37,7 @@ static std::string extract_error(GWBUF* buffer) { size_t replylen = MYSQL_GET_PAYLOAD_LEN(GWBUF_DATA(buffer)); char replybuf[replylen]; - gwbuf_copy_data(buffer, 0, gwbuf_length(buffer), (uint8_t*)replybuf); + gwbuf_copy_data(buffer, 0, sizeof(replybuf), (uint8_t*)replybuf); std::string err; std::string msg; err.append(replybuf + 8, 5); diff --git a/server/modules/routing/schemarouter/schemaroutersession.cc b/server/modules/routing/schemarouter/schemaroutersession.cc index 73c569f27..d7e2c42d5 100644 --- a/server/modules/routing/schemarouter/schemaroutersession.cc +++ b/server/modules/routing/schemarouter/schemaroutersession.cc @@ -641,7 +641,8 @@ void SchemaRouterSession::handleError(GWBUF* pMessage, break; case ERRACT_REPLY_CLIENT: - if (m_client->session->state == SESSION_STATE_ROUTER_READY) + // The session pointer can be NULL if the creation fails when filters are being set up + if (m_client->session && m_client->session->state == SESSION_STATE_ROUTER_READY) { m_client->func.write(m_client, gwbuf_clone(pMessage)); }