Merge branch '2.1' into develop
This commit is contained in:
@ -4,7 +4,7 @@
|
|||||||
## About MariaDB MaxScale
|
## About MariaDB MaxScale
|
||||||
|
|
||||||
- [About MariaDB MaxScale](About/About-MaxScale.md)
|
- [About MariaDB MaxScale](About/About-MaxScale.md)
|
||||||
- [Release Notes](Release-Notes/MaxScale-2.1.3-Release-Notes.md)
|
- [Release Notes](Release-Notes/MaxScale-2.1.5-Release-Notes.md)
|
||||||
- [Changelog](Changelog.md)
|
- [Changelog](Changelog.md)
|
||||||
- [Limitations](About/Limitations.md)
|
- [Limitations](About/Limitations.md)
|
||||||
|
|
||||||
|
66
Documentation/Release-Notes/MaxScale-2.1.5-Release-Notes.md
Normal file
66
Documentation/Release-Notes/MaxScale-2.1.5-Release-Notes.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# MariaDB MaxScale 2.1.5 Release Notes
|
||||||
|
|
||||||
|
Release 2.1.5 is a GA release.
|
||||||
|
|
||||||
|
This document describes the changes in release 2.1.5, when compared to
|
||||||
|
release [2.1.4](MaxScale-2.1.4-Release-Notes.md).
|
||||||
|
|
||||||
|
If you are upgrading from release 2.0, please also read the following
|
||||||
|
release notes:
|
||||||
|
[2.1.4](./MaxScale-2.1.4-Release-Notes.md)
|
||||||
|
[2.1.3](./MaxScale-2.1.3-Release-Notes.md)
|
||||||
|
[2.1.2](./MaxScale-2.1.2-Release-Notes.md)
|
||||||
|
[2.1.1](./MaxScale-2.1.1-Release-Notes.md)
|
||||||
|
[2.1.0](./MaxScale-2.1.0-Release-Notes.md)
|
||||||
|
|
||||||
|
For any problems you encounter, please consider submitting a bug
|
||||||
|
report at [Jira](https://jira.mariadb.org).
|
||||||
|
|
||||||
|
## Changed Features
|
||||||
|
|
||||||
|
### Schemarouter
|
||||||
|
|
||||||
|
Starting with MaxScale 2.1.5, the _schemarouter_ will prioritize the current
|
||||||
|
database over an explicit database if tables in the the current database are
|
||||||
|
used in a query.
|
||||||
|
|
||||||
|
## New Features
|
||||||
|
|
||||||
|
### Schemarouter
|
||||||
|
|
||||||
|
A new parameter for the _schemarouter_ was added that allows deterministic
|
||||||
|
resolution of database mapping conflicts (i.e. the database exists on more than
|
||||||
|
one backend server).
|
||||||
|
|
||||||
|
The new `preferred_server` parameter takes a server name as its value. If a
|
||||||
|
database mapping conflict occurs, the server given as the parameter will have
|
||||||
|
preference. In practice, this means that databases on a central server can be
|
||||||
|
replicated to the shards for doing JOINs but writes to the replicate database
|
||||||
|
will still go to the central database.
|
||||||
|
|
||||||
|
## Bug fixes
|
||||||
|
|
||||||
|
[Here is a list of bugs fixed since the release of MaxScale 2.1.4.]
|
||||||
|
(https://jira.mariadb.org/issues/?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20status%20%3D%20Closed%20AND%20fixVersion%20%3D%202.1.5)
|
||||||
|
|
||||||
|
* [MXS-1310](https://jira.mariadb.org/browse/MXS-1310) schemarouter ignores local copy of duplicate schemas on JOIN
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
The source code is available [here](https://github.com/mariadb-corporation/MaxScale).
|
@ -51,6 +51,17 @@ List of databases to ignore when checking for duplicate databases.
|
|||||||
|
|
||||||
Regular expression that is matched against database names when checking for duplicate databases.
|
Regular expression that is matched against database names when checking for duplicate databases.
|
||||||
|
|
||||||
|
### `preferred_server`
|
||||||
|
|
||||||
|
The name of a server in MaxScale which will be used as the preferred server when
|
||||||
|
a database is found on more than one server. If a database exists on two
|
||||||
|
servers, of which neither is the server referred by this parameter, the server
|
||||||
|
that replies first will be assigned as the location of the database.
|
||||||
|
|
||||||
|
This parameter allows deterministic conflict resolution when a sharded cluster
|
||||||
|
has a central database server and one or more sharded databases spread across
|
||||||
|
multiple servers which replicate from the central database server.
|
||||||
|
|
||||||
**Note:** As of version 2.1 of MaxScale, all of the router options can also be
|
**Note:** As of version 2.1 of MaxScale, all of the router options can also be
|
||||||
defined as parameters. The values defined in _router_options_ will have priority
|
defined as parameters. The values defined in _router_options_ will have priority
|
||||||
over the parameters.
|
over the parameters.
|
||||||
|
@ -299,6 +299,9 @@ add_test_executable(longblob.cpp longblob longblob LABELS readwritesplit readcon
|
|||||||
# Test with extremely big blob inserting/selecting with > 16 mb data blocks
|
# Test with extremely big blob inserting/selecting with > 16 mb data blocks
|
||||||
add_test_executable(mxs1110_16mb.cpp mxs1110_16mb longblob_filters LABELS readwritesplit readconnroute HEAVY REPL_BACKEND)
|
add_test_executable(mxs1110_16mb.cpp mxs1110_16mb longblob_filters LABELS readwritesplit readconnroute HEAVY REPL_BACKEND)
|
||||||
|
|
||||||
|
# Schemarouter implicit database detection
|
||||||
|
add_test_executable(mxs1310_implicit_db.cpp mxs1310_implicit_db mxs1310_implicit_db LABELS schemarouter REPL_BACKEND)
|
||||||
|
|
||||||
# INSERT extremelly big number of rows
|
# INSERT extremelly big number of rows
|
||||||
add_test_executable(lots_of_rows.cpp lots_of_rows galera LABELS readwritesplit HEAVY GALERA_BACKEND)
|
add_test_executable(lots_of_rows.cpp lots_of_rows galera LABELS readwritesplit HEAVY GALERA_BACKEND)
|
||||||
|
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
[maxscale]
|
||||||
|
threads=###threads###
|
||||||
|
log_info=1
|
||||||
|
|
||||||
|
[MySQL Monitor]
|
||||||
|
type=monitor
|
||||||
|
module=mysqlmon
|
||||||
|
###repl51###
|
||||||
|
servers=server1,server2
|
||||||
|
user=maxskysql
|
||||||
|
passwd=skysql
|
||||||
|
|
||||||
|
[Sharding router]
|
||||||
|
type=service
|
||||||
|
router=schemarouter
|
||||||
|
servers=server1,server2
|
||||||
|
user=maxskysql
|
||||||
|
passwd=skysql
|
||||||
|
auth_all_servers=1
|
||||||
|
ignore_databases_regex=.*
|
||||||
|
|
||||||
|
[Sharding Listener]
|
||||||
|
type=listener
|
||||||
|
service=Sharding router
|
||||||
|
protocol=MySQLClient
|
||||||
|
port=4006
|
||||||
|
|
||||||
|
[CLI]
|
||||||
|
type=service
|
||||||
|
router=cli
|
||||||
|
|
||||||
|
[CLI Listener]
|
||||||
|
type=listener
|
||||||
|
service=CLI
|
||||||
|
protocol=maxscaled
|
||||||
|
socket=default
|
||||||
|
|
||||||
|
[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
|
54
maxscale-system-test/mxs1310_implicit_db.cpp
Normal file
54
maxscale-system-test/mxs1310_implicit_db.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Test for MXS-1310.
|
||||||
|
* - Only explicit databases used -> shard containing the explicit database
|
||||||
|
* - Only implicit databases used -> shard containing current database
|
||||||
|
* - Mix of explicit and implicit databases -> shard containing current database
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "testconnections.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
TestConnections test(argc, argv);
|
||||||
|
|
||||||
|
// Get the @@server_id value from both shards
|
||||||
|
char server_id[2][1024];
|
||||||
|
test.repl->connect();
|
||||||
|
sprintf(server_id[0], "%d", test.repl->get_server_id(0));
|
||||||
|
sprintf(server_id[1], "%d", test.repl->get_server_id(1));
|
||||||
|
execute_query(test.repl->nodes[0],
|
||||||
|
"CREATE DATABASE db1;"
|
||||||
|
"CREATE TABLE db1.t1(id int);"
|
||||||
|
"INSERT INTO db1.t1 VALUES (@@server_id)");
|
||||||
|
execute_query(test.repl->nodes[1],
|
||||||
|
"CREATE DATABASE db2;"
|
||||||
|
"CREATE TABLE db2.t2(id int);"
|
||||||
|
"INSERT INTO db2.t2 VALUES (@@server_id)");
|
||||||
|
test.repl->sync_slaves();
|
||||||
|
|
||||||
|
test.tprintf("Run test with sharded database as active database");
|
||||||
|
test.connect_rwsplit();
|
||||||
|
test.try_query(test.conn_rwsplit, "USE db2");
|
||||||
|
execute_query_check_one(test.conn_rwsplit, "SELECT @@server_id, id FROM t2", server_id[1]);
|
||||||
|
execute_query_check_one(test.conn_rwsplit, "SELECT @@server_id, id FROM db1.t1", server_id[0]);
|
||||||
|
execute_query_check_one(test.conn_rwsplit, "SELECT @@server_id, a.id FROM t2 as a JOIN db1.t1 as b",
|
||||||
|
server_id[1]);
|
||||||
|
test.close_rwsplit();
|
||||||
|
|
||||||
|
test.tprintf("Run test with a common database as active database");
|
||||||
|
test.connect_rwsplit();
|
||||||
|
test.try_query(test.conn_rwsplit, "USE db1");
|
||||||
|
execute_query_check_one(test.conn_rwsplit, "SELECT @@server_id, id FROM t1", server_id[0]);
|
||||||
|
execute_query_check_one(test.conn_rwsplit, "SELECT @@server_id, id FROM db2.t2", server_id[1]);
|
||||||
|
execute_query_check_one(test.conn_rwsplit, "SELECT @@server_id, a.id FROM t1 as a JOIN db1.t1 as b",
|
||||||
|
server_id[0]);
|
||||||
|
test.close_rwsplit();
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
execute_query(test.repl->nodes[0], "DROP DATABASE db1");
|
||||||
|
execute_query(test.repl->nodes[1], "DROP DATABASE db2");
|
||||||
|
|
||||||
|
test.repl->fix_replication();
|
||||||
|
|
||||||
|
return test.global_result;
|
||||||
|
}
|
@ -46,13 +46,15 @@ struct Config
|
|||||||
pcre2_code* ignore_regex; /**< Regular expression used to ignore databases */
|
pcre2_code* ignore_regex; /**< Regular expression used to ignore databases */
|
||||||
pcre2_match_data* ignore_match_data; /**< Match data for @c ignore_regex */
|
pcre2_match_data* ignore_match_data; /**< Match data for @c ignore_regex */
|
||||||
std::set<std::string> ignored_dbs; /**< Set of ignored databases */
|
std::set<std::string> ignored_dbs; /**< Set of ignored databases */
|
||||||
|
SERVER* preferred_server; /**< Server to prefer in conflict situations */
|
||||||
|
|
||||||
Config():
|
Config():
|
||||||
refresh_min_interval(0.0),
|
refresh_min_interval(0.0),
|
||||||
refresh_databases(false),
|
refresh_databases(false),
|
||||||
debug(false),
|
debug(false),
|
||||||
ignore_regex(NULL),
|
ignore_regex(NULL),
|
||||||
ignore_match_data(NULL)
|
ignore_match_data(NULL),
|
||||||
|
preferred_server(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -75,6 +75,7 @@ SchemaRouter* SchemaRouter::create(SERVICE* pService, char** pzOptions)
|
|||||||
config.refresh_databases = config_get_bool(conf, "refresh_databases");
|
config.refresh_databases = config_get_bool(conf, "refresh_databases");
|
||||||
config.refresh_min_interval = config_get_integer(conf, "refresh_interval");
|
config.refresh_min_interval = config_get_integer(conf, "refresh_interval");
|
||||||
config.debug = config_get_bool(conf, "debug");
|
config.debug = config_get_bool(conf, "debug");
|
||||||
|
config.preferred_server = config_get_server(conf, "preferred_server");
|
||||||
|
|
||||||
/** Add default system databases to ignore */
|
/** Add default system databases to ignore */
|
||||||
config.ignored_dbs.insert("mysql");
|
config.ignored_dbs.insert("mysql");
|
||||||
@ -401,6 +402,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
|||||||
{"refresh_databases", MXS_MODULE_PARAM_BOOL, "true"},
|
{"refresh_databases", MXS_MODULE_PARAM_BOOL, "true"},
|
||||||
{"refresh_interval", MXS_MODULE_PARAM_COUNT, DEFAULT_REFRESH_INTERVAL},
|
{"refresh_interval", MXS_MODULE_PARAM_COUNT, DEFAULT_REFRESH_INTERVAL},
|
||||||
{"debug", MXS_MODULE_PARAM_BOOL, "false"},
|
{"debug", MXS_MODULE_PARAM_BOOL, "false"},
|
||||||
|
{"preferred_server", MXS_MODULE_PARAM_SERVER},
|
||||||
{MXS_END_MODULE_PARAMS}
|
{MXS_END_MODULE_PARAMS}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1322,6 +1322,14 @@ enum showdb_response SchemaRouterSession::parse_mapping_response(SSRBackend& bre
|
|||||||
data, target->unique_name, duplicate->unique_name,
|
data, target->unique_name, duplicate->unique_name,
|
||||||
m_client->user, m_client->remote);
|
m_client->user, m_client->remote);
|
||||||
}
|
}
|
||||||
|
else if (m_config->preferred_server == target)
|
||||||
|
{
|
||||||
|
/** In conflict situations, use the preferred server */
|
||||||
|
MXS_INFO("Forcing location of '%s' from '%s' to '%s'",
|
||||||
|
data, m_shard.get_location(data)->unique_name,
|
||||||
|
target->unique_name);
|
||||||
|
m_shard.replace_location(data, target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MXS_FREE(data);
|
MXS_FREE(data);
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,12 @@ bool Shard::add_location(std::string db, SERVER* target)
|
|||||||
return m_map.insert(std::make_pair(db, target)).second;
|
return m_map.insert(std::make_pair(db, target)).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Shard::replace_location(std::string db, SERVER* target)
|
||||||
|
{
|
||||||
|
std::transform(db.begin(), db.end(), db.begin(), ::tolower);
|
||||||
|
m_map[db] = target;
|
||||||
|
}
|
||||||
|
|
||||||
SERVER* Shard::get_location(std::string db)
|
SERVER* Shard::get_location(std::string db)
|
||||||
{
|
{
|
||||||
SERVER* rval = NULL;
|
SERVER* rval = NULL;
|
||||||
|
@ -52,6 +52,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
SERVER* get_location(std::string db);
|
SERVER* get_location(std::string db);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Change the location of a database
|
||||||
|
*
|
||||||
|
* @param db Database to relocate
|
||||||
|
* @param target Target where database is relocated to
|
||||||
|
*/
|
||||||
|
void replace_location(std::string db, SERVER* target);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if shard contains stale information
|
* @brief Check if shard contains stale information
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user