Merge branch '2.2' into develop
This commit is contained in:
@ -16,7 +16,7 @@ endif()
|
|||||||
|
|
||||||
# Set default values for cache entries and set the MaxScale version
|
# Set default values for cache entries and set the MaxScale version
|
||||||
include(cmake/defaults.cmake)
|
include(cmake/defaults.cmake)
|
||||||
include(VERSION22.cmake)
|
include(VERSION.cmake)
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
|
|
||||||
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
|
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
|
||||||
|
@ -31,7 +31,9 @@ monitor_interval=2500
|
|||||||
|
|
||||||
### `backend_connect_timeout`
|
### `backend_connect_timeout`
|
||||||
|
|
||||||
This parameter controls the timeout for connecting to a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 3 seconds.
|
This parameter controls the timeout for connecting to a monitored server. It is
|
||||||
|
in seconds and the minimum value is 1 second. The default value for this
|
||||||
|
parameter is 3 seconds.
|
||||||
|
|
||||||
```
|
```
|
||||||
backend_connect_timeout=6
|
backend_connect_timeout=6
|
||||||
@ -39,7 +41,9 @@ backend_connect_timeout=6
|
|||||||
|
|
||||||
### `backend_write_timeout`
|
### `backend_write_timeout`
|
||||||
|
|
||||||
This parameter controls the timeout for writing to a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 2 seconds.
|
This parameter controls the timeout for writing to a monitored server. It is in
|
||||||
|
seconds and the minimum value is 1 second. The default value for this parameter
|
||||||
|
is 3 seconds.
|
||||||
|
|
||||||
```
|
```
|
||||||
backend_write_timeout=4
|
backend_write_timeout=4
|
||||||
@ -47,7 +51,9 @@ backend_write_timeout=4
|
|||||||
|
|
||||||
### `backend_read_timeout`
|
### `backend_read_timeout`
|
||||||
|
|
||||||
This parameter controls the timeout for reading from a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 1 seconds.
|
This parameter controls the timeout for reading from a monitored server. It is
|
||||||
|
in seconds and the minimum value is 1 second. The default value for this
|
||||||
|
parameter is 3 seconds.
|
||||||
|
|
||||||
```
|
```
|
||||||
backend_read_timeout=2
|
backend_read_timeout=2
|
||||||
|
@ -2,22 +2,19 @@
|
|||||||
|
|
||||||
Release 2.2.14 is a GA release.
|
Release 2.2.14 is a GA release.
|
||||||
|
|
||||||
This document describes the changes in release 2.2.14, when compared to
|
This document describes the changes in release 2.2.14, when compared to the
|
||||||
release 2.2.13.
|
previous release in the same series.
|
||||||
|
|
||||||
For any problems you encounter, please consider submitting a bug
|
For any problems you encounter, please consider submitting a bug
|
||||||
report on [our Jira](https://jira.mariadb.org/projects/MXS).
|
report on [our Jira](https://jira.mariadb.org/projects/MXS).
|
||||||
|
|
||||||
## New Features
|
## New Features
|
||||||
|
|
||||||
### Avrorouter Table Filtering
|
* [MXS-2039](https://jira.mariadb.org/browse/MXS-2039) Filter tables in avrorouter
|
||||||
|
|
||||||
The tables that the avrorouter processes can now be filtered with two new
|
|
||||||
parameters: [`match`](../Routers/Avrorouter.md#match) and
|
|
||||||
[`exclude`](../Routers/Avrorouter.md#exclude).
|
|
||||||
|
|
||||||
## Bug fixes
|
## Bug fixes
|
||||||
|
|
||||||
|
* [MXS-2037](https://jira.mariadb.org/browse/MXS-2037) % wildcards not working with source in Named Server Filter
|
||||||
* [MXS-2034](https://jira.mariadb.org/browse/MXS-2034) query_retry_timeout was not set
|
* [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-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
|
* [MXS-2024](https://jira.mariadb.org/browse/MXS-2024) Crash in reauthenticate_client
|
||||||
|
42
Documentation/Release-Notes/generate_release_notes.sh
Executable file
42
Documentation/Release-Notes/generate_release_notes.sh
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#!/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/.*=//'`
|
||||||
|
|
||||||
|
VERSION=${major}.${minor}.${patch}
|
||||||
|
|
||||||
|
cat <<EOF > MaxScale-$VERSION-Release-Notes.md
|
||||||
|
# MariaDB MaxScale ${VERSION} Release Notes
|
||||||
|
|
||||||
|
Release ${VERSION} is a ${maturity} release.
|
||||||
|
|
||||||
|
This document describes the changes in release ${VERSION}, when compared to the
|
||||||
|
previous release in the same series.
|
||||||
|
|
||||||
|
For any problems you encounter, please consider submitting a bug
|
||||||
|
report on [our Jira](https://jira.mariadb.org/projects/MXS).
|
||||||
|
|
||||||
|
`../list_fixed.sh ${VERSION}`
|
||||||
|
|
||||||
|
## 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 supported the Linux distributions.
|
||||||
|
|
||||||
|
Packages can be downloaded [here](https://mariadb.com/downloads/mariadb-tx/maxscale).
|
||||||
|
|
||||||
|
## 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, the default branch is always the latest GA version
|
||||||
|
of MaxScale.
|
||||||
|
|
||||||
|
The source code is available [here](https://github.com/mariadb-corporation/MaxScale).
|
||||||
|
EOF
|
@ -11,4 +11,4 @@ fi
|
|||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
version=$1
|
version=$1
|
||||||
curl -s "https://jira.mariadb.org/sr/jira.issueviews:searchrequest-csv-current-fields/temp/SearchRequest.csv?jqlQuery=project+%3D+MXS+AND+issuetype+%3D+Bug+AND+status+%3D+Closed+AND+fixVersion+%3D+$version" | $DIR/process.pl
|
curl -s "https://jira.mariadb.org/sr/jira.issueviews:searchrequest-csv-all-fields/temp/SearchRequest.csv?jqlQuery=project+%3D+MXS+AND+status+%3D+Closed+AND+fixVersion+%3D+$version" | $DIR/process.py
|
@ -1,14 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
|
|
||||||
if [ $# -ne 1 ]
|
|
||||||
then
|
|
||||||
echo "USAGE: $0 VERSION"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Script location
|
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
||||||
|
|
||||||
version=$1
|
|
||||||
curl -s "https://jira.mariadb.org/sr/jira.issueviews:searchrequest-csv-current-fields/temp/SearchRequest.csv?jqlQuery=project+%3D+MXS+AND+issuetype+%21%3D+Bug+AND+status+%3D+Closed+AND+fixVersion+%3D+$version" | $DIR/process.pl
|
|
@ -1,22 +0,0 @@
|
|||||||
#!/usr/bin/env perl
|
|
||||||
|
|
||||||
# Discard the CSV headers
|
|
||||||
<>;
|
|
||||||
|
|
||||||
while (<>)
|
|
||||||
{
|
|
||||||
# Replace commas that are inside double quotes
|
|
||||||
while (s/("[^"]*),([^"]*")/$1$2/g)
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
# Replace the double quotes themselves
|
|
||||||
s/"//g;
|
|
||||||
|
|
||||||
# Split the line and grab the issue number and description
|
|
||||||
my @parts = split(/,/);
|
|
||||||
my $issue = @parts[1];
|
|
||||||
my $desc = @parts[0];
|
|
||||||
|
|
||||||
print "* [$issue](https://jira.mariadb.org/browse/$issue) $desc\n";
|
|
||||||
}
|
|
30
Documentation/process.py
Executable file
30
Documentation/process.py
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import csv
|
||||||
|
|
||||||
|
bugs = []
|
||||||
|
new_features = []
|
||||||
|
|
||||||
|
for row in csv.DictReader(sys.stdin):
|
||||||
|
if row['Issue Type'] == 'Bug':
|
||||||
|
bugs.append(row)
|
||||||
|
elif row['Issue Type'] == 'New Feature':
|
||||||
|
new_features.append(row)
|
||||||
|
|
||||||
|
if len(new_features) > 0:
|
||||||
|
print("## New Features")
|
||||||
|
print()
|
||||||
|
|
||||||
|
for f in new_features:
|
||||||
|
print("* [" + f['Issue key'] + "](https://jira.mariadb.org/browse/" + f['Issue key'] + ") " + f['Summary'])
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
print("## Bug fixes")
|
||||||
|
print()
|
||||||
|
|
||||||
|
for b in bugs:
|
||||||
|
print("* [" + b['Issue key'] + "](https://jira.mariadb.org/browse/" + b['Issue key'] + ") " + b['Summary'])
|
||||||
|
|
||||||
|
print()
|
1
VERSION.cmake
Normal file
1
VERSION.cmake
Normal file
@ -0,0 +1 @@
|
|||||||
|
include(${CMAKE_SOURCE_DIR}/VERSION22.cmake)
|
@ -10,5 +10,7 @@ set(MAXSCALE_VERSION_PATCH "3" CACHE STRING "Patch version")
|
|||||||
# This should only be incremented if a package is rebuilt
|
# This should only be incremented if a package is rebuilt
|
||||||
set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number")
|
set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number")
|
||||||
|
|
||||||
|
set(MAXSCALE_MATURITY "GA" CACHE STRING "Release maturity")
|
||||||
|
|
||||||
set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
||||||
set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
||||||
|
@ -10,5 +10,7 @@ set(MAXSCALE_VERSION_PATCH "18" CACHE STRING "Patch version")
|
|||||||
# This should only be incremented if a package is rebuilt
|
# This should only be incremented if a package is rebuilt
|
||||||
set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number")
|
set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number")
|
||||||
|
|
||||||
|
set(MAXSCALE_MATURITY "GA" CACHE STRING "Release maturity")
|
||||||
|
|
||||||
set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
||||||
set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
||||||
|
@ -10,5 +10,7 @@ set(MAXSCALE_VERSION_PATCH "14" CACHE STRING "Patch version")
|
|||||||
# This should only be incremented if a package is rebuilt
|
# This should only be incremented if a package is rebuilt
|
||||||
set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number")
|
set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number")
|
||||||
|
|
||||||
|
set(MAXSCALE_MATURITY "GA" CACHE STRING "Release maturity")
|
||||||
|
|
||||||
set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
||||||
set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
include(../VERSION22.cmake)
|
include(../VERSION.cmake)
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/lib/version.js.in ${CMAKE_CURRENT_BINARY_DIR}/lib/version.js @ONLY)
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/lib/version.js.in ${CMAKE_CURRENT_BINARY_DIR}/lib/version.js @ONLY)
|
||||||
|
@ -491,6 +491,10 @@ add_test_executable(mxs827_write_timeout.cpp mxs827_write_timeout mxs827_write_t
|
|||||||
# https://jira.mariadb.org/browse/MXS-872
|
# https://jira.mariadb.org/browse/MXS-872
|
||||||
add_test_executable(mxs872_roles.cpp mxs872_roles replication LABELS REPL_BACKEND)
|
add_test_executable(mxs872_roles.cpp mxs872_roles replication LABELS REPL_BACKEND)
|
||||||
|
|
||||||
|
# MXS-1947: Composite roles are not supported
|
||||||
|
# https://jira.mariadb.org/browse/MXS-1947
|
||||||
|
add_test_executable(mxs1947_composite_roles.cpp mxs1947_composite_roles replication LABELS REPL_BACKEND)
|
||||||
|
|
||||||
# Block and unblock first and second slaves and check that they are recovered
|
# Block and unblock first and second slaves and check that they are recovered
|
||||||
add_test_executable(mxs874_slave_recovery.cpp mxs874_slave_recovery mxs874 LABELS readwritesplit REPL_BACKEND)
|
add_test_executable(mxs874_slave_recovery.cpp mxs874_slave_recovery mxs874 LABELS readwritesplit REPL_BACKEND)
|
||||||
|
|
||||||
|
55
maxscale-system-test/mxs1947_composite_roles.cpp
Normal file
55
maxscale-system-test/mxs1947_composite_roles.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* MXS-1947: Composite roles are not supported
|
||||||
|
*
|
||||||
|
* https://jira.mariadb.org/browse/MXS-1947
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "testconnections.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
TestConnections test(argc, argv);
|
||||||
|
|
||||||
|
test.repl->connect();
|
||||||
|
|
||||||
|
auto prepare =
|
||||||
|
{
|
||||||
|
"DROP USER test@'%'",
|
||||||
|
"CREATE USER test@'%' IDENTIFIED BY 'test';",
|
||||||
|
"CREATE ROLE a;",
|
||||||
|
"CREATE ROLE b;",
|
||||||
|
"CREATE DATABASE db;",
|
||||||
|
"GRANT ALL ON db.* TO a;",
|
||||||
|
"GRANT a TO b;",
|
||||||
|
"GRANT b TO test@'%';",
|
||||||
|
"SET DEFAULT ROLE b FOR test@'%';"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto a : prepare)
|
||||||
|
{
|
||||||
|
execute_query_silent(test.repl->nodes[0], a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the users to replicate
|
||||||
|
test.repl->sync_slaves();
|
||||||
|
|
||||||
|
test.tprintf("Connect with a user that has a composite role as the default role");
|
||||||
|
MYSQL* conn = open_conn_db(test.maxscales->rwsplit_port[0], test.maxscales->IP[0], "db", "test", "test");
|
||||||
|
test.assert(mysql_errno(conn) == 0, "Connection failed: %s", mysql_error(conn));
|
||||||
|
mysql_close(conn);
|
||||||
|
|
||||||
|
auto cleanup =
|
||||||
|
{
|
||||||
|
"DROP DATABASE IF EXISTS db;",
|
||||||
|
"DROP ROLE IF EXISTS a;",
|
||||||
|
"DROP ROLE IF EXISTS b;",
|
||||||
|
"DROP USER 'test'@'%';"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto a : cleanup)
|
||||||
|
{
|
||||||
|
execute_query_silent(test.repl->nodes[0], a);
|
||||||
|
}
|
||||||
|
|
||||||
|
return test.global_result;
|
||||||
|
}
|
@ -24,8 +24,8 @@ MXS_BEGIN_DECLS
|
|||||||
#define MON_ARG_MAX 8192
|
#define MON_ARG_MAX 8192
|
||||||
|
|
||||||
#define DEFAULT_CONNECT_TIMEOUT 3
|
#define DEFAULT_CONNECT_TIMEOUT 3
|
||||||
#define DEFAULT_READ_TIMEOUT 1
|
#define DEFAULT_READ_TIMEOUT 3
|
||||||
#define DEFAULT_WRITE_TIMEOUT 2
|
#define DEFAULT_WRITE_TIMEOUT 3
|
||||||
#define DEFAULT_CONNECTION_ATTEMPTS 1
|
#define DEFAULT_CONNECTION_ATTEMPTS 1
|
||||||
|
|
||||||
#define DEFAULT_MONITOR_INTERVAL 2000 // in milliseconds
|
#define DEFAULT_MONITOR_INTERVAL 2000 // in milliseconds
|
||||||
|
@ -43,8 +43,8 @@
|
|||||||
/** MySQL 5.7 password column name */
|
/** MySQL 5.7 password column name */
|
||||||
#define MYSQL57_PASSWORD "authentication_string"
|
#define MYSQL57_PASSWORD "authentication_string"
|
||||||
|
|
||||||
#define NEW_LOAD_DBUSERS_QUERY \
|
// Query used with 10.0 or older
|
||||||
"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 \
|
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 \
|
ON (u.user = d.user AND u.host = d.host) WHERE u.plugin IN ('', 'mysql_native_password') %s \
|
||||||
UNION \
|
UNION \
|
||||||
@ -52,9 +52,34 @@
|
|||||||
FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t \
|
FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t \
|
||||||
ON (u.user = t.user AND u.host = t.host) WHERE u.plugin IN ('', 'mysql_native_password') %s"
|
ON (u.user = t.user AND u.host = t.host) WHERE u.plugin IN ('', 'mysql_native_password') %s"
|
||||||
|
|
||||||
// Query used with MariaDB 10.1 and newer, supports roles
|
// Used with 10.2 or newer, supports composite roles
|
||||||
const char* mariadb_users_query
|
const char* mariadb_102_users_query =
|
||||||
= // First, select all users
|
// `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 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 "
|
" SELECT u.user, u.host, d.db, u.select_priv, u.password AS password, u.is_role "
|
||||||
@ -103,6 +128,18 @@ static int gw_mysql_set_timeouts(MYSQL* handle);
|
|||||||
static char *mysql_format_user_entry(void *data);
|
static char *mysql_format_user_entry(void *data);
|
||||||
static bool get_hostname(DCB *dcb, char *client_hostname, size_t size);
|
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'";
|
||||||
|
|
||||||
|
size_t n_bytes = snprintf(NULL, 0, mariadb_102_users_query, root);
|
||||||
|
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);
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
static char* get_mariadb_users_query(bool include_root)
|
static char* get_mariadb_users_query(bool include_root)
|
||||||
{
|
{
|
||||||
const char* root = include_root ? "" : " AND t.user NOT IN ('root')";
|
const char* root = include_root ? "" : " AND t.user NOT IN ('root')";
|
||||||
@ -115,11 +152,13 @@ static char* get_mariadb_users_query(bool include_root)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* get_users_query(const char* server_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
|
if (is_mariadb) // 10.1.1 or newer, supports default roles
|
||||||
{
|
{
|
||||||
return 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
|
// Either an older MariaDB version or a MySQL variant, use the legacy query
|
||||||
@ -897,6 +936,7 @@ int get_users_from_server(MYSQL* con, SERVER_REF* server_ref, SERVICE* service,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
service->enable_root,
|
||||||
roles_are_available(con, service, server_ref->server));
|
roles_are_available(con, service, server_ref->server));
|
||||||
|
|
||||||
@ -906,7 +946,8 @@ int get_users_from_server(MYSQL* con, SERVER_REF* server_ref, SERVICE* service,
|
|||||||
|
|
||||||
if (query)
|
if (query)
|
||||||
{
|
{
|
||||||
if (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);
|
MYSQL_RES* result = mysql_store_result(con);
|
||||||
|
|
||||||
|
@ -866,7 +866,8 @@ static int gw_read_and_write(DCB* dcb)
|
|||||||
if (mxs_mysql_is_result_set(read_buffer))
|
if (mxs_mysql_is_result_set(read_buffer))
|
||||||
{
|
{
|
||||||
bool more = false;
|
bool more = false;
|
||||||
if (modutil_count_signal_packets(read_buffer, 0, &more, NULL) != 2)
|
int eof_cnt = modutil_count_signal_packets(read_buffer, 0, &more, NULL);
|
||||||
|
if (more || eof_cnt % 2 != 0)
|
||||||
{
|
{
|
||||||
dcb_readq_prepend(dcb, read_buffer);
|
dcb_readq_prepend(dcb, read_buffer);
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user