Merge branch '2.2' into develop
This commit is contained in:
commit
7ec2f77708
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 <<EOF > MaxScale-$VERSION-Release-Notes.md
|
||||
# MariaDB MaxScale ${VERSION} Release Notes
|
||||
|
@ -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}
|
||||
|
@ -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)
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
23
maxscale-system-test/mxs2037_namedserver_wildcards.cpp
Normal file
23
maxscale-system-test/mxs2037_namedserver_wildcards.cpp
Normal file
@ -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;
|
||||
}
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<char*>(MXS_MALLOC(n_bytes + 1));
|
||||
char* rval = static_cast<char*>(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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user