Merge branch '2.2' into develop
This commit is contained in:
@ -36,7 +36,7 @@ These tutorials are for specific use cases and module combinations.
|
||||
|
||||
- [Administration Tutorial](Tutorials/Administration-Tutorial.md)
|
||||
- [Avro Router Tutorial](Tutorials/Avrorouter-Tutorial.md)
|
||||
- [Failover with Keepalived](Tutorials/Failover-with-Keepalived.md)
|
||||
- [MaxScale Failover with Keepalived and MaxCtrl](Tutorials/MaxScale-Failover-with-Keepalived-and-MaxCtrl.md)
|
||||
- [Filter Tutorial](Tutorials/Filter-Tutorial.md)
|
||||
- [Galera Cluster Connection Routing Tutorial](Tutorials/Galera-Cluster-Connection-Routing-Tutorial.md)
|
||||
- [Galera Gluster Read Write Splitting Tutorial](Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md)
|
||||
|
@ -21,6 +21,7 @@ plugin modules that tailor the behavior of the program.
|
||||
* [Diagnostic Modules](#diagnostic-modules)
|
||||
* [Monitor Modules](#monitor-modules)
|
||||
* [Filter Modules](#filter-modules)
|
||||
* [Encrypting Passwords](#encrypting-passwords)
|
||||
* [Reloading Configuration](#reloading-configuration)
|
||||
* [Authentication](#authentication)
|
||||
* [Error Reporting](#error-reporting)
|
||||
@ -887,9 +888,6 @@ In versions of MySQL 5.7.6 and later, the `Password` column was replaced by
|
||||
`authentication_string`. Change `user.password` above with
|
||||
`user.authentication_string`.
|
||||
|
||||
**Note**: If authentication fails, MaxScale will try to refresh the list of
|
||||
database users used by the service up to 4 times every 30 seconds.
|
||||
|
||||
<a id="passwd"></a>
|
||||
#### `password`
|
||||
|
||||
@ -1524,6 +1522,49 @@ can add a filter to a service and combine multiple filters in one service.
|
||||
* [Query Redirection Filter](../Filters/Named-Server-Filter.md)
|
||||
* [RabbitMQ Filter](../Filters/RabbitMQ-Filter.md)
|
||||
|
||||
|
||||
## Encrypting Passwords
|
||||
|
||||
Passwords stored in the maxscale.cnf file may optionally be encrypted for added security.
|
||||
This is done by creation of an encryption key on installation of MariaDB MaxScale.
|
||||
Encryption keys may be created manually by executing the maxkeys utility with the argument
|
||||
of the filename to store the key. The default location MariaDB MaxScale stores
|
||||
the keys is `/var/lib/maxscale`.
|
||||
|
||||
```
|
||||
# Usage: maxkeys [PATH]
|
||||
maxkeys /var/lib/maxscale/
|
||||
```
|
||||
|
||||
Changing the encryption key for MariaDB MaxScale will invalidate any currently
|
||||
encrypted keys stored in the maxscale.cnf file.
|
||||
|
||||
## Creating Encrypted Passwords
|
||||
|
||||
Encrypted passwords are created by executing the maxpasswd command with the location
|
||||
of the .secrets file and the password you require to encrypt as an argument.
|
||||
|
||||
```
|
||||
# Usage: maxpasswd PATH PASSWORD
|
||||
maxpasswd /var/lib/maxscale/ MaxScalePw001
|
||||
61DD955512C39A4A8BC4BB1E5F116705
|
||||
```
|
||||
|
||||
The output of the maxpasswd command is a hexadecimal string, this should be inserted
|
||||
into the maxscale.cnf file in place of the ordinary, plain text, password.
|
||||
MariaDB MaxScale will determine this as an encrypted password and automatically decrypt
|
||||
it before sending it the database server.
|
||||
|
||||
```
|
||||
[Split Service]
|
||||
type=service
|
||||
router=readwritesplit
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxscale
|
||||
password=61DD955512C39A4A8BC4BB1E5F116705
|
||||
```
|
||||
|
||||
|
||||
## Reloading Configuration
|
||||
|
||||
**Note:** This functionality has been deprecated. Use the MaxScale REST API or the
|
||||
|
@ -174,44 +174,9 @@ that discusses the concept and gives some examples of ways to use filters.
|
||||
|
||||
## Encrypting Passwords
|
||||
|
||||
Passwords stored in the maxscale.cnf file may optionally be encrypted for added security.
|
||||
This is done by creation of an encryption key on installation of MariaDB MaxScale.
|
||||
Encryption keys may be created manually by executing the maxkeys utility with the argument
|
||||
of the filename to store the key. The default location MariaDB MaxScale stores
|
||||
the keys is `/var/lib/maxscale`.
|
||||
|
||||
```
|
||||
# Usage: maxkeys [PATH]
|
||||
maxkeys /var/lib/maxscale/
|
||||
```
|
||||
|
||||
Changing the encryption key for MariaDB MaxScale will invalidate any currently
|
||||
encrypted keys stored in the maxscale.cnf file.
|
||||
|
||||
### Creating Encrypted Passwords
|
||||
|
||||
Encrypted passwords are created by executing the maxpasswd command with the location
|
||||
of the .secrets file and the password you require to encrypt as an argument.
|
||||
|
||||
```
|
||||
# Usage: maxpasswd PATH PASSWORD
|
||||
maxpasswd /var/lib/maxscale/ MaxScalePw001
|
||||
61DD955512C39A4A8BC4BB1E5F116705
|
||||
```
|
||||
|
||||
The output of the maxpasswd command is a hexadecimal string, this should be inserted
|
||||
into the maxscale.cnf file in place of the ordinary, plain text, password.
|
||||
MariaDB MaxScale will determine this as an encrypted password and automatically decrypt
|
||||
it before sending it the database server.
|
||||
|
||||
```
|
||||
[Split Service]
|
||||
type=service
|
||||
router=readwritesplit
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxscale
|
||||
password=61DD955512C39A4A8BC4BB1E5F116705
|
||||
```
|
||||
Read the [Encrypting Passwords](Configuration-Guide.md#encrypting-passwords)
|
||||
section of the configuration guide to set up password encryption for the
|
||||
configuration file.
|
||||
|
||||
## Running MariaDB MaxScale
|
||||
|
||||
|
@ -120,9 +120,8 @@ service=Galera Service
|
||||
```
|
||||
|
||||
A listener must also define the protocol module it will use for the incoming
|
||||
network protocol, currently this should be the MariaDBClient protocol for all
|
||||
database listeners. The listener may then supply a network port to listen on
|
||||
and/or a socket within the file system.
|
||||
network protocol, currently this must be the `MariaDBClient` protocol for all
|
||||
database listeners. The listener must also supply the network port to listen on.
|
||||
|
||||
```
|
||||
[Galera Listener]
|
||||
@ -130,7 +129,6 @@ type=listener
|
||||
service=Galera Service
|
||||
protocol=MariaDBClient
|
||||
port=4306
|
||||
socket=/tmp/DB.Cluster
|
||||
```
|
||||
|
||||
An address parameter may be given if the listener is required to bind to a particular
|
||||
|
@ -71,7 +71,9 @@ type=listener
|
||||
service=Splitter Service
|
||||
```
|
||||
|
||||
A listener must also define the protocol module it will use for the incoming network protocol, currently this should be the `MariaDBClient` protocol for all database listeners. The listener may then supply a network port to listen on and/or a socket within the file system.
|
||||
A listener must also define the protocol module it will use for the incoming
|
||||
network protocol, currently this must be the `MariaDBClient` protocol for all
|
||||
database listeners. The listener must also supply the network port to listen on.
|
||||
|
||||
```
|
||||
[Splitter Listener]
|
||||
@ -79,7 +81,6 @@ type=listener
|
||||
service=Splitter Service
|
||||
protocol=MariaDBClient
|
||||
port=3306
|
||||
socket=/tmp/ClusterMaster
|
||||
```
|
||||
|
||||
An address parameter may be given if the listener is required to bind to a particular network address when using hosts with multiple network addresses. The default behavior is to listen on all network interfaces.
|
||||
|
@ -106,7 +106,9 @@ type=listener
|
||||
service=Read-Service
|
||||
```
|
||||
|
||||
A listener must also define the protocol module it will use for the incoming network protocol, currently this should be the MariaDBClient protocol for all database listeners. The listener may then supply a network port to listen on and/or a socket within the file system.
|
||||
A listener must also define the protocol module it will use for the incoming
|
||||
network protocol, currently this must be the `MariaDBClient` protocol for all
|
||||
database listeners. The listener must also supply the network port to listen on.
|
||||
|
||||
```
|
||||
[Write-Listener]
|
||||
@ -114,7 +116,6 @@ type=listener
|
||||
service=Write-Service
|
||||
protocol=MariaDBClient
|
||||
port=4306
|
||||
socket=/tmp/ClusterMaster
|
||||
|
||||
[Read-Listener]
|
||||
type=listener
|
||||
|
@ -106,9 +106,8 @@ service=Splitter Service
|
||||
```
|
||||
|
||||
A listener must also define the protocol module it will use for the incoming
|
||||
network protocol, currently this should be the `MariaDBClient` protocol for all
|
||||
database listeners. The listener may then supply a network port to listen on
|
||||
and/or a socket within the file system.
|
||||
network protocol, currently this must be the `MariaDBClient` protocol for all
|
||||
database listeners. The listener must also supply the network port to listen on.
|
||||
|
||||
```
|
||||
[Splitter Listener]
|
||||
@ -116,7 +115,6 @@ type=listener
|
||||
service=Splitter Service
|
||||
protocol=MariaDBClient
|
||||
port=3306
|
||||
socket=/tmp/ClusterMaster
|
||||
```
|
||||
|
||||
An address parameter may be given if the listener is required to bind to a
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
set(MAXSCALE_VERSION_MAJOR "2" CACHE STRING "Major version")
|
||||
set(MAXSCALE_VERSION_MINOR "1" CACHE STRING "Minor version")
|
||||
set(MAXSCALE_VERSION_PATCH "14" CACHE STRING "Patch version")
|
||||
set(MAXSCALE_VERSION_PATCH "15" CACHE STRING "Patch version")
|
||||
|
||||
# This should only be incremented if a package is rebuilt
|
||||
set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number")
|
||||
|
@ -7,54 +7,6 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
typedef std::set<std::string> StringSet;
|
||||
|
||||
// Note: This is backported from 2.2 and can be replaced with MaxScales::get_server_status once merged
|
||||
StringSet state(TestConnections& test, const char* name)
|
||||
{
|
||||
StringSet rval;
|
||||
int exit_code;
|
||||
char* res = test.maxscales->ssh_node_output_f(0, true, &exit_code,
|
||||
"maxadmin list servers|grep \'%s\'", name);
|
||||
char* pipe = strrchr(res, '|');
|
||||
|
||||
if (res && pipe)
|
||||
{
|
||||
pipe++;
|
||||
char* tok = strtok(pipe, ",");
|
||||
|
||||
while (tok)
|
||||
{
|
||||
char* p = tok;
|
||||
char *end = strchr(tok, '\n');
|
||||
if (!end)
|
||||
{
|
||||
end = strchr(tok, '\0');
|
||||
}
|
||||
|
||||
// Trim leading whitespace
|
||||
while (p < end && isspace(*p))
|
||||
{
|
||||
p++;
|
||||
}
|
||||
|
||||
// Trim trailing whitespace
|
||||
while (end > tok && isspace(*end))
|
||||
{
|
||||
*end-- = '\0';
|
||||
}
|
||||
|
||||
rval.insert(p);
|
||||
tok = strtok(NULL, ",\n");
|
||||
}
|
||||
}
|
||||
|
||||
free(res);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
TestConnections test(argc, argv);
|
||||
@ -63,6 +15,7 @@ int main(int argc, char** argv)
|
||||
execute_query(test.repl->nodes[3], "CHANGE MASTER TO MASTER_HOST='%s', MASTER_PORT=%d",
|
||||
test.repl->IP_private[2], test.repl->port[2]);
|
||||
execute_query(test.repl->nodes[3], "START SLAVE");
|
||||
sleep(5);
|
||||
|
||||
StringSet master = {"Master", "Running"};
|
||||
StringSet slave = {"Slave", "Running"};
|
||||
@ -74,10 +27,10 @@ int main(int argc, char** argv)
|
||||
test.tprintf("%s", output);
|
||||
free(output);
|
||||
|
||||
test.add_result(state(test, "server1") != master, "server1 is not a master");
|
||||
test.add_result(state(test, "server2") != slave, "server2 is not a slave");
|
||||
test.add_result(state(test, "server3") != relay_master, "server3 is not a relay master");
|
||||
test.add_result(state(test, "server4") != slave, "server4 is not a slave");
|
||||
test.add_result(test.maxscales->get_server_status("server1") != master, "server1 is not a master");
|
||||
test.add_result(test.maxscales->get_server_status("server2") != slave, "server2 is not a slave");
|
||||
test.add_result(test.maxscales->get_server_status("server3") != relay_master, "server3 is not a relay master");
|
||||
test.add_result(test.maxscales->get_server_status("server4") != slave, "server4 is not a slave");
|
||||
|
||||
execute_query(test.repl->nodes[2], "STOP SLAVE IO_THREAD");
|
||||
sleep(10);
|
||||
@ -86,10 +39,10 @@ int main(int argc, char** argv)
|
||||
output = test.maxscales->ssh_node_output(0, "maxadmin list servers", true, &exit_code);
|
||||
test.tprintf("%s", output);
|
||||
free(output);
|
||||
test.add_result(state(test, "server1") != master, "server1 is not a master");
|
||||
test.add_result(state(test, "server2") != slave, "server2 is not a slave");
|
||||
test.add_result(state(test, "server3") != relay_master, "server3 is not a relay master");
|
||||
test.add_result(state(test, "server4") != slave, "server4 is not a slave");
|
||||
test.add_result(test.maxscales->get_server_status("server1") != master, "server1 is not a master");
|
||||
test.add_result(test.maxscales->get_server_status( "server2") != slave, "server2 is not a slave");
|
||||
test.add_result(test.maxscales->get_server_status("server3") != relay_master, "server3 is not a relay master");
|
||||
test.add_result(test.maxscales->get_server_status("server4") != slave, "server4 is not a slave");
|
||||
|
||||
test.repl->fix_replication();
|
||||
return test.global_result;
|
||||
|
@ -90,7 +90,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
Test->stop_timeout();
|
||||
sleep(5);
|
||||
sleep(20);
|
||||
Test->check_maxscale_alive(0);
|
||||
Test->check_current_operations(0, 0);
|
||||
|
||||
|
@ -179,6 +179,18 @@ MYSQL *mxs_mysql_real_connect(MYSQL *con, SERVER *server, const char *user, cons
|
||||
mysql_optionsv(con, MYSQL_OPT_RECONNECT, &yes);
|
||||
mysql_optionsv(con, MYSQL_INIT_COMMAND, "SET SQL_MODE=''");
|
||||
|
||||
MXS_CONFIG* config = config_get_global_options();
|
||||
|
||||
if (config->local_address)
|
||||
{
|
||||
if (mysql_optionsv(con, MYSQL_OPT_BIND, config->local_address) != 0)
|
||||
{
|
||||
MXS_ERROR("'local_address' specified in configuration file, but could not "
|
||||
"configure MYSQL handle. MaxScale will try to connect using default "
|
||||
"address.");
|
||||
}
|
||||
}
|
||||
|
||||
MYSQL* mysql = mysql_real_connect(con, server->name, user, passwd, NULL, server->port, NULL, 0);
|
||||
|
||||
if (mysql)
|
||||
|
@ -9,6 +9,7 @@ add_executable(test_hash test_hash.cc)
|
||||
add_executable(test_hint test_hint.cc)
|
||||
add_executable(test_http test_http.cc)
|
||||
add_executable(test_json test_json.cc)
|
||||
add_executable(test_local_address test_local_address.cc)
|
||||
add_executable(test_log test_log.cc)
|
||||
add_executable(test_logorder test_logorder.cc)
|
||||
add_executable(test_logthrottling test_logthrottling.cc)
|
||||
@ -38,6 +39,7 @@ target_link_libraries(test_hash maxscale-common)
|
||||
target_link_libraries(test_hint maxscale-common)
|
||||
target_link_libraries(test_http maxscale-common)
|
||||
target_link_libraries(test_json maxscale-common)
|
||||
target_link_libraries(test_local_address maxscale-common)
|
||||
target_link_libraries(test_log maxscale-common)
|
||||
target_link_libraries(test_logorder maxscale-common)
|
||||
target_link_libraries(test_logthrottling maxscale-common)
|
||||
|
183
server/core/test/test_local_address.cc
Normal file
183
server/core/test/test_local_address.cc
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <maxscale/config.h>
|
||||
#include <maxscale/mysql_utils.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
char USAGE[] =
|
||||
"usage: test_local_address -u user [-p password] [-a address] [-h host] [-s success]\n"
|
||||
"\n"
|
||||
"user : The user to connect as.\n"
|
||||
"password: The password of the user, default none.\n"
|
||||
"address : The address to connect from, default none specified.\n"
|
||||
"host : The address of the host to connect to, default 127.0.0.1.\n"
|
||||
"success : (0|1), whether the connection attempt is expected to succeed or not, defaul 1.\n"
|
||||
"\n"
|
||||
"Example:\n"
|
||||
"\n"
|
||||
"MariaDB [(none)]> create user 'l1'@'192.168.1.254';\n"
|
||||
"MariaDB [(none)]> create user 'l2'@'127.0.0.1';\n"
|
||||
"\n"
|
||||
"$ ./test_local_address -s 1 -u l1 -a 192.168.1.254\n"
|
||||
"User : l1\n"
|
||||
"Password: (none)\n"
|
||||
"Server : 127.0.0.1\n"
|
||||
"Address : 192.168.1.254\n"
|
||||
"Success : 1\n"
|
||||
"\n"
|
||||
"Could connect, as expected.\n"
|
||||
"$ ./test_local_address -s 0 -u l1 -a 127.0.0.1\n"
|
||||
"User : l1\n"
|
||||
"Password: (none)\n"
|
||||
"Server : 127.0.0.1\n"
|
||||
"Address : 127.0.0.1\n"
|
||||
"Success : 0\n"
|
||||
"\n"
|
||||
"Could not connect, as expected. "
|
||||
"Reported error: Access denied for user 'l1'@'localhost' (using password: NO)\n"
|
||||
"$ ./test_local_address -s 1 -u l2 -a 127.0.0.1\n"
|
||||
"User : l2\n"
|
||||
"Password: (none)\n"
|
||||
"Server : 127.0.0.1\n"
|
||||
"Address : 127.0.0.1\n"
|
||||
"Success : 1\n"
|
||||
"\n"
|
||||
"Could connect, as expected.\n"
|
||||
"$ ./test_local_address -s 0 -u l2 -a 192.168.1.254\n"
|
||||
"User : l2\n"
|
||||
"Password: (none)\n"
|
||||
"Server : 127.0.0.1\n"
|
||||
"Address : 192.168.1.254\n"
|
||||
"Success : 0\n"
|
||||
"\n"
|
||||
"Could not connect, as expected. "
|
||||
"Reported error: Access denied for user 'l2'@'192.168.1.254' (using password: NO)\n";
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
int test(bool success, const char* zHost, const char* zUser, const char* zPassword, const char* zAddress)
|
||||
{
|
||||
int rv = EXIT_FAILURE;
|
||||
|
||||
MXS_CONFIG* config = config_get_global_options();
|
||||
config->local_address = const_cast<char*>(zAddress);
|
||||
|
||||
SERVER server;
|
||||
memset(&server, 0, sizeof(server));
|
||||
|
||||
strcpy(server.name, zHost);
|
||||
server.port = 3306;
|
||||
|
||||
MYSQL* pMysql = mysql_init(NULL);
|
||||
|
||||
MYSQL* pConn = mxs_mysql_real_connect(pMysql, &server, zUser, zPassword);
|
||||
|
||||
if (pConn)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
cout << "Could connect, as expected." << endl;
|
||||
rv = EXIT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Error: Connection succeeded, although expected not to." << endl;
|
||||
}
|
||||
|
||||
mysql_close(pConn);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
cout << "Could not connect, as expected. Reported error: " << mysql_error(pMysql) << endl;
|
||||
rv = EXIT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Error: " << mysql_error(pMysql) << endl;
|
||||
}
|
||||
|
||||
mysql_close(pMysql);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int rv = EXIT_SUCCESS;
|
||||
|
||||
int opt;
|
||||
|
||||
const char* zUser = NULL;
|
||||
const char* zPassword = NULL;
|
||||
const char* zAddress = NULL;
|
||||
const char* zHost = "127.0.0.1";
|
||||
bool success = true;
|
||||
|
||||
while ((opt = getopt(argc, argv, "a:h:p:s:u:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'a':
|
||||
zAddress = optarg;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
zHost = optarg;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
zPassword = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
success = (atoi(optarg) == 0) ? false : true;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
zUser = optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((rv == EXIT_SUCCESS) && zUser)
|
||||
{
|
||||
cout << "User : " << zUser << endl;
|
||||
cout << "Password: " << (zPassword ? zPassword : "(none)") << endl;
|
||||
cout << "Server : " << zHost << endl;
|
||||
cout << "Address : " << (zAddress ? zAddress : "(default)") << endl;
|
||||
cout << "Success : " << success << endl;
|
||||
cout << endl;
|
||||
|
||||
rv = test(success, zHost, zUser, zPassword, zAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << USAGE << endl;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
@ -1255,6 +1255,7 @@ static bool slave_receiving_events(MariaDBMonitor* handle)
|
||||
MySqlServerInfo* info = get_server_info(handle, server);
|
||||
|
||||
if (info->slave_configured &&
|
||||
info->slave_status.slave_io_running &&
|
||||
info->slave_status.master_server_id == master_id &&
|
||||
difftime(time(NULL), info->latest_event) < handle->master_failure_timeout)
|
||||
{
|
||||
|
Reference in New Issue
Block a user