Merge branch '2.2' into develop

This commit is contained in:
Markus Mäkelä 2018-06-08 11:30:55 +03:00
commit 0d73530ff3
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
44 changed files with 274 additions and 182 deletions

View File

@ -73,6 +73,7 @@ MXS_BEGIN_DECLS
#define MXS_JSON_PTR_PARAM_SSL_CA_CERT MXS_JSON_PTR_PARAMETERS "/ssl_ca_cert"
#define MXS_JSON_PTR_PARAM_SSL_VERSION MXS_JSON_PTR_PARAMETERS "/ssl_version"
#define MXS_JSON_PTR_PARAM_SSL_CERT_VERIFY_DEPTH MXS_JSON_PTR_PARAMETERS "/ssl_cert_verify_depth"
#define MXS_JSON_PTR_PARAM_SSL_VERIFY_PEER_CERT MXS_JSON_PTR_PARAMETERS "/ssl_verify_peer_certificate"
/** Non-parameter JSON pointers */
#define MXS_JSON_PTR_MODULE "/data/attributes/module"

View File

@ -33,7 +33,7 @@ any other names or paths.
## 2. Build and upgrade test
The Jenkins
[Build_all](http://localhost:8089/job/build_all/)
[build_for_release](http://127.0.0.1:8089/job/build_for_release/)
job should be used for building the packages.
Note that the above will not work unless you have set up an
@ -42,57 +42,34 @@ ssh tunnel to Jenkins:
$ ssh -f -N -L 8089:127.0.0.1:8089 vagrant@max-tst-01.mariadb.com
```
Usually two runs are done: one for _release_ and one for _debug_ packages.
### Parameters to define
Use defaults for all other parameters.
#### `scm_source`
This is the tag that is used to build the release.
#### source
```
refs/tags/maxscale-x.y.z-ttN
```
#### `version_number`
#### target
Debug build:
```
maxscale-x.y.z-debug
```
Release build:
```
maxscale-x.y.z-release
```
#### cmake_flags
Debug build:
```
-DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DBUILD_MMMON=Y -DBUILD_CDC=Y
```
Release build:
```
-DBUILD_TESTS=N -DBUILD_MMMON=Y -DBUILD_CDC=Y
```
#### run_upgrade_test
The version number of this release in x.y.z format. This will create two packages; maxscale-x.y.z-release and maxscale-x.y.z-debug.
```
yes
x.y.z
```
#### old_target
#### `old_target`
Name of some existing Maxscale repository
(please check http://max-tst-01.mariadb.com/ci-repository/
before build).
The previous released version, used by upgrade tests.
```
maxscale-x'.y'.z'-release
x.y.z
```
### Options for 1.4.x build
### 1.4.x build
Use the [build_all](http://127.0.0.1:8089/job/build_all/) job.
For `1.4` builds the default values of the following parameters
should be changed:

View File

@ -11,9 +11,9 @@ monitor_interval=1000
detect_standalone_master=true
failcount=2
allow_cluster_recovery=false
backend_connect_timeout=2
backend_read_timeout=3
backend_write_timeout=3
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW Split Router]
type=service

View File

@ -16,6 +16,9 @@ auto_rejoin=true
replication_user=repl
replication_password=repl
ignore_external_masters=true
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW Split Router]
type=service

View File

@ -14,9 +14,9 @@ allow_cluster_recovery=true
auto_failover=true
replication_user=repl
replication_password=repl
backend_connect_timeout=15
backend_read_timeout=15
backend_write_timeout=15
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW Split Router]
type=service

View File

@ -13,9 +13,9 @@ failcount=1
allow_cluster_recovery=true
replication_user=repl
replication_password=repl
backend_connect_timeout=15
backend_read_timeout=15
backend_write_timeout=15
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW Split Router]
type=service

View File

@ -13,7 +13,9 @@ detect_standalone_master=true
auto_failover=false
replication_user=repl
replication_password=repl
backend_connect_timeout=1
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW-Split-Router]
type=service

View File

@ -13,7 +13,9 @@ detect_standalone_master=true
auto_failover=false
replication_user=repl
replication_password=repl
backend_connect_timeout=1
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW Split Router]
type=service

View File

@ -13,7 +13,9 @@ detect_standalone_master=true
auto_failover=false
replication_user=repl
replication_password=repl
backend_connect_timeout=1
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW-Split-Router]
type=service

View File

@ -14,7 +14,10 @@ auto_failover=true
auto_rejoin=true
replication_user=repl
replication_password=repl
backend_connect_timeout=1
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
failcount=1
[RW-Split-Router]
type=service

View File

@ -13,7 +13,9 @@ detect_standalone_master=true
auto_failover=true
replication_user=repl
replication_password=repl
backend_connect_timeout=1
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW-Split-Router]
type=service

View File

@ -14,7 +14,9 @@ auto_failover=true
auto_rejoin=true
replication_user=repl
replication_password=repl
backend_connect_timeout=1
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW-Split-Router]
type=service

View File

@ -14,9 +14,10 @@ auto_failover=true
auto_rejoin=true
replication_user=repl
replication_password=repl
backend_connect_timeout=5
backend_read_timeout=5
backend_write_timeout=5
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
failcount=1
[RW-Split-Router]
type=service

View File

@ -13,9 +13,9 @@ failcount=1
allow_cluster_recovery=true
replication_user=repl
replication_password=repl
backend_connect_timeout=3
backend_read_timeout=3
backend_write_timeout=3
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
auto_failover=true
auto_rejoin=true

View File

@ -13,9 +13,9 @@ failcount=1
allow_cluster_recovery=true
replication_user=repl
replication_password=repl
backend_connect_timeout=3
backend_read_timeout=3
backend_write_timeout=3
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
auto_failover=true
[RW Split Router]

View File

@ -14,9 +14,9 @@ auto_failover=false
auto_rejoin=true
replication_user=repl
replication_password=repl
backend_connect_timeout=5
backend_read_timeout=5
backend_write_timeout=5
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW-Split-Router]
type=service

View File

@ -14,7 +14,10 @@ auto_failover=true
auto_rejoin=false
replication_user=repl
replication_password=repl
backend_connect_timeout=1
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
failcount=1
[RW-Split-Router]
type=service

View File

@ -14,9 +14,9 @@ auto_failover=false
auto_rejoin=false
replication_user=repl
replication_password=repl
backend_connect_timeout=5
backend_read_timeout=5
backend_write_timeout=5
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW-Split-Router]
type=service

View File

@ -24,13 +24,13 @@ void reset_replication(TestConnections& test)
{
int ind = master_id - 1;
replicate_from(test, 0, ind);
sleep(3);
test.maxscales->wait_for_monitor();
get_output(test);
int ec;
stringstream switchover;
switchover << "maxadmin call command mysqlmon switchover MySQL-Monitor server1 server" << master_id;
test.maxscales->ssh_node_output(0, switchover.str().c_str() , true, &ec);
sleep(3);
test.maxscales->wait_for_monitor();
master_id = get_master_server_id(test);
cout << "Master server id is now back to " << master_id << endl;
test.assert(master_id == 1, "Switchover back to server1 failed");
@ -80,11 +80,9 @@ void prepare_test_2(TestConnections& test)
cout << LINE << endl;
test.repl->connect();
check(test);
sleep(1);
print_gtids(test);
test.try_query(test.repl->nodes[1], "STOP SLAVE;");
test.try_query(test.repl->nodes[1], "RESET SLAVE ALL;");
sleep(1);
get_output(test);
if (test.global_result == 0)
{
@ -108,7 +106,7 @@ void check_test_2(TestConnections& test)
// Reset state
replicate_from(test, 1, master_id - 1);
sleep(3);
test.maxscales->wait_for_monitor();
get_output(test);
StringSet node_states = test.get_server_status("server2");
test.assert(node_states.find("Slave") != node_states.end(), "Server 2 is not replicating.");
@ -145,7 +143,7 @@ void prepare_test_3(TestConnections& test)
test.repl->start_node(2, (char *) "");
test.repl->start_node(3, (char *) "");
test.maxscales->start_maxscale(0);
sleep(2);
test.maxscales->wait_for_monitor();
test.repl->connect();
test.tprintf("Settings changed.");
@ -182,7 +180,6 @@ void check_test_3(TestConnections& test)
test.repl->stop_node(1);
test.repl->stop_node(2);
test.repl->stop_node(3);
sleep(4);
test.repl->restore_server_settings(1);
test.repl->restore_server_settings(2);
@ -191,6 +188,5 @@ void check_test_3(TestConnections& test)
test.repl->start_node(1, (char *) "");
test.repl->start_node(2, (char *) "");
test.repl->start_node(3, (char *) "");
sleep(2);
test.maxscales->start_maxscale(0);
}

View File

@ -33,7 +33,7 @@ int main(int argc, char *argv[])
execute_query(test->repl->nodes[3], "STOP SLAVE;RESET SLAVE ALL;");
test->tprintf("Wait for the monitor to detect it ");
sleep(15);
test.maxscales->wait_for_monitor();
test->tprintf("Connect and insert should work ");
char *output = test->ssh_maxscale_output(true, "maxadmin list servers");
@ -49,7 +49,7 @@ int main(int argc, char *argv[])
test->repl->unblock_node(2);
test->tprintf("Wait for the monitor to detect it ");
sleep(15);
test.maxscales->wait_for_monitor();
test->tprintf("Check that we are still using the last node to which we failed over "
"to and that the old nodes are in maintenance mode");

View File

@ -1,4 +1,6 @@
#include "maxscales.h"
#include <sstream>
#include <unordered_map>
Maxscales::Maxscales(const char *pref, const char *test_cwd, bool verbose)
{
@ -431,3 +433,56 @@ int Maxscales::port(enum service type, int m) const
}
return -1;
}
void Maxscales::wait_for_monitor(int intervals, int m)
{
//Helper for getting number of monitor ticks
auto get_ticks = [&](std::string name)
{
int rc;
char* ticks = ssh_node_output_f(m, false, &rc, "maxctrl api get monitors/%s data.attributes.ticks", name.c_str());
char* ptr;
int rval = strtol(ticks, &ptr, 10);
if (ptr == ticks || (*ptr != '\0' && !isspace(*ptr)))
{
printf("ERROR, invalid monitor tick value: %s\n", ticks);
rval = -1;
}
free(ticks);
return rval;
};
int rc = 0;
// Get a list of monitor names that are running
char* monitors = ssh_node_output_f(m, false, &rc, "maxctrl --tsv list monitors|grep Running|cut -f 1");
std::istringstream is;
is.str(monitors);
free(monitors);
std::string name;
std::unordered_map<std::string, int> ticks;
// For each monitor, store the current monitor tick
while (std::getline(is, name))
{
ticks[name] = get_ticks(name);
}
for (auto a: ticks)
{
// Wait a maximum of 60 seconds for a single monitor interval
for (int i = 0; i < 60; i++)
{
int start = a.second;
int end = get_ticks(a.first);
if (start == -1 || end == -1 || end - start >= intervals)
{
break;
}
sleep(1);
}
}
}

View File

@ -262,6 +262,16 @@ public:
*/
StringSet get_server_status(const char* name, int m = 0);
/**
* Wait until the monitors have performed at least one monitoring operation
*
* The function waits until all monitors have performed at least one monitoring cycle.
*
* @param intervals The number of monitor intervals to wait
* @param m Number of Maxscale node
*/
void wait_for_monitor(int intervals = 1, int m = 0);
};
#endif // MAXSCALES_H

View File

@ -19,8 +19,10 @@ void double_cursor(TestConnections& test, MYSQL* conn)
const char* query = "SELECT id FROM test.t1";
int rc = mysql_stmt_prepare(stmt1, query, strlen(query));
test.assert(rc == 0, "First prepare should work: %s %s", mysql_stmt_error(stmt1), mysql_error(conn));
int type = CURSOR_TYPE_READ_ONLY;
mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, &type);
unsigned long type = CURSOR_TYPE_READ_ONLY;
test.assert(mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, &type) == 0,
"Set of first attribute should work: %s %s",
mysql_stmt_error(stmt1), mysql_error(conn));
MYSQL_BIND bind[1] {};
uint32_t id;
@ -36,7 +38,9 @@ void double_cursor(TestConnections& test, MYSQL* conn)
MYSQL_STMT* stmt2 = mysql_stmt_init(conn);
rc = mysql_stmt_prepare(stmt2, query, strlen(query));
test.assert(rc == 0, "Second prepare should work: %s %s", mysql_stmt_error(stmt2), mysql_error(conn));
mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, &type);
test.assert(mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, &type) == 0,
"Set of second attribute should work: %s %s",
mysql_stmt_error(stmt2), mysql_error(conn));
mysql_stmt_bind_result(stmt2, bind);
test.assert(mysql_stmt_execute(stmt2) == 0, "Execute of second statement should work: %s %s",

View File

@ -63,10 +63,10 @@ void restore_servers(TestConnections& test, bool events_added)
replicate_from(test, 0, 3);
replicate_from(test, 1, 3);
replicate_from(test, 2, 3);
sleep(10);
test.maxscales->wait_for_monitor();
o1 = test.maxscales->ssh_node_output(0,
"maxadmin call command mariadbmon switchover MySQL-Monitor server1 server4", true, &dummy);
sleep(10);
test.maxscales->wait_for_monitor();
int master_id = get_master_server_id(test);
test.assert(master_id == 1, "Switchover failed to set server1 as master.");
}
@ -106,7 +106,7 @@ int main(int argc, char *argv[])
test.try_query(test.repl->nodes[3], "STOP SLAVE;RESET SLAVE ALL;");
test.tprintf(" Wait for the monitor to detect it ");
sleep(10);
test.maxscales->wait_for_monitor(3);
test.tprintf(" Connect and insert should work ");
get_output(test);
@ -136,7 +136,7 @@ int main(int argc, char *argv[])
test.repl->unblock_node(2);
test.tprintf(" Wait for the monitor to detect it ");
sleep(10);
test.maxscales->wait_for_monitor();
test.tprintf("Check that we are still using the last node to which we failed over "
"to and that the old nodes are in maintenance mode");

View File

@ -60,14 +60,14 @@ int main(int argc, char** argv)
test.tprintf("Start by having the current master replicate from the external server");
test.repl->connect();
test.repl->replicate_from(0, 3);
sleep(10);
test.maxscales->wait_for_monitor();
check_status(test, "server1", master_running, "server1 should be the master");
check_status(test, "server2", slave_running, "server2 should be a slave");
check_status(test, "server3", slave_running, "server3 should be a slave");
test.tprintf("Stop server1, expect server2 to be promoted as the master");
test.repl->stop_node(0);
sleep(10);
test.maxscales->wait_for_monitor();
check_status(test, "server1", down, "server1 should be down");
check_status(test, "server2", master_running, "server2 should be the master");
@ -76,13 +76,13 @@ int main(int argc, char** argv)
test.tprintf("Configure master-master replication between server2 and the external server");
test.repl->replicate_from(1, 3);
test.repl->replicate_from(3, 1);
sleep(10);
test.maxscales->wait_for_monitor();
check_status(test, "server2", master_running, "server2 should still be the master");
check_status(test, "server3", slave_running, "server3 should be a slave");
test.tprintf("Start server1, expect it to rejoin the cluster");
test.repl->start_node(0);
sleep(10);
test.maxscales->wait_for_monitor();
check_status(test, "server1", slave_running, "server1 should be a slave");
check_status(test, "server2", master_running, "server2 should still be the master");
check_status(test, "server3", slave_running, "server3 should be a slave");
@ -92,7 +92,7 @@ int main(int argc, char** argv)
test.repl->connect();
test.repl->replicate_from(0, 3);
test.repl->replicate_from(3, 0);
sleep(10);
test.maxscales->wait_for_monitor();
check_status(test, "server1", master_running, "server1 should be the master");
check_status(test, "server2", down, "server2 should be down");
@ -100,7 +100,7 @@ int main(int argc, char** argv)
test.tprintf("Start server2, expect it to rejoin the cluster");
test.repl->start_node(1);
sleep(10);
test.maxscales->wait_for_monitor();
check_status(test, "server1", master_running, "server1 should still be the master");
check_status(test, "server2", slave_running, "server2 should be a slave");
check_status(test, "server3", slave_running, "server3 should be a slave");

View File

@ -21,13 +21,13 @@ int main(int argc, char** argv)
test.repl->connect();
delete_slave_binlogs(test);
sleep(2);
test.maxscales->wait_for_monitor();
basic_test(test);
print_gtids(test);
// Part 1
int node0_id = prepare_test_1(test);
sleep(10);
test.maxscales->wait_for_monitor();
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);
sleep(10);
test.maxscales->wait_for_monitor();
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);
sleep(10);
test.maxscales->wait_for_monitor();
check_test_3(test);
return test.global_result;

View File

@ -23,7 +23,6 @@ int main(int argc, char** argv)
test.repl->connect();
delete_slave_binlogs(test);
sleep(2);
basic_test(test);
print_gtids(test);
@ -32,10 +31,9 @@ int main(int argc, char** argv)
// Part 1
node0_id = prepare_test_1(test);
sleep(3);
test.maxscales->ssh_node_output(0, FAILOVER_CMD , true, &ec);
sleep(10);
test.maxscales->wait_for_monitor();
check_test_1(test, node0_id);
if (test.global_result != 0)
@ -45,10 +43,9 @@ int main(int argc, char** argv)
// Part 2
prepare_test_2(test);
sleep(3);
test.maxscales->ssh_node_output(0, FAILOVER_CMD, true, &ec);
sleep(10);
test.maxscales->wait_for_monitor();
check_test_2(test);
if (test.global_result != 0)
@ -58,10 +55,9 @@ int main(int argc, char** argv)
// Part 3
prepare_test_3(test);
sleep(3);
test.maxscales->ssh_node_output(0, FAILOVER_CMD, true, &ec);
sleep(10);
test.maxscales->wait_for_monitor();
check_test_3(test);
return test.global_result;

View File

@ -44,13 +44,13 @@ int main(int argc, char** argv)
test.try_query(nodes[3], CHANGE_CMD);
test.try_query(nodes[3], "START SLAVE;");
sleep(10);
test.maxscales->wait_for_monitor();
get_output(test);
test.tprintf(LINE);
test.tprintf("Stopping master. Failover should not happen.");
test.repl->block_node(0);
sleep(10);
test.maxscales->wait_for_monitor();
get_output(test);
int master_id = get_master_server_id(test);
test.assert(master_id == -1, "Master was promoted even when no slave was eligible.");

View File

@ -122,7 +122,7 @@ void expect(TestConnections& test, const char* zServer, const char* zState1, con
void run(TestConnections& test)
{
sleep(10);
test.maxscales->wait_for_monitor();
int N = test.repl->N;
cout << "Nodes: " << N << endl;
@ -147,7 +147,7 @@ void run(TestConnections& test)
cout << "\nStopping slave " << N - 1 << endl;
test.repl->stop_node(N - 1);
sleep(10);
test.maxscales->wait_for_monitor();
// server4 was stopped, so we expect the state of it to be /Down/,
// and the states of the other ones not to have changed.
@ -171,7 +171,7 @@ void run(TestConnections& test)
cout << "\nStopping master." << endl;
test.repl->stop_node(0);
sleep(10);
test.maxscales->wait_for_monitor();
// server1 (previous master) was taken down, so its state should be /Down/.
// server2 should have been made into master, and server4 should still be down.
@ -183,7 +183,7 @@ void run(TestConnections& test)
cout << "\nBringing up slave " << N - 1 << endl;
test.repl->start_node(N - 1, (char*)"");
sleep(10);
test.maxscales->wait_for_monitor();
// server1 should still be down, server2 still master, and server3 still
// a slave. server4 was brought up, so it should have been rejoined and

View File

@ -204,7 +204,7 @@ void stop_node(XTestConnections& test, int index)
void run(XTestConnections& test)
{
sleep(10);
test.maxscales->wait_for_monitor();
int N = test.repl->N;
cout << "Nodes: " << N << endl;
@ -236,7 +236,7 @@ void run(XTestConnections& test)
cout << "\nClosing connection to MaxScale." << endl;
test.maxscales->close_maxscale_connections(0);
sleep(10);
test.maxscales->wait_for_monitor();
list_servers(test);

View File

@ -157,7 +157,7 @@ void check_server_status(TestConnections& test, int N, int down = -1)
void run(TestConnections& test)
{
sleep(10);
test.maxscales->wait_for_monitor();
int N = test.repl->N;
cout << "Nodes: " << N << endl;
@ -183,14 +183,14 @@ void run(TestConnections& test)
cout << "\nStopping slave " << slave << endl;
test.repl->stop_node(i);
sleep(10);
test.maxscales->wait_for_monitor();
check_server_status(test, N, i);
cout << "\nStarting slave " << slave << endl;
test.repl->start_node(i, (char*)"");
sleep(10);
test.maxscales->wait_for_monitor();
check_server_status(test, N);
}

View File

@ -525,7 +525,7 @@ void run(TestConnections& test)
while (time(NULL) - start < TEST_DURATION)
{
sleep(FAILOVER_DURATION);
test.maxscales->wait_for_monitor();
int master_id = get_master_server_id(test);
@ -534,20 +534,20 @@ void run(TestConnections& test)
cout << "\nStopping node: " << master_id << endl;
test.repl->stop_node(master_id - 1);
sleep(2 * MONITOR_INTERVAL);
test.maxscales->wait_for_monitor();
list_servers(test);
sleep(FAILOVER_DURATION);
test.maxscales->wait_for_monitor();
list_servers(test);
sleep(FAILOVER_DURATION);
test.maxscales->wait_for_monitor();
cout << "\nStarting node: " << master_id << endl;
test.repl->start_node(master_id - 1);
sleep(2 * MONITOR_INTERVAL);
test.maxscales->wait_for_monitor();
list_servers(test);
sleep(FAILOVER_DURATION);
test.maxscales->wait_for_monitor();
list_servers(test);
}
else
@ -556,7 +556,7 @@ void run(TestConnections& test)
}
}
sleep(FAILOVER_DURATION);
test.maxscales->wait_for_monitor();
cout << "\nStopping clients.\n" << flush;
Client::stop();

View File

@ -98,7 +98,7 @@ int main(int argc, char** argv)
test.assert(false, "Could not start MaxScale.");
return test.global_result;
}
sleep(10);
test.maxscales->wait_for_monitor();
get_output(test);
StringSet node2_states = test.get_server_status("server3");
@ -119,7 +119,7 @@ int main(int argc, char** argv)
snprintf(cmd, sizeof(cmd), CHANGE_CMD_FMT, test.repl->IP[3], test.repl->port[3]);
mysql_query(nodes[0], cmd);
mysql_query(nodes[0], "START SLAVE;");
sleep(10);
test.maxscales->wait_for_monitor();
get_output(test);
int master_id = get_master_server_id(test);
test.assert(master_id == 4, "Server 4 should be the cluster master.");
@ -132,7 +132,7 @@ int main(int argc, char** argv)
int ec;
test.maxscales->ssh_node_output(0,
"maxadmin call command mysqlmon switchover MySQL-Monitor server1 server4" , true, &ec);
sleep(10);
test.maxscales->wait_for_monitor();
master_id = get_master_server_id(test);
test.assert(master_id == 1, "Server 1 should be the cluster master.");
get_output(test);

View File

@ -88,7 +88,7 @@ int main(int argc, char** argv)
cout << "Stopping master, should auto-failover." << endl;
int master_id_old = get_master_server_id(test);
test.repl->stop_node(0);
sleep(10);
test.maxscales->wait_for_monitor();
get_output(test);
int master_id_new = get_master_server_id(test);
cout << "Master server id is " << master_id_new << endl;
@ -107,7 +107,7 @@ int main(int argc, char** argv)
}
// Restart old master. Then add some events to it.
test.repl->start_node(0, (char*)"");
sleep(3);
test.maxscales->wait_for_monitor();
test.repl->connect();
cout << "Adding more events to node 0. It should not join the cluster." << endl;
generate_traffic_and_check(test, test.repl->nodes[0], 5);
@ -118,7 +118,7 @@ int main(int argc, char** argv)
test.assert(false, "Could not start MaxScale.");
return test.global_result;
}
sleep(10);
test.maxscales->wait_for_monitor();
get_output(test);
expect(test, "server1", "Running");
@ -139,7 +139,7 @@ int main(int argc, char** argv)
MYSQL** nodes = test.repl->nodes;
mysql_query(nodes[ind], cmd);
mysql_query(nodes[ind], "START SLAVE;");
sleep(10);
test.maxscales->wait_for_monitor();
get_output(test);
expect(test, "server1", "Running");

View File

@ -28,7 +28,7 @@ int main(int argc, char** argv)
char result_tmp[bufsize];
// Advance gtid:s a bit to so gtid variables are updated.
generate_traffic_and_check(test, maxconn, 10);
sleep(1);
test.maxscales->wait_for_monitor();
test.tprintf(LINE);
print_gtids(test);
get_input();
@ -38,7 +38,7 @@ int main(int argc, char** argv)
const int old_master_id = get_master_server_id(test); // Read master id now before shutdown.
const int master_index = test.repl->master;
test.repl->stop_node(master_index);
sleep(10);
test.maxscales->wait_for_monitor();
// Recreate maxscale session
mysql_close(maxconn);
maxconn = test.maxscales->open_rwsplit_connection(0);
@ -53,7 +53,7 @@ int main(int argc, char** argv)
{
test.tprintf("Sending more inserts.");
generate_traffic_and_check(test, maxconn, 5);
sleep(1);
test.maxscales->wait_for_monitor();
if (find_field(maxconn, GTID_QUERY, GTID_FIELD, result_tmp) == 0)
{
gtid_final = result_tmp;
@ -63,11 +63,11 @@ int main(int argc, char** argv)
test.tprintf(LINE);
test.repl->start_node(master_index, (char*) "");
sleep(10);
test.maxscales->wait_for_monitor();
get_output(test);
test.repl->connect();
sleep(1);
test.maxscales->wait_for_monitor();
string gtid_old_master;
if (find_field(test.repl->nodes[master_index], GTID_QUERY, GTID_FIELD, result_tmp) == 0)
{
@ -81,7 +81,7 @@ int main(int argc, char** argv)
int ec;
test.maxscales->ssh_node_output(0, "maxadmin call command mysqlmon switchover "
"MySQL-Monitor server1 server2" , true, &ec);
sleep(10); // Wait for monitor to update status
test.maxscales->wait_for_monitor(); // Wait for monitor to update status
get_output(test);
master_id = get_master_server_id(test);
test.assert(master_id == old_master_id, "Switchover back to server1 failed.");
@ -89,7 +89,7 @@ int main(int argc, char** argv)
else
{
test.repl->start_node(master_index, (char*) "");
sleep(10);
test.maxscales->wait_for_monitor();
}
test.repl->fix_replication();

View File

@ -40,7 +40,10 @@ int main(int argc, char** argv)
const int old_master_id = get_master_server_id(test); // Read master id now before shutdown.
const int master_index = test.repl->master;
test.repl->stop_node(master_index);
sleep(10);
// Wait until failover is performed
test.maxscales->wait_for_monitor(3);
// Recreate maxscale session
mysql_close(maxconn);
maxconn = test.maxscales->open_rwsplit_connection(0);
@ -54,20 +57,16 @@ int main(int argc, char** argv)
{
cout << "Sending more inserts." << endl;
generate_traffic_and_check(test, maxconn, 5);
if (find_field(maxconn, GTID_QUERY, GTID_FIELD, result_tmp) == 0)
{
gtid_final = result_tmp;
}
print_gtids(test);
cout << "Bringing old master back online..." << endl;
test.repl->start_node(master_index, (char*) "");
sleep(10);
test.maxscales->wait_for_monitor();
test.repl->connect();
get_output(test);
test.tprintf("and manually rejoining it to cluster.");
const char REJOIN_CMD[] = "maxadmin call command mariadbmon rejoin MySQL-Monitor server1";
test.maxscales->ssh_node_output(0, REJOIN_CMD , true, &ec);
sleep(10);
test.maxscales->wait_for_monitor();
get_output(test);
string gtid_old_master;
@ -75,15 +74,20 @@ int main(int argc, char** argv)
{
gtid_old_master = result_tmp;
}
if (find_field(maxconn, GTID_QUERY, GTID_FIELD, result_tmp) == 0)
{
gtid_final = result_tmp;
}
cout << LINE << "\n";
print_gtids(test);
cout << LINE << "\n";
test.assert(gtid_final == gtid_old_master, "Old master did not successfully rejoin the cluster.");
test.assert(gtid_final == gtid_old_master, "Old master did not successfully rejoin the cluster (%s != %s).", gtid_final.c_str(), gtid_old_master.c_str());
// Switch master back to server1 so last check is faster
int ec;
test.maxscales->ssh_node_output(0, "maxadmin call command mysqlmon switchover "
"MySQL-Monitor server1 server2" , true, &ec);
sleep(10); // Wait for monitor to update status
test.maxscales->wait_for_monitor(); // Wait for monitor to update status
get_output(test);
master_id = get_master_server_id(test);
test.assert(master_id == old_master_id, "Switchover back to server1 failed.");
@ -91,7 +95,7 @@ int main(int argc, char** argv)
else
{
test.repl->start_node(master_index, (char*) "");
sleep(10);
test.maxscales->wait_for_monitor();
}
test.repl->fix_replication();

View File

@ -94,7 +94,7 @@ int main(int argc, char** argv)
string rejoin_s4 = REJOIN_CMD + " server4";
test.maxscales->ssh_node_output(0, rejoin_s3.c_str() , true, &ec);
test.maxscales->ssh_node_output(0, rejoin_s4.c_str() , true, &ec);
sleep(10);
test.maxscales->wait_for_monitor();
get_output(test);
StringSet node2_states = test.get_server_status("server3");
@ -115,11 +115,11 @@ int main(int argc, char** argv)
snprintf(cmd, sizeof(cmd), CHANGE_CMD_FMT, test.repl->IP[3], test.repl->port[3]);
mysql_query(nodes[0], cmd);
mysql_query(nodes[0], "START SLAVE;");
sleep(10);
test.maxscales->wait_for_monitor();
string rejoin_s2 = REJOIN_CMD + " server2";
test.maxscales->ssh_node_output(0, rejoin_s2.c_str() , true, &ec);
test.maxscales->ssh_node_output(0, rejoin_s3.c_str() , true, &ec);
sleep(10);
test.maxscales->wait_for_monitor();
get_output(test);
int master_id = get_master_server_id(test);
test.assert(master_id == 4, "Server 4 should be the cluster master.");
@ -132,7 +132,7 @@ int main(int argc, char** argv)
int ec;
test.maxscales->ssh_node_output(0,
"maxadmin call command mysqlmon switchover MySQL-Monitor server1 server4" , true, &ec);
sleep(10);
test.maxscales->wait_for_monitor();
master_id = get_master_server_id(test);
test.assert(master_id == 1, "Server 1 should be the cluster master.");
get_output(test);

View File

@ -122,7 +122,7 @@ void expect(TestConnections& test, const char* zServer, const char* zState1, con
void run(TestConnections& test)
{
sleep(10);
test.maxscales->wait_for_monitor();
int N = test.repl->N;
cout << "Nodes: " << N << endl;
@ -149,7 +149,7 @@ void run(TestConnections& test)
zCommand = "call command mysqlmon switchover MySQL-Monitor server2 server1";
test.maxscales->execute_maxadmin_command_print(0, (char*)zCommand);
sleep(10);
test.maxscales->wait_for_monitor();
expect(test, "server1", "Slave", "Running");
expect(test, "server2", "Master", "Running");
@ -162,7 +162,7 @@ void run(TestConnections& test)
zCommand = "call command mysqlmon switchover MySQL-Monitor server1 server2";
test.maxscales->execute_maxadmin_command_print(0, (char*)zCommand);
sleep(10);
test.maxscales->wait_for_monitor();
expect(test, "server1", "Master", "Running");
expect(test, "server2", "Slave", "Running");

View File

@ -122,7 +122,7 @@ void expect(TestConnections& test, const char* zServer, const char* zState1, con
void run(TestConnections& test)
{
sleep(10);
test.maxscales->wait_for_monitor();
int N = test.repl->N;
cout << "Nodes: " << N << endl;
@ -147,7 +147,7 @@ void run(TestConnections& test)
cout << "\nStopping slave " << N - 1 << endl;
test.repl->stop_node(N - 1);
sleep(10);
test.maxscales->wait_for_monitor();
// server4 was stopped, so we expect the state of it to be /Down/,
// and the states of the other ones not to have changed.
@ -171,7 +171,7 @@ void run(TestConnections& test)
cout << "\nStopping master." << endl;
test.repl->stop_node(0);
sleep(10);
test.maxscales->wait_for_monitor(3);
// server1 (previous master) was taken down, so its state should be /Down/.
// server2 should have been made into master, and server4 should still be down.
@ -183,7 +183,7 @@ void run(TestConnections& test)
cout << "\nBringing up slave " << N - 1 << endl;
test.repl->start_node(N - 1, (char*)"");
sleep(10);
test.maxscales->wait_for_monitor();
// server1 should still be down, server2 still master, and server3 still
// a slave. server4 was brought up, but as auto_rejoin is false, it should
@ -198,7 +198,7 @@ void run(TestConnections& test)
const char* zCommand = "call command mysqlmon switchover MySQL-Monitor server4 server2";
test.maxscales->execute_maxadmin_command_print(0, (char*)zCommand);
sleep(10);
test.maxscales->wait_for_monitor();
// The state should not change, as server4 is not good enough as master.
expect(test, "server1", "Down");

View File

@ -245,7 +245,8 @@ bool runtime_destroy_server(SERVER *server)
}
static SSL_LISTENER* create_ssl(const char *name, const char *key, const char *cert,
const char *ca, const char *version, const char *depth)
const char *ca, const char *version, const char *depth,
const char *verify)
{
SSL_LISTENER *rval = NULL;
CONFIG_CONTEXT *obj = config_context_create(name);
@ -257,7 +258,8 @@ static SSL_LISTENER* create_ssl(const char *name, const char *key, const char *c
config_add_param(obj, CN_SSL_CERT, cert) &&
config_add_param(obj, CN_SSL_CA_CERT, ca) &&
(!version || config_add_param(obj, CN_SSL_VERSION, version)) &&
(!depth || config_add_param(obj, CN_SSL_CERT_VERIFY_DEPTH, depth)))
(!depth || config_add_param(obj, CN_SSL_CERT_VERIFY_DEPTH, depth)) &&
(!verify || config_add_param(obj, CN_SSL_VERIFY_PEER_CERTIFICATE, verify)))
{
int err = 0;
SSL_LISTENER *ssl = make_ssl_structure(obj, true, &err);
@ -275,14 +277,15 @@ static SSL_LISTENER* create_ssl(const char *name, const char *key, const char *c
}
bool runtime_enable_server_ssl(SERVER *server, const char *key, const char *cert,
const char *ca, const char *version, const char *depth)
const char *ca, const char *version, const char *depth,
const char *verify)
{
bool rval = false;
if (key && cert && ca)
{
spinlock_acquire(&crt_lock);
SSL_LISTENER *ssl = create_ssl(server->name, key, cert, ca, version, depth);
SSL_LISTENER *ssl = create_ssl(server->name, key, cert, ca, version, depth, verify);
if (ssl)
{
@ -792,7 +795,8 @@ bool runtime_create_listener(SERVICE *service, const char *name, const char *add
const char *port, const char *proto, const char *auth,
const char *auth_opt, const char *ssl_key,
const char *ssl_cert, const char *ssl_ca,
const char *ssl_version, const char *ssl_depth)
const char *ssl_version, const char *ssl_depth,
const char *verify_ssl)
{
if (addr == NULL || strcasecmp(addr, CN_DEFAULT) == 0)
@ -830,7 +834,7 @@ bool runtime_create_listener(SERVICE *service, const char *name, const char *add
SSL_LISTENER *ssl = NULL;
if (ssl_key && ssl_cert && ssl_ca &&
(ssl = create_ssl(name, ssl_key, ssl_cert, ssl_ca, ssl_version, ssl_depth)) == NULL)
(ssl = create_ssl(name, ssl_key, ssl_cert, ssl_ca, ssl_version, ssl_depth, verify_ssl)) == NULL)
{
MXS_ERROR("SSL initialization for listener '%s' failed.", name);
runtime_error("SSL initialization for listener '%s' failed.", name);
@ -1267,6 +1271,7 @@ static bool process_ssl_parameters(SERVER* server, json_t* params)
if (validate_ssl_json(params))
{
char buf[20]; // Enough to hold the string form of the ssl_cert_verify_depth
char buf_verify[20]; // Enough to hold the string form of the ssl_verify_peer_certificate
const char* key = json_string_value(mxs_json_pointer(params, CN_SSL_KEY));
const char* cert = json_string_value(mxs_json_pointer(params, CN_SSL_CERT));
const char* ca = json_string_value(mxs_json_pointer(params, CN_SSL_CA_CERT));
@ -1280,7 +1285,16 @@ static bool process_ssl_parameters(SERVER* server, json_t* params)
depth = buf;
}
if (!runtime_enable_server_ssl(server, key, cert, ca, version, depth))
const char* verify = NULL;
json_t* verify_json = mxs_json_pointer(params, CN_SSL_VERIFY_PEER_CERTIFICATE);
if (verify_json)
{
snprintf(buf_verify, sizeof(buf), "%s", json_boolean_value(verify_json) ? "true" : "false");
verify = buf_verify;
}
if (!runtime_enable_server_ssl(server, key, cert, ca, version, depth, verify))
{
runtime_error("Failed to initialize SSL for server '%s'. See "
"error log for more details.", server->name);
@ -1957,11 +1971,12 @@ bool runtime_create_listener_from_json(SERVICE* service, json_t* json)
const char* ssl_ca_cert = get_string_or_null(json, MXS_JSON_PTR_PARAM_SSL_CA_CERT);
const char* ssl_version = get_string_or_null(json, MXS_JSON_PTR_PARAM_SSL_VERSION);
const char* ssl_cert_verify_depth = get_string_or_null(json, MXS_JSON_PTR_PARAM_SSL_CERT_VERIFY_DEPTH);
const char* ssl_verify_peer_certificate = get_string_or_null(json, MXS_JSON_PTR_PARAM_SSL_VERIFY_PEER_CERT);
rval = runtime_create_listener(service, id, address, port.c_str(), protocol,
authenticator, authenticator_options,
ssl_key, ssl_cert, ssl_ca_cert, ssl_version,
ssl_cert_verify_depth);
ssl_cert_verify_depth, ssl_verify_peer_certificate);
}
return rval;

View File

@ -105,10 +105,13 @@ bool runtime_alter_server(SERVER *server, const char *key, const char *value);
* @param ca Path to certificate authority
* @param version Required SSL Version
* @param depth Certificate verification depth
* @param verify Verify peer certificate
*
* @return True if SSL was successfully enabled
*/
bool runtime_enable_server_ssl(SERVER *server, const char *key, const char *cert,
const char *ca, const char *version, const char *depth);
const char *ca, const char *version, const char *depth,
const char *verify);
/**
* @brief Alter monitor parameters
@ -158,6 +161,7 @@ bool runtime_alter_maxscale(const char* name, const char* value);
* @param ssl_ca SSL CA cert, NULL for no CA cert
* @param ssl_version SSL version, NULL for default of "MAX"
* @param ssl_depth SSL cert verification depth, NULL for default
* @param verify_ssl SSL peer certificate verification, NULL for default
*
* @return True if the listener was successfully created and started
*/
@ -165,7 +169,8 @@ bool runtime_create_listener(SERVICE *service, const char *name, const char *add
const char *port, const char *proto, const char *auth,
const char *auth_opt, const char *ssl_key,
const char *ssl_cert, const char *ssl_ca,
const char *ssl_version, const char *ssl_depth);
const char *ssl_version, const char *ssl_depth,
const char *verify_ssl);
/**
* @brief Destroy a listener

View File

@ -1455,6 +1455,8 @@ static json_t* server_json_attributes(const SERVER* server)
json_object_set_new(params, CN_SSL_CA_CERT, json_string(server->server_ssl->ssl_ca_cert));
json_object_set_new(params, CN_SSL_CERT_VERIFY_DEPTH,
json_integer(server->server_ssl->ssl_cert_verify_depth));
json_object_set_new(params, CN_SSL_VERIFY_PEER_CERTIFICATE,
json_boolean(server->server_ssl->ssl_verify_peer_certificate));
json_object_set_new(params, CN_SSL_VERSION,
json_string(ssl_method_type_to_string(server->server_ssl->ssl_method_type)));
}

View File

@ -64,7 +64,7 @@
#include "../../../core/internal/poll.h"
#include "../../../core/internal/session.h"
#define MAXARGS 12
#define MAXARGS 14
#define ARG_TYPE_NONE 0
#define ARG_TYPE_ADDRESS 1
@ -1168,11 +1168,11 @@ static void createServer(DCB *dcb, char *name, char *address, char *port,
static void createListener(DCB *dcb, SERVICE *service, char *name, char *address,
char *port, char *protocol, char *authenticator,
char *authenticator_options, char *key, char *cert,
char *ca, char *version, char *depth)
char *ca, char *version, char *depth, char *verify)
{
if (runtime_create_listener(service, name, address, port, protocol,
authenticator, authenticator_options,
key, cert, ca, version, depth))
key, cert, ca, version, depth, verify))
{
dcb_printf(dcb, "Listener '%s' created\n", name);
}
@ -1380,6 +1380,7 @@ static void alterServer(DCB *dcb, SERVER *server, char *v1, char *v2, char *v3,
char *ssl_ca = NULL;
char *ssl_version = NULL;
char *ssl_depth = NULL;
char *ssl_verify = NULL;
bool enable = false;
for (int i = 0; i < items && values[i]; i++)
@ -1413,6 +1414,10 @@ static void alterServer(DCB *dcb, SERVER *server, char *v1, char *v2, char *v3,
{
ssl_depth = value;
}
else if (strcmp("ssl_verify_peer_certificate", key) == 0)
{
ssl_verify = value;
}
else
{
enable = strcmp("ssl", key) == 0 && strcmp(value, "required") == 0;
@ -1436,7 +1441,7 @@ static void alterServer(DCB *dcb, SERVER *server, char *v1, char *v2, char *v3,
{
/** We have SSL parameters, try to process them */
if (!runtime_enable_server_ssl(server, ssl_key, ssl_cert, ssl_ca,
ssl_version, ssl_depth))
ssl_version, ssl_depth, ssl_verify))
{
dcb_printf(dcb, "Enabling SSL for server '%s' failed, see log "
"for more details.\n", server->name);
@ -1538,7 +1543,7 @@ static void alterMaxScale(DCB *dcb, char *v1, char *v2, char *v3,
struct subcommand alteroptions[] =
{
{
"server", 2, 12, (FN)alterServer,
"server", 2, 14, (FN)alterServer,
"Alter server parameters",
"Usage: alter server NAME KEY=VALUE ...\n"
"\n"
@ -1548,18 +1553,19 @@ struct subcommand alteroptions[] =
"\n"
"This will alter an existing parameter of a server. The accepted values for KEY are:\n"
"\n"
"address Server address\n"
"port Server port\n"
"monitoruser Monitor user for this server\n"
"monitorpw Monitor password for this server\n"
"ssl Enable SSL, value must be 'required'\n"
"ssl_key Path to SSL private key\n"
"ssl_cert Path to SSL certificate\n"
"ssl_ca_cert Path to SSL CA certificate\n"
"ssl_version SSL version\n"
"ssl_cert_verify_depth Certificate verification depth\n"
"persistpoolmax Persisted connection pool size\n"
"persistmaxtime Persisted connection maximum idle time\n"
"address Server address\n"
"port Server port\n"
"monitoruser Monitor user for this server\n"
"monitorpw Monitor password for this server\n"
"ssl Enable SSL, value must be 'required'\n"
"ssl_key Path to SSL private key\n"
"ssl_cert Path to SSL certificate\n"
"ssl_ca_cert Path to SSL CA certificate\n"
"ssl_version SSL version\n"
"ssl_cert_verify_depth Certificate verification depth\n"
"ssl_verify_peer_certificate Peer certificate verification\n"
"persistpoolmax Persisted connection pool size\n"
"persistmaxtime Persisted connection maximum idle time\n"
"\n"
"To configure SSL for a newly created server, the 'ssl', 'ssl_cert',\n"
"'ssl_key' and 'ssl_ca_cert' parameters must be given at the same time.\n"

View File

@ -353,6 +353,7 @@ static void log_unexpected_response(SRWBackend& backend, GWBUF* buffer, GWBUF* c
"server '%s' when no response was expected. Command: 0x%02hhx "
"Query: %s", mxs_mysql_get_command(buffer), backend->name(),
backend->current_command(), sql.c_str());
session_dump_statements(backend->dcb()->session);
ss_dassert(false);
}
}