From ba821d0aff35254c18ae27d844d71797e0dcd2eb Mon Sep 17 00:00:00 2001 From: Esa Korhonen Date: Mon, 12 Feb 2018 14:17:00 +0200 Subject: [PATCH 01/24] Add mention of external master to 2.2.2 release notes --- .../Release-Notes/MaxScale-2.2.2-Release-Notes.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md index 620ba9012..fab60e518 100644 --- a/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md @@ -26,6 +26,13 @@ It is now possible to specify what local address MaxScale should use when connecting to servers. Please refer to the documentation for [details](../Getting-Started/Configuration-Guide.md#local_address). +### External master support for failover/switchover + +Failover/switchover now tries to preserve replication from an external master +server. Check +[MariaDB Monitor documentation](../Monitors/MariaDB-Monitor.md#external-master-support) +for more information. + ## Bug fixes [Here is a list of bugs fixed in MaxScale 2.2.2.](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.2.2) From f7857518f350972fc834a46bf87884dff2a635d0 Mon Sep 17 00:00:00 2001 From: Timofey Turenko Date: Mon, 12 Feb 2018 15:49:07 +0200 Subject: [PATCH 02/24] Mxs 1140 keepalived (#166) add keepalived test --- maxscale-system-test/CMakeLists.txt | 3 + .../cnf/maxscale.cnf.template.keepalived.000 | 93 +++++++++++ .../cnf/maxscale.cnf.template.keepalived.001 | 93 +++++++++++ maxscale-system-test/keepalived.cpp | 146 ++++++++++++++++++ .../keepalived_cnf/is_maxscale_running.sh | 24 +++ maxscale-system-test/mdbci/set_env.sh | 7 +- maxscale-system-test/nodes.cpp | 35 ++++- maxscale-system-test/nodes.h | 10 ++ maxscale-system-test/testconnections.cpp | 27 +++- maxscale-system-test/testconnections.h | 7 +- 10 files changed, 436 insertions(+), 9 deletions(-) create mode 100755 maxscale-system-test/cnf/maxscale.cnf.template.keepalived.000 create mode 100755 maxscale-system-test/cnf/maxscale.cnf.template.keepalived.001 create mode 100644 maxscale-system-test/keepalived.cpp create mode 100755 maxscale-system-test/keepalived_cnf/is_maxscale_running.sh diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index 748ebe651..5c481a7ce 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -822,6 +822,9 @@ add_test_executable(setup_binlog_gtid.cpp setup_binlog_gtid setup_binlog_gtid LA # TODO: make it working with zypper and apt, move part of KDC setup to MDBCI add_test_executable(kerberos_setup.cpp kerberos_setup kerberos LABELS HEAVY gssapi REPL_BACKEND) +# Configures 'keepalived' on two Maxscale machines and tried failover +add_test_executable(keepalived.cpp keepalived keepalived LABELS REPL_BACKEND TWO_MAXSCALES) + # enable after fixing MXS-419 # add_test_executable(mxs419_lots_of_connections.cpp mxs419_lots_of_connections replication LABELS REPL_BACKEND) diff --git a/maxscale-system-test/cnf/maxscale.cnf.template.keepalived.000 b/maxscale-system-test/cnf/maxscale.cnf.template.keepalived.000 new file mode 100755 index 000000000..7810d3583 --- /dev/null +++ b/maxscale-system-test/cnf/maxscale.cnf.template.keepalived.000 @@ -0,0 +1,93 @@ +[maxscale] +threads=###threads### + +[MySQL Monitor] +type=monitor +module=mysqlmon +###repl51### +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql +monitor_interval=1000 +detect_stale_master=false +detect_standalone_master=false + +[RW Split Router] +type=service +router=readwritesplit +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql +router_options=slave_selection_criteria=LEAST_GLOBAL_CONNECTIONS +max_slave_connections=1 +version_string=10.2-server1 + +[Read Connection Router Slave] +type=service +router=readconnroute +router_options=slave +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql +version_string=10.2-server1 + +[Read Connection Router Master] +type=service +router=readconnroute +router_options=master +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql +version_string=10.2-server1 + +[RW Split Listener] +type=listener +service=RW Split Router +protocol=MySQLClient +port=4006 + +[Read Connection Listener Slave] +type=listener +service=Read Connection Router Slave +protocol=MySQLClient +port=4009 + +[Read Connection Listener Master] +type=listener +service=Read Connection Router Master +protocol=MySQLClient +port=4008 + +[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 + +[server3] +type=server +address=###node_server_IP_3### +port=###node_server_port_3### +protocol=MySQLBackend + +[server4] +type=server +address=###node_server_IP_4### +port=###node_server_port_4### +protocol=MySQLBackend diff --git a/maxscale-system-test/cnf/maxscale.cnf.template.keepalived.001 b/maxscale-system-test/cnf/maxscale.cnf.template.keepalived.001 new file mode 100755 index 000000000..c16a40c49 --- /dev/null +++ b/maxscale-system-test/cnf/maxscale.cnf.template.keepalived.001 @@ -0,0 +1,93 @@ +[maxscale] +threads=###threads### + +[MySQL Monitor] +type=monitor +module=mysqlmon +###repl51### +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql +monitor_interval=1000 +detect_stale_master=false +detect_standalone_master=false + +[RW Split Router] +type=service +router=readwritesplit +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql +router_options=slave_selection_criteria=LEAST_GLOBAL_CONNECTIONS +max_slave_connections=1 +version_string=10.2-server2 + +[Read Connection Router Slave] +type=service +router=readconnroute +router_options=slave +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql +version_string=10.2-server2 + +[Read Connection Router Master] +type=service +router=readconnroute +router_options=master +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql +version_string=10.2-server2 + +[RW Split Listener] +type=listener +service=RW Split Router +protocol=MySQLClient +port=4006 + +[Read Connection Listener Slave] +type=listener +service=Read Connection Router Slave +protocol=MySQLClient +port=4009 + +[Read Connection Listener Master] +type=listener +service=Read Connection Router Master +protocol=MySQLClient +port=4008 + +[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 + +[server3] +type=server +address=###node_server_IP_3### +port=###node_server_port_3### +protocol=MySQLBackend + +[server4] +type=server +address=###node_server_IP_4### +port=###node_server_port_4### +protocol=MySQLBackend diff --git a/maxscale-system-test/keepalived.cpp b/maxscale-system-test/keepalived.cpp new file mode 100644 index 000000000..650a28039 --- /dev/null +++ b/maxscale-system-test/keepalived.cpp @@ -0,0 +1,146 @@ +/** + * @file keepalived.cpp keepalived Test of two Maxscale + keepalived failover + * + * - 'version_string' configured to be different for every Maxscale + * - configure keepalived for two nodes (uses xxx.xxx.xxx.253 as a virtual IP + * where xxx.xxx.xxx. - first 3 numbers from client IP) + * - suspend Maxscale 1 + * - wait and check version_string from Maxscale on virtual IP, expect 10.2-server2 + * - resume Maxscale 1, suspend Maxscale 2 + * - wait and check version_string from Maxscale on virtual IP, expect 10.2-server1 + * - resume Maxscale 2 + * TODO: replace 'yum' call with executing Chef recipe + */ + + +#include +#include "testconnections.h" + +#define FAILOVER_WAIT_TIME 5 + +char virtual_ip[16]; +char * print_version_string(TestConnections * Test) +{ + MYSQL * keepalived_conn = open_conn(Test->maxscales->rwsplit_port[0], virtual_ip, Test->maxscales->user_name, Test->maxscales->password, Test->ssl); + const char * version_string; + mariadb_get_info(keepalived_conn, MARIADB_CONNECTION_SERVER_VERSION, (void *)&version_string); + Test->tprintf("%s\n", version_string); + mysql_close(keepalived_conn); + return((char*) version_string); +} + +int main(int argc, char *argv[]) +{ + int i; + char * version; + + TestConnections * Test = new TestConnections(argc, argv); + Test->set_timeout(10); + + Test->tprintf("Maxscale_N %d\n", Test->maxscales->N); + if (Test->maxscales->N < 2) + { + Test->tprintf("At least 2 Maxscales are needed for this test. Exiting\n"); + exit(0); + } + + + Test->check_maxscale_alive(0); + Test->check_maxscale_alive(1); + + // Get test client IP, replace last number in it with 253 and use it as Virtual IP + char client_ip[24]; + char * last_dot; + Test->get_client_ip(0, client_ip); + last_dot = client_ip; + Test->tprintf("My IP is %s\n", client_ip); + for (i = 0; i < 3; i++) + { + last_dot = strstr(last_dot, "."); + last_dot = &last_dot[1]; + } + last_dot[0] = '\0'; + Test->tprintf("First part of IP is %s\n", client_ip); + + sprintf(virtual_ip, "%s253", client_ip); + + + for (i = 0; i < Test->maxscales->N; i++) + { + std::string src = std::string(test_dir) + "/keepalived_cnf/" + std::to_string(i + 1) + ".conf"; + std::string cp_cmd = "cp " + std::string(Test->maxscales->access_homedir[i]) + std::to_string(i + 1) + ".conf " + + " /etc/keepalived/keepalived.conf"; + Test->tprintf("%s\n", src.c_str()); + Test->tprintf("%s\n", cp_cmd.c_str()); + Test->maxscales->ssh_node(i, "yum install -y keepalived", true); + Test->maxscales->copy_to_node(i, src.c_str(), Test->maxscales->access_homedir[i]); + Test->maxscales->ssh_node(i, cp_cmd.c_str(), true); + Test->maxscales->ssh_node_f(i, true, "sed -i \"s/###virtual_ip###/%s/\" /etc/keepalived/keepalived.conf", virtual_ip); + std::string script_src = std::string(test_dir) + "/keepalived_cnf/is_maxscale_running.sh"; + std::string script_cp_cmd = "cp " + std::string(Test->maxscales->access_homedir[i]) + "is_maxscale_running.sh /usr/bin/"; + Test->maxscales->copy_to_node(i, script_src.c_str(), Test->maxscales->access_homedir[i]); + Test->maxscales->ssh_node(i, script_cp_cmd.c_str(), true); + Test->maxscales->ssh_node(i, "sudo service keepalived restart", true); + } + + print_version_string(Test); + + Test->tprintf("Suspend Maxscale 000 machine and waiting\n"); + system(Test->maxscales->stop_vm_command[0]); + sleep(FAILOVER_WAIT_TIME); + + version = print_version_string(Test); + if (strcmp(version, "10.2-server2") != 0) + { + Test->add_result(false, "Failover did not happen"); + } + + + Test->tprintf("Resume Maxscale 000 machine and waiting\n"); + system(Test->maxscales->start_vm_command[0]); + sleep(FAILOVER_WAIT_TIME); + print_version_string(Test); + + Test->tprintf("Suspend Maxscale 001 machine and waiting\n"); + system(Test->maxscales->stop_vm_command[1]); + sleep(FAILOVER_WAIT_TIME); + + version = print_version_string(Test); + if (strcmp(version, "10.2-server1") != 0) + { + Test->add_result(false, "Failover did not happen"); + } + + print_version_string(Test); + Test->tprintf("Resume Maxscale 001 machine and waiting\n"); + system(Test->maxscales->start_vm_command[1]); + sleep(FAILOVER_WAIT_TIME); + print_version_string(Test); + + Test->tprintf("Stop Maxscale on 000 machine\n"); + Test->stop_maxscale(0); + sleep(FAILOVER_WAIT_TIME); + version = print_version_string(Test); + if (strcmp(version, "10.2-server2") != 0) + { + Test->add_result(false, "Failover did not happen"); + } + + Test->tprintf("Start back Maxscale on 000 machine\n"); + Test->start_maxscale(0); + sleep(FAILOVER_WAIT_TIME); + + Test->tprintf("Stop Maxscale on 001 machine\n"); + Test->stop_maxscale(1); + sleep(FAILOVER_WAIT_TIME); + version = print_version_string(Test); + if (strcmp(version, "10.2-server1") != 0) + { + Test->add_result(false, "Failover did not happen"); + } + + int rval = Test->global_result; + delete Test; + return rval; +} + diff --git a/maxscale-system-test/keepalived_cnf/is_maxscale_running.sh b/maxscale-system-test/keepalived_cnf/is_maxscale_running.sh new file mode 100755 index 000000000..e0a894c89 --- /dev/null +++ b/maxscale-system-test/keepalived_cnf/is_maxscale_running.sh @@ -0,0 +1,24 @@ +#!/bin/bash +fileName="maxadmin_output.txt" +rm $fileName +timeout 2s maxadmin list servers > $fileName +to_result=$? +if [ $to_result -ge 1 ] +then + echo Timed out or error, timeout returned $to_result + exit 3 +else + echo MaxAdmin success, rval is $to_result + echo Checking maxadmin output sanity + grep1=$(grep server1 $fileName) + grep2=$(grep server2 $fileName) + + if [ "$grep1" ] && [ "$grep2" ] + then + echo All is fine + exit 0 + else + echo Something is wrong + exit 3 + fi +fi diff --git a/maxscale-system-test/mdbci/set_env.sh b/maxscale-system-test/mdbci/set_env.sh index 86459e8d1..8461744c3 100644 --- a/maxscale-system-test/mdbci/set_env.sh +++ b/maxscale-system-test/mdbci/set_env.sh @@ -20,6 +20,7 @@ export maxscale_log_dir="/var/log/maxscale/" # Number of nodes export galera_N=`cat "$MDBCI_VM_PATH/$config_name"_network_config | grep galera | grep network | wc -l` export node_N=`cat "$MDBCI_VM_PATH/$config_name"_network_config | grep node | grep network | wc -l` +export maxscale_N=`cat "$MDBCI_VM_PATH/$config_name"_network_config | grep maxscale | grep network | wc -l` sed "s/^/export /g" "$MDBCI_VM_PATH/$config_name"_network_config > "$curr_dir"/"$config_name"_network_config_export source "$curr_dir"/"$config_name"_network_config_export @@ -40,7 +41,7 @@ export maxscale_password="skysql" export maxadmin_password="mariadb" -for prefix in "node" "galera" +for prefix in "node" "galera" "maxscale" do N_var="$prefix"_N Nx=${!N_var} @@ -77,8 +78,8 @@ do eval 'export $stop_cmd_var="$mysql_exe stop "' fi - eval 'export "$prefix"_"$num"_start_vm_command="cd $mdbci_dir/$config_name;vagrant up node_$num --provider=$provider; cd $curr_dir"' - eval 'export "$prefix"_"$num"_kill_vm_command="cd $mdbci_dir/$config_name;vagrant halt node_$num --provider=$provider; cd $curr_dir"' + eval 'export "$prefix"_"$num"_start_vm_command="cd ${MDBCI_VM_PATH}/$config_name;vagrant resume ${prefix}_$num ; cd $curr_dir"' + eval 'export "$prefix"_"$num"_stop_vm_command="cd ${MDBCI_VM_PATH}/$config_name;vagrant suspend ${prefix}_$num ; cd $curr_dir"' done done diff --git a/maxscale-system-test/nodes.cpp b/maxscale-system-test/nodes.cpp index c85b19dab..125b53f16 100644 --- a/maxscale-system-test/nodes.cpp +++ b/maxscale-system-test/nodes.cpp @@ -197,7 +197,6 @@ int Nodes::ssh_node_f(int node, bool sudo, const char* format, ...) va_start(valist, format); vsnprintf(sys, message_len + 1, format, valist); va_end(valist); - int result = ssh_node(node, sys, sudo); free(sys); return (result); @@ -428,6 +427,40 @@ int Nodes::read_basic_env() { sprintf(hostname[i], "%s", IP[i]); } + + sprintf(env_name, "%s_%03d_start_vm_command", prefix, i); + env = getenv(env_name); + if (env == NULL) + { + sprintf(env_name, "%s_start_vm_command", prefix); + env = getenv(env_name); + } + + if (env != NULL) + { + sprintf(start_vm_command[i], "%s", env); + } + else + { + sprintf(start_vm_command[i], "exit 0"); + } + + sprintf(env_name, "%s_%03d_stop_vm_command", prefix, i); + env = getenv(env_name); + if (env == NULL) + { + sprintf(env_name, "%s_stop_vm_command", prefix); + env = getenv(env_name); + } + + if (env != NULL) + { + sprintf(stop_vm_command[i], "%s", env); + } + else + { + sprintf(stop_vm_command[i], "exit 0"); + } } } diff --git a/maxscale-system-test/nodes.h b/maxscale-system-test/nodes.h index b961e226f..376a03ae9 100644 --- a/maxscale-system-test/nodes.h +++ b/maxscale-system-test/nodes.h @@ -64,6 +64,16 @@ public: char hostname[256][1024]; + /** + * @brief stop_vm_command Command to suspend VM + */ + char stop_vm_command[256][1024]; + /** + + * @brief start_vm_command Command to resume VM + */ + char start_vm_command[256][1024]; + /** * @brief User name to access backend nodes */ diff --git a/maxscale-system-test/testconnections.cpp b/maxscale-system-test/testconnections.cpp index 9828afa7b..5c44be7df 100644 --- a/maxscale-system-test/testconnections.cpp +++ b/maxscale-system-test/testconnections.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "mariadb_func.h" @@ -281,7 +282,7 @@ TestConnections::TestConnections(int argc, char *argv[]): if (maxscale_init) { - init_maxscale(0); + init_maxscales(); } if (backend_ssl) @@ -529,11 +530,23 @@ const char * get_template_name(char * test_name) void TestConnections::process_template(int m, const char *template_name, const char *dest) { + struct stat stb; char str[4096]; char template_file[1024]; + char extended_template_file[1024]; + sprintf(template_file, "%s/cnf/maxscale.cnf.template.%s", test_dir, template_name); + sprintf(extended_template_file, "%s.%03d", template_file, m); + + if (stat((char*)extended_template_file, &stb) == 0) + { + strcpy(template_file, extended_template_file); + } + tprintf("Template file is %s\n", template_file); + sprintf(str, "cp %s maxscale.cnf", template_file); + tprintf("Executing '%s' command\n", str); if (system(str) != 0) { tprintf("Error copying maxscale.cnf template\n"); @@ -595,12 +608,19 @@ void TestConnections::process_template(int m, const char *template_name, const c maxscales->copy_to_node_legacy((char *) "maxscale.cnf", (char *) dest, m); } +int TestConnections::init_maxscales() +{ + for (int i = 0; i < maxscales->N; i++) + { + init_maxscale(i); + } +} + int TestConnections::init_maxscale(int m) { const char * template_name = get_template_name(test_name); - tprintf("Template is %s\n", template_name); - process_template(m, template_name, maxscales->access_homedir[m]); + process_template(m, template_name, maxscales->access_homedir[m]); maxscales->ssh_node_f(m, true, "cp maxscale.cnf %s;rm -rf %s/certs;mkdir -m a+wrx %s/certs;", maxscales->maxscale_cnf[m], @@ -614,7 +634,6 @@ int TestConnections::init_maxscale(int m) sprintf(str, "cp %s/ssl-cert/* .", test_dir); system(str); - maxscales->ssh_node_f(m, true, "chown maxscale:maxscale -R %s/certs;" "chmod 664 %s/certs/*.pem;" diff --git a/maxscale-system-test/testconnections.h b/maxscale-system-test/testconnections.h index 18aa92413..824732aa8 100644 --- a/maxscale-system-test/testconnections.h +++ b/maxscale-system-test/testconnections.h @@ -263,11 +263,16 @@ public: /** * @brief InitMaxscale Copies MaxSclae.cnf and start MaxScale + * @param m Number of Maxscale node * @return 0 if case of success */ int init_maxscale(int m = 0); - + /** + * @brief InitMaxscale Copies MaxSclae.cnf and start MaxScale on all Maxscale nodes + * @return 0 if case of success + */ + int init_maxscales(); /** * @brief start_binlog configure first node as Master, Second as slave connected to Master and others as slave connected to MaxScale binlog router From 062da5c956d4b1abc7c24a070d308f9dcab6454b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 12 Feb 2018 15:21:04 +0200 Subject: [PATCH 03/24] Remove master count assertion in mysqlmon_failover_stress The assertion can be triggered if failover has failed. This is expected behavior if the master has executed events that the slaves haven't received. --- maxscale-system-test/mysqlmon_failover_stress.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/maxscale-system-test/mysqlmon_failover_stress.cpp b/maxscale-system-test/mysqlmon_failover_stress.cpp index e6452583b..4d698cbed 100755 --- a/maxscale-system-test/mysqlmon_failover_stress.cpp +++ b/maxscale-system-test/mysqlmon_failover_stress.cpp @@ -488,8 +488,6 @@ void check_server_statuses(TestConnections& test) masters += check_server_status(test, 2); masters += check_server_status(test, 3); masters += check_server_status(test, 4); - - test.assert(masters == 1, "Unpexpected number of masters: %d", masters); } void run(TestConnections& test) From b468f2f6390657c7586a770509f13eb5f796ffe7 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 12 Feb 2018 16:24:38 +0200 Subject: [PATCH 04/24] Check for failover turned off if failover stress tests fails If there are no masters at the end of the test, it suggests the auto failover has been turned off. Check that. --- maxscale-system-test/mysqlmon_failover_stress.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/maxscale-system-test/mysqlmon_failover_stress.cpp b/maxscale-system-test/mysqlmon_failover_stress.cpp index 4d698cbed..6ccb6d8a2 100755 --- a/maxscale-system-test/mysqlmon_failover_stress.cpp +++ b/maxscale-system-test/mysqlmon_failover_stress.cpp @@ -488,6 +488,16 @@ void check_server_statuses(TestConnections& test) masters += check_server_status(test, 2); masters += check_server_status(test, 3); masters += check_server_status(test, 4); + + if (masters == 0) + { + test.tprintf("No master, checking that autofail has been turned off."); + test.log_includes(0, "disabling automatic failover"); + } + else if (masters != 1) + { + test.assert(!true, "Unexpected number of masters: %d", masters); + } } void run(TestConnections& test) From 35402557d747c6596225e6a8a21c20d5ffd126da Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 13 Feb 2018 08:43:46 +0200 Subject: [PATCH 05/24] In the documentation, state that hintrouter is beta --- Documentation/Routers/HintRouter.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/Routers/HintRouter.md b/Documentation/Routers/HintRouter.md index dbb7c9ef5..3413e8b98 100644 --- a/Documentation/Routers/HintRouter.md +++ b/Documentation/Routers/HintRouter.md @@ -1,5 +1,7 @@ # HintRouter +HintRouter was introduced in 2.2 and is still beta. + ## Overview The **HintRouter** module is a simple router intended to operate in conjunction From 049606de150064c150f23327f9204bc2fcb87bfb Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 13 Feb 2018 11:13:55 +0200 Subject: [PATCH 06/24] Remove document on HA with Corosync/Pacemaker --- .../MaxScale-HA-with-Corosync-Pacemaker.md | 528 ------------------ 1 file changed, 528 deletions(-) delete mode 100644 Documentation/Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md diff --git a/Documentation/Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md b/Documentation/Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md deleted file mode 100644 index c06af5720..000000000 --- a/Documentation/Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md +++ /dev/null @@ -1,528 +0,0 @@ -# How to make MariaDB MaxScale High Available - -The document shows an example of a Pacemaker / Corosync setup with MariaDB MaxScale based on Linux Centos 6.5, using three virtual servers and unicast heartbeat mode with the following minimum requirements: - -- MariaDB MaxScale process is started/stopped and monitored via /etc/init.d/maxscale script that is LSB compatible in order to be managed by Pacemaker resource manager - -- A Virtual IP is set providing the access to the MariaDB MaxScale process that could be set to one of the cluster nodes - -- Pacemaker/Corosync and crmsh command line tool basic knowledge - -Please note the solution is a quick setup example that may not be suited for all production environments. - -## Clustering Software installation - -On each node in the cluster do the following steps. - -### Add clustering repos to yum - -``` -# vi /etc/yum.repos.d/ha-clustering.repo -``` - -Add the following to the file. - -``` -[haclustering] -name=HA Clustering -baseurl=http://download.opensuse.org/repositories/network:/ha-clustering:/Stable/CentOS_CentOS-6/ -enabled=1 -gpgcheck=0 -``` - -### Install the software - -``` -# yum install pacemaker corosync crmsh -``` - -Package versions used - -``` -Package pacemaker-1.1.10-14.el6_5.3.x86_64 -Package corosync-1.4.5-2.4.x86_64 -Package crmsh-2.0+git46-1.1.x86_64 -``` - -### Assign hostname on each node - -In this example the three names used for the nodes are: node1,node,node3 - -``` -[root@server1 ~]# hostname node1 -... -[root@server2 ~]# hostname node2 -... -[root@server3 ~]# hostname node3 -``` - -For each node, add all the server names into `/etc/hosts`. - -``` -[root@node3 ~]# vi /etc/hosts -10.74.14.39 node1 -10.228.103.72 node2 -10.35.15.26 node3 current-node -... -[root@node1 ~]# vi /etc/hosts -10.74.14.39 node1 current-node -10.228.103.72 node2 -10.35.15.26 node3 -``` - -**Note**: add _current-node_ as an alias for the current node in each of the /etc/hosts files. - -### Prepare authkey for optional cryptographic use - -On one of the nodes, say node2 run the corosync-keygen utility and follow - -``` -[root@node2 ~]# corosync-keygen - -Corosync Cluster Engine Authentication key generator. Gathering 1024 bits for key from /dev/random. Press keys on your keyboard to generate entropy. - -After completion the key will be found in /etc/corosync/authkey. -``` - -### Prepare the corosync configuration file - -Using node2 as an example: - -``` -[root@node2 ~]# vi /etc/corosync/corosync.conf -``` - -Add the following to the file: - -``` -# Please read the corosync.conf.5 manual page - -compatibility: whitetank - -totem { - version: 2 - secauth: off - interface { - member { - memberaddr: node1 - } - member { - memberaddr: node2 - } - member { - memberaddr: node3 - } - ringnumber: 0 - bindnetaddr: current-node - mcastport: 5405 - ttl: 1 - } - transport: udpu -} - -logging { - fileline: off - to_logfile: yes - to_syslog: yes - logfile: /var/log/cluster/corosync.log - debug: off - timestamp: on - logger_subsys { - subsys: AMF - debug: off - } -} - -# this will start Pacemaker processes - -service { -ver: 0 -name: pacemaker -} -``` - -**Note**: in this example: - -- unicast UDP is used - -- bindnetaddr for corosync process is current-node, that has the right value on each node due to the alias added in /etc/hosts above - -- Pacemaker processes are started by the corosync daemon, so there is no need to launch it via /etc/init.d/pacemaker start - -### Copy configuration files and auth key on each of the other nodes - -``` -[root@node2 ~]# scp /etc/corosync/* root@node1:/etc/corosync/ -... -[root@node2 ~]# scp /etc/corosync/* root@nodeN:/etc/corosync/ -``` - -Corosync needs port 5405 to be opened. Configure any firewall or iptables accordingly. For a quick start just disable iptables on each nodes: - -``` -[root@node2 ~]# service iptables stop -... -[root@nodeN ~]# service iptables stop -``` - -### Start Corosyn on each node - -``` -[root@node2 ~] #/etc/init.d/corosync start -... -[root@nodeN ~] #/etc/init.d/corosync start -``` - -Check that the corosync daemon is successfully bound to port 5405. - -``` -[root@node2 ~] #netstat -na | grep 5405 -udp 0 0 10.228.103.72:5405 0.0.0.0:* -``` - -Check if other nodes are reachable with nc utility and option UDP (-u). - -``` -[root@node2 ~] #echo "check ..." | nc -u node1 5405 -[root@node2 ~] #echo "check ..." | nc -u node3 5405 -... -[root@node1 ~] #echo "check ..." | nc -u node2 5405 -[root@node1 ~] #echo "check ..." | nc -u node3 5405 -``` - -If the following message is displayed, there is an issue with communication between the nodes. - -``` -nc: Write error: Connection refused -``` - -This is most likely to be an issue with the firewall configuration on your nodes. Check and resolve any issues with your firewall configuration. - -### Check the cluster status from any node - -``` -[root@node3 ~]# crm status -``` - -The command should produce the following. - -``` -[root@node3 ~]# crm status -Last updated: Mon Jun 30 12:47:53 2014 -Last change: Mon Jun 30 12:47:39 2014 via crmd on node2 -Stack: classic openais (with plugin) -Current DC: node2 - partition with quorum -Version: 1.1.10-14.el6_5.3-368c726 - -3 Nodes configured, 3 expected votes -0 Resources configured - -Online: [ node1 node2 node3 ] -``` - -For the basic setup disable the following properties: - -- stonith - -- quorum policy - -``` -[root@node3 ~]# crm configure property 'stonith-enabled'='false' -[root@node3 ~]# crm configure property 'no-quorum-policy'='ignore' -``` - -For additional information see: - -[http://www.clusterlabs.org/doc/crm_fencing.html](http://www.clusterlabs.org/doc/crm_fencing.html) - -[http://clusterlabs.org/doc/](http://clusterlabs.org/doc/) - -The configuration is automatically updated on every node. - -Check it from another node, say node1: - -``` -[root@node1 ~]# crm configure show -node node1 -node node2 -node node3 -property cib-bootstrap-options: \ - dc-version=1.1.10-14.el6_5.3-368c726 \ - cluster-infrastructure="classic openais (with plugin)" \ - expected-quorum-votes=3 \ - stonith-enabled=false \ - no-quorum-policy=ignore \ - placement-strategy=balanced \ - default-resource-stickiness=infinity -``` - -The Corosync / Pacemaker cluster is ready to be configured to manage resources. - -## MariaDB MaxScale init script - -The MariaDB MaxScale init script in `/etc/init.d./maxscale` allows to start, stop, restart and monitor the MariaDB MaxScale process running on the system. - -``` -[root@node1 ~]# /etc/init.d/maxscale -Usage: /etc/init.d/maxscale {start|stop|status|restart|condrestart|reload} -``` - -- Start - -``` -[root@node1 ~]# /etc/init.d/maxscale start -Starting MaxScale: maxscale (pid 25892) is running... [ OK ] -``` - -- Start again - -``` -[root@node1 ~]# /etc/init.d/maxscale start -Starting MaxScale: found maxscale (pid 25892) is running.[ OK ] -``` - -- Stop - -``` -[root@node1 ~]# /etc/init.d/maxscale stop -Stopping MaxScale: [ OK ] -``` - -- Stop again - -``` -[root@node1 ~]# /etc/init.d/maxscale stop -Stopping MaxScale: [FAILED] -``` - -- Status (MaxScale not running) - -``` -[root@node1 ~]# /etc/init.d/maxscale status -MaxScale is stopped [FAILED] -``` - -The script exit code for "status" is 3 - -- Status (MaxScale is running) - -``` -[root@node1 ~]# /etc/init.d/maxscale status -Checking MaxScale status: MaxScale (pid 25953) is running.[ OK ] -``` - -The script exit code for "status" is 0 - -Read the following for additional information about LSB init scripts: - -[http://www.linux-ha.org/wiki/LSB_Resource_Agents](http://www.linux-ha.org/wiki/LSB_Resource_Agents) - -After checking that the init scripts for MariaDB MaxScale work, it is possible to configure MariaDB MaxScale for HA via Pacemaker. - -# Configure MariaDB MaxScale for HA with Pacemaker - -``` -[root@node2 ~]# crm configure primitive MaxScale lsb:maxscale \ -op monitor interval="10s” timeout=”15s” \ -op start interval="0” timeout=”15s” \ -op stop interval="0” timeout=”30s” -``` - -MaxScale resource will be started. - -``` -[root@node2 ~]# crm status -Last updated: Mon Jun 30 13:15:34 2014 -Last change: Mon Jun 30 13:15:28 2014 via cibadmin on node2 -Stack: classic openais (with plugin) -Current DC: node2 - partition with quorum -Version: 1.1.10-14.el6_5.3-368c726 - -3 Nodes configured, 3 expected votes -1 Resources configured - -Online: [ node1 node2 node3 ] - - MaxScale (lsb:maxscale): Started node1 -``` - -## Basic use cases - -### Resource restarted after a failure - -In the example MariaDB MaxScale PID is 26114, kill the process immediately. - -``` -[root@node2 ~]# kill -9 26114 -... -[root@node2 ~]# crm status -Last updated: Mon Jun 30 13:16:11 2014 -Last change: Mon Jun 30 13:15:28 2014 via cibadmin on node2 -Stack: classic openais (with plugin) -Current DC: node2 - partition with quorum -Version: 1.1.10-14.el6_5.3-368c726 - -3 Nodes configured, 3 expected votes -1 Resources configured - -Online: [ node1 node2 node3 ] - -Failed actions: - - MaxScale_monitor_15000 on node1 'not running' (7): call=19, status=complete, last-rc-change='Mon Jun 30 13:16:14 2014', queued=0ms, exec=0ms -``` - -**Note**: the _MaxScale_monitor_ failed action - -After a few seconds it will be started again. - -``` -[root@node2 ~]# crm status -Last updated: Mon Jun 30 13:21:12 2014 -Last change: Mon Jun 30 13:15:28 2014 via cibadmin on node1 -Stack: classic openais (with plugin) -Current DC: node2 - partition with quorum -Version: 1.1.10-14.el6_5.3-368c726 - -3 Nodes configured, 3 expected votes -1 Resources configured - -Online: [ node1 node2 node3 ] - - MaxScale (lsb:maxscale): Started node1 -``` - -### The resource cannot be migrated to node1 for a failure - -First, migrate the the resource to another node, say node3. - -``` -[root@node1 ~]# crm resource migrate MaxScale node3 -... - -Online: [ node1 node2 node3 ] - -Failed actions: - - MaxScale_start_0 on node1 'not running' (7): call=76, status=complete, last-rc-change='Mon Jun 30 13:31:17 2014', queued=2015ms, exec=0ms -``` - -**Note**: the _MaxScale_start_ failed action on node1, and after a few seconds. - -``` -[root@node3 ~]# crm status -Last updated: Mon Jun 30 13:35:00 2014 -Last change: Mon Jun 30 13:31:13 2014 via crm_resource on node3 -Stack: classic openais (with plugin) -Current DC: node2 - partition with quorum -Version: 1.1.10-14.el6_5.3-368c726 - -3 Nodes configured, 3 expected votes -1 Resources configured - -Online: [ node1 node2 node3 ] - - MaxScale (lsb:maxscale): Started node2 - -Failed actions: - - MaxScale_start_0 on node1 'not running' (7): call=76, status=complete, last-rc-change='Mon Jun 30 13:31:17 2014', queued=2015ms, exec=0ms -``` - -Successfully, MaxScale has been started on a new node (node2). - -**Note**: Failed actions remain in the output of crm status. - - With "crm resource cleanup MaxScale" is possible to cleanup the messages: - -``` -[root@node1 ~]# crm resource cleanup MaxScale -Cleaning up MaxScale on node1 -Cleaning up MaxScale on node2 -Cleaning up MaxScale on node3 -``` - -The cleaned status is visible from other nodes as well. - -``` -[root@node2 ~]# crm status -Last updated: Mon Jun 30 13:38:18 2014 -Last change: Mon Jun 30 13:38:17 2014 via crmd on node3 -Stack: classic openais (with plugin) -Current DC: node2 - partition with quorum -Version: 1.1.10-14.el6_5.3-368c726 - -3 Nodes configured, 3 expected votes -1 Resources configured - -Online: [ node1 node2 node3 ] - - MaxScale (lsb:maxscale): Started node2 -``` - -## Add a Virtual IP (VIP) to the cluster - -It’s possible to add a virtual IP to the cluster. MariaDB MaxScale process will be only contacted via this IP. The virtual IP can move across nodes in case one of them fails. - -The Setup is very easy. Assuming an addition IP address is available and can be added to one of the nodes, this is the new configuration to add. - -``` -[root@node2 ~]# crm configure primitive maxscale_vip ocf:heartbeat:IPaddr2 params ip=192.168.122.125 op monitor interval=10s -``` - -MariaDB MaxScale process and the VIP must be run in the same node, so it is mandatory to add to the configuration to the group ‘maxscale_service’. - -``` -[root@node2 ~]# crm configure group maxscale_service maxscale_vip MaxScale -``` - -The following is the final configuration. - -``` -[root@node3 ~]# crm configure show -node node1 -node node2 -node node3 -primitive MaxScale lsb:maxscale \ - op monitor interval=15s timeout=10s \ - op start interval=0 timeout=15s \ - op stop interval=0 timeout=30s -primitive maxscale_vip IPaddr2 \ - params ip=192.168.122.125 \ - op monitor interval=10s -group maxscale_service maxscale_vip MaxScale \ - meta target-role=Started -property cib-bootstrap-options: \ - dc-version=1.1.10-14.el6_5.3-368c726 \ - cluster-infrastructure="classic openais (with plugin)" \ - expected-quorum-votes=3 \ - stonith-enabled=false \ - no-quorum-policy=ignore \ - placement-strategy=balanced \ - last-lrm-refresh=1404125486 -``` - -Check the resource status. - -``` -[root@node1 ~]# crm status -Last updated: Mon Jun 30 13:51:29 2014 -Last change: Mon Jun 30 13:51:27 2014 via crmd on node1 -Stack: classic openais (with plugin) -Current DC: node2 - partition with quorum -Version: 1.1.10-14.el6_5.3-368c726 - -3 Nodes configured, 3 expected votes -2 Resources configured - -Online: [ node1 node2 node3 ] - - Resource Group: maxscale_service - - maxscale_vip (ocf::heartbeat:IPaddr2): Started node2 - - MaxScale (lsb:maxscale): Started node2 -``` - -With both resources on node2, now MariaDB MaxScale service will be reachable via the configured VIP address 192.168.122.125. - From 45ad6f943ff3c3f49c1dc6f87c71ddc05e8f47e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 12 Feb 2018 23:48:13 +0200 Subject: [PATCH 07/24] Validate master data inside transaction The insertion and subsequent read of the data into the master in `generate_traffic_and_check` will now be done inside a transaction. This keeps the behavior consistent with the `check` function that only inserts one row. --- maxscale-system-test/fail_switch_rejoin_common.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/maxscale-system-test/fail_switch_rejoin_common.cpp b/maxscale-system-test/fail_switch_rejoin_common.cpp index 292020649..765a39381 100644 --- a/maxscale-system-test/fail_switch_rejoin_common.cpp +++ b/maxscale-system-test/fail_switch_rejoin_common.cpp @@ -147,13 +147,16 @@ bool generate_traffic_and_check(TestConnections& test, MYSQL* conn, int insert_c timespec short_sleep; short_sleep.tv_sec = 0; short_sleep.tv_nsec = 100000000; + + mysql_query(conn, "BEGIN"); + for (int i = 0; i < insert_count; i++) { test.try_query(conn, INSERT, inserts++); nanosleep(&short_sleep, NULL); } - sleep(1); bool rval = false; + mysql_query(conn, SELECT); MYSQL_RES *res = mysql_store_result(conn); test.assert(res != NULL, "Query did not return a result set"); @@ -184,6 +187,7 @@ bool generate_traffic_and_check(TestConnections& test, MYSQL* conn, int insert_c } mysql_free_result(res); } + mysql_query(conn, "COMMIT"); return rval; } From 2e920af845910fac989d6eb0815a5eb2dbef8d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 13 Feb 2018 01:10:23 +0200 Subject: [PATCH 08/24] Change expected result of mysqlmon_rejoin_bad2 Instead of the current master rejoining to the diverged master, the current master should remain as the master server. This behavior should be explained by the extra GTID event injected by the failover process. --- maxscale-system-test/mysqlmon_rejoin_bad2.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/maxscale-system-test/mysqlmon_rejoin_bad2.cpp b/maxscale-system-test/mysqlmon_rejoin_bad2.cpp index 27837696b..7b89d2551 100644 --- a/maxscale-system-test/mysqlmon_rejoin_bad2.cpp +++ b/maxscale-system-test/mysqlmon_rejoin_bad2.cpp @@ -129,9 +129,9 @@ int main(int argc, char** argv) return test.global_result; } - // Manually set current master to replicate from the old master to quickly fix the cluster. - cout << "Setting server " << master_id_new << " to replicate from server 1. Auto-rejoin should redirect " - "servers so that in the end server 1 is master and all others are slaves." << endl; + // Set current master to replicate from the old master. The old master should remain as the current master. + cout << "Setting server " << master_id_new << " to replicate from server 1. Server " << master_id_new + << " should remain as the master because server 1 doesn't have the latest event it has." << endl; const char CHANGE_CMD_FMT[] = "CHANGE MASTER TO MASTER_HOST = '%s', MASTER_PORT = %d, " "MASTER_USE_GTID = current_pos, MASTER_USER='repl', MASTER_PASSWORD = 'repl';"; char cmd[256]; @@ -143,9 +143,10 @@ int main(int argc, char** argv) sleep(5); get_output(test); - expect(test, "server1", "Master", "Running"); - expect(test, "server2", "Slave", "Running"); + expect(test, "server1", "Running"); + expect(test, "server2", "Master", "Running"); expect(test, "server3", "Slave", "Running"); expect(test, "server4", "Slave", "Running"); + test.repl->fix_replication(); return test.global_result; } From 8e4c6a9eee9124facb98d4b65131418393e412cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 13 Feb 2018 12:55:34 +0200 Subject: [PATCH 09/24] Use HTTPS also for pings If HTTPS requests are used, the pings should also be done with HTTPS. --- maxctrl/lib/common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maxctrl/lib/common.js b/maxctrl/lib/common.js index 9372c28fa..8497749a7 100644 --- a/maxctrl/lib/common.js +++ b/maxctrl/lib/common.js @@ -275,7 +275,7 @@ function pingCluster(hosts) { var promises = [] hosts.forEach(function(i) { - promises.push(request(getUri(i, false, ''))) + promises.push(request(getUri(i, this.argv.secure, ''))) }) return Promise.all(promises) From 5716f0b21012f3b8832985e49e08b8e36e5cb3aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 13 Feb 2018 13:36:01 +0200 Subject: [PATCH 10/24] Add support for self-signed certificates to MaxCtrl MaxCtrl now supports explicit paths for certificates and optional server certificate verification. This allows testing by using a self-signed certificate with the server certificate verification turned off. --- Documentation/Reference/MaxCtrl.md | 15 ++++++++--- maxctrl/lib/common.js | 40 +++++++++++++++++++++++++++++- maxctrl/lib/core.js | 38 ++++++++++++++++++++-------- 3 files changed, 78 insertions(+), 15 deletions(-) diff --git a/Documentation/Reference/MaxCtrl.md b/Documentation/Reference/MaxCtrl.md index 53f313e4f..d5effed0d 100644 --- a/Documentation/Reference/MaxCtrl.md +++ b/Documentation/Reference/MaxCtrl.md @@ -43,10 +43,17 @@ All command accept the following global options. -h, --hosts List of MaxScale hosts. The hosts must be in HOST:PORT format and each value must be separated by a comma. [string] [default: "localhost:8989"] - -s, --secure Enable HTTPS requests [boolean] [default: "false"] - -t, --timeout Request timeout in milliseconds [number] [default: "10000"] - -q, --quiet Silence all output [boolean] [default: "false"] - --tsv Print tab separated output [boolean] [default: "false"] + -t, --timeout Request timeout in milliseconds [number] [default: 10000] + -q, --quiet Silence all output [boolean] [default: false] + --tsv Print tab separated output [boolean] [default: false] + +HTTPS/TLS Options: + -s, --secure Enable HTTPS requests [boolean] [default: false] + --tls-key Path to TLS private key [string] + --tls-cert Path to TLS public certificate [string] + --tls-ca-cert Path to TLS CA certificate [string] + --tls-verify-server-cert Whether to verify server TLS certificates + [boolean] [default: true] Options: --version Show version number [boolean] diff --git a/maxctrl/lib/common.js b/maxctrl/lib/common.js index 8497749a7..bf786d6dc 100644 --- a/maxctrl/lib/common.js +++ b/maxctrl/lib/common.js @@ -16,6 +16,7 @@ var colors = require('colors/safe'); var Table = require('cli-table'); var consoleLib = require('console') var os = require('os') +var fs = require('fs') module.exports = function() { @@ -57,6 +58,13 @@ module.exports = function() { argv.reject(err) }) }, function(err) { + + if (err.error.cert) { + // TLS errors cause extremely verbose errors, truncate the certifiate details + // from the error output + delete err.error.cert + } + // One of the HTTP request pings to the cluster failed, log the error argv.reject(JSON.stringify(err.error, null, 4)) }) @@ -181,6 +189,31 @@ module.exports = function() { return Promise.resolve(colors.green('OK')) } + + this.setTlsCerts = function(args) { + args.agentOptions = {} + if (this.argv['tls-key']) { + args.agentOptions.key = fs.readFileSync(this.argv['tls-key']) + } + + if (this.argv['tls-cert']) { + args.agentOptions.cert = fs.readFileSync(this.argv['tls-cert']) + } + + if (this.argv['tls-ca-cert']) { + args.agentOptions.ca = fs.readFileSync(this.argv['tls-ca-cert']) + } + + if (this.argv['tls-passphrase']) { + args.agentOptions.passphrase = this.argv['tls-passphrase'] + } + + if (!this.argv['tls-verify-server-cert']) { + args.agentOptions.checkServerIdentity = function() { + } + } + } + // Helper for executing requests and handling their responses, returns a // promise that is fulfilled when all requests successfully complete. The // promise is rejected if any of the requests fails. @@ -189,6 +222,7 @@ module.exports = function() { args.uri = getUri(host, this.argv.secure, resource) args.json = true args.timeout = this.argv.timeout + setTlsCerts(args) return request(args) .then(function(res) { @@ -275,7 +309,11 @@ function pingCluster(hosts) { var promises = [] hosts.forEach(function(i) { - promises.push(request(getUri(i, this.argv.secure, ''))) + args = {} + args.uri = getUri(i, this.argv.secure, '') + args.json = true + setTlsCerts(args) + promises.push(request(args)) }) return Promise.all(promises) diff --git a/maxctrl/lib/core.js b/maxctrl/lib/core.js index 7a3c34ee5..a386c9642 100644 --- a/maxctrl/lib/core.js +++ b/maxctrl/lib/core.js @@ -21,7 +21,7 @@ program .strict() .exitProcess(false) .showHelpOnFail(false) - .group(['u', 'p', 'h', 's', 't', 'q', 'tsv'], 'Global Options:') + .group(['u', 'p', 'h', 't', 'q', 'tsv'], 'Global Options:') .option('u', { alias:'user', global: true, @@ -42,27 +42,45 @@ program default: 'localhost:8989', type: 'string' }) - .option('s', { - alias: 'secure', - describe: 'Enable HTTPS requests', - default: 'false', - type: 'boolean' - }) .option('t', { alias: 'timeout', describe: 'Request timeout in milliseconds', - default: '10000', + default: 10000, type: 'number' }) .option('q', { alias: 'quiet', describe: 'Silence all output', - default: 'false', + default: false, type: 'boolean' }) .option('tsv', { describe: 'Print tab separated output', - default: 'false', + default: false, + type: 'boolean' + }) + .group(['s', 'tls-key', 'tls-cert', 'tls-ca-cert', 'tls-verify-server-cert'], 'HTTPS/TLS Options:') + .option('s', { + alias: 'secure', + describe: 'Enable HTTPS requests', + default: false, + type: 'boolean' + }) + .option('tls-key', { + describe: 'Path to TLS private key', + type: 'string' + }) + .option('tls-cert', { + describe: 'Path to TLS public certificate', + type: 'string' + }) + .option('tls-ca-cert', { + describe: 'Path to TLS CA certificate', + type: 'string' + }) + .option('tls-verify-server-cert', { + describe: 'Whether to verify server TLS certificates', + default: true, type: 'boolean' }) From f6c83585970224d63236d5e50e529cee5981a41b Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 13 Feb 2018 15:20:53 +0200 Subject: [PATCH 11/24] Update release notes --- Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md index fab60e518..fb0038f4b 100644 --- a/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md @@ -40,6 +40,9 @@ for more information. * [MXS-1661](https://jira.mariadb.org/browse/MXS-1661) Excessive logging by MySQLAuth at authentication error (was: MySQLAuth SQLite database can be permanently locked) * [MXS-1660](https://jira.mariadb.org/browse/MXS-1660) Failure to resolve hostname is considered an error * [MXS-1654](https://jira.mariadb.org/browse/MXS-1654) MaxScale crashes if env-variables are used without substitute_variables=1 having been defined +* [MXS-1653](https://jira.mariadb.org/browse/MXS-1653) sysbench failed to initialize w/ MaxScale read/write splitter +* [MXS-1647](https://jira.mariadb.org/browse/MXS-1647) Module API version is not checked +* [MXS-1643](https://jira.mariadb.org/browse/MXS-1643) Too many monitor events are triggered * [MXS-1641](https://jira.mariadb.org/browse/MXS-1641) Fix overflow in master id * [MXS-1633](https://jira.mariadb.org/browse/MXS-1633) Need remove mutex in sqlite * [MXS-1630](https://jira.mariadb.org/browse/MXS-1630) MaxCtrl binary are not included by default in MaxScale package @@ -53,6 +56,7 @@ for more information. * [MXS-1586](https://jira.mariadb.org/browse/MXS-1586) Mysqlmon switchover does not immediately detect bad new master * [MXS-1583](https://jira.mariadb.org/browse/MXS-1583) Database firewall filter failing with multiple users statements in rules file * [MXS-1539](https://jira.mariadb.org/browse/MXS-1539) Authentication data should be thread specific +* [MXS-1508](https://jira.mariadb.org/browse/MXS-1508) Failover is sometimes triggered on non-simple topologies ## Known Issues and Limitations From 3f0ce53ae37bba3897008e4ccfcb200b5e72442b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 13 Feb 2018 14:58:14 +0200 Subject: [PATCH 12/24] Remove dead links The documents they point to don't exist. --- Documentation/Documentation-Contents.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index 75f473557..3009bba65 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -4,7 +4,6 @@ ## About MariaDB MaxScale - [About MariaDB MaxScale](About/About-MaxScale.md) - - [Release Notes](Release-Notes/MaxScale-2.1.5-Release-Notes.md) - [Changelog](Changelog.md) - [Limitations](About/Limitations.md) @@ -53,7 +52,6 @@ These tutorials are for specific use cases and module combinations. Here are tutorials on monitoring and managing MariaDB MaxScale in cluster environments. - - [MariaDB MaxScale HA with Corosync-Pacemaker](Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md) - [MariaDB MaxScale HA with Lsyncd](Tutorials/MaxScale-HA-with-lsyncd.md) - [Nagios Plugins for MariaDB MaxScale Tutorial](Tutorials/Nagios-Plugins.md) From a6a73f8c299bced646b3981a2d2aeeac378cf6fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 13 Feb 2018 15:56:52 +0200 Subject: [PATCH 13/24] MXS-1537: Move CDC Connector documentation Placed the CDC Connector documentation in the main documentation directory under the Connector directory. Added a link into the Documentation-Contents.md document. --- .../Connectors/CDC-Connector.md | 16 +++++++++++----- Documentation/Documentation-Contents.md | 4 ++++ 2 files changed, 15 insertions(+), 5 deletions(-) rename connectors/cdc-connector/README.md => Documentation/Connectors/CDC-Connector.md (76%) diff --git a/connectors/cdc-connector/README.md b/Documentation/Connectors/CDC-Connector.md similarity index 76% rename from connectors/cdc-connector/README.md rename to Documentation/Connectors/CDC-Connector.md index b5bcf94b5..63ecace82 100644 --- a/connectors/cdc-connector/README.md +++ b/Documentation/Connectors/CDC-Connector.md @@ -1,12 +1,18 @@ -# maxscale-cdc-connector +# Maxscale CDC Connector The C++ connector for the [MariaDB MaxScale](https://mariadb.com/products/technology/maxscale) [CDC system](https://mariadb.com/kb/en/mariadb-enterprise/mariadb-maxscale-22-avrorouter-tutorial/). ## Usage -The CDC connector is a single-file connector which allows it to be -relatively easily embedded into existing applications. +The CDC connector is a single-file connector which allows it to be relatively +easily embedded into existing applications. + +## Examples + +The source code +[contains an example](https://github.com/mariadb-corporation/MaxScale/blob/2.2/connectors/cdc-connector/examples/main.cpp) +that demonstrates basic usage of the MaxScale CDC Connector. ## Dependencies @@ -45,5 +51,5 @@ sudo zypper install -y libjansson-devel openssl-devel cmake make gcc-c++ git ## Building and Packaging To build and package the connector as a library, follow MaxScale build -instructions with the exception of adding `-DTARGET_COMPONENT=devel` to -the CMake call. +instructions with the exception of adding `-DTARGET_COMPONENT=devel` to the +CMake call. diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index 3009bba65..b52a22427 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -113,6 +113,10 @@ Documentation for MaxScale protocol modules. - [Change Data Capture (CDC) Protocol](Protocols/CDC.md) - [Change Data Capture (CDC) Users](Protocols/CDC_users.md) +The MaxScale CDC Connector provides a C++ API for consuming data from a CDC system. + + - [CDC Connector](Connectors/CDC-Connector.md) + ## Authenticators A short description of the authentication module type can be found in the From f3a77f228cfd827f48a36670276b1c31c7346860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 13 Feb 2018 15:59:09 +0200 Subject: [PATCH 14/24] Update 2.2 upgrading document and release notes Listed changes to MaxCtrl and the CDC connnector to release notes. Added a note into the upgrade document about the beta versions of the MaxCtrl client. --- .../Release-Notes/MaxScale-2.2.2-Release-Notes.md | 15 +++++++++++++++ .../Upgrading/Upgrading-To-MaxScale-2.2.md | 8 +++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md index fb0038f4b..613e870f7 100644 --- a/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md @@ -10,6 +10,21 @@ report at [Jira](https://jira.mariadb.org). ## Changed Features +### MaxCtrl Moved to `maxscale` Package + +The MaxCtrl client is now a part of the main MaxScale package, `maxscale`. This +means that the `maxctrl` executable is now immediately available upon the +installation of MaxScale. + +In the 2.2.1 beta version MaxCtrl was in its own package. If you have a previous +installation of MaxCtrl, please remove it before upgrading to MaxScale 2.2.2. + +### MaxScale C++ CDC Connector Integration + +The MaxScale C++ CDC Connector is now distributed as a part of MaxScale. The +connector libraries are in a separate package, `maxscale-cdc-connector`. Refer +to the [CDC Connector documentation](../Connectors/CDC-Connector.md) for more details. + ## Dropped Features ## New Features diff --git a/Documentation/Upgrading/Upgrading-To-MaxScale-2.2.md b/Documentation/Upgrading/Upgrading-To-MaxScale-2.2.md index 5fc566a09..1ff71d84c 100644 --- a/Documentation/Upgrading/Upgrading-To-MaxScale-2.2.md +++ b/Documentation/Upgrading/Upgrading-To-MaxScale-2.2.md @@ -25,4 +25,10 @@ string in slashes, e.g. `match=/^select/` defines the pattern `^select`. ### Binlog Server Binlog server automatically accepts GTID connection from MariaDB 10 slave servers -by saving all incoming GTIDs into a SQLite map database. \ No newline at end of file +by saving all incoming GTIDs into a SQLite map database. + +### MaxCtrl Included in Main Package + +In the 2.2.1 beta version MaxCtrl was in its own package whereas in 2.2.2 +it is in the main `maxscale` package. If you have a previous installation +of MaxCtrl, please remove it before upgrading to MaxScale 2.2.2. From 558fdc1875cb828bdd9c35fbf37d4ca389fcdc84 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 14 Feb 2018 13:42:42 +0200 Subject: [PATCH 15/24] MXS-1644 Do not refresh users if max connections is reached According to MXS-1644 the refreshing of users may cause a crash. In that particular case, the refreshing is triggered by the authentication failing due to the user having hit the 'max_user_connection' limit of the server. That is, refreshing the users in the situation is never going to change the end-result. With this change, the users will not be refreshed in that case and hopefully the crash will be avoided. Note that this is something of a workaround as the crash could not be repeated and the refreshing of the users should obviously not ever cause MaxScale to crash. --- server/modules/protocol/mysql_backend.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 23bf2a2b4..4d13d9d7f 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -19,6 +19,7 @@ #include #include #include +#include /* The following can be compared using memcmp to detect a null password */ uint8_t null_client_sha1[MYSQL_SCRAMBLE_LEN]=""; @@ -86,7 +87,7 @@ static int gw_read_reply_or_error(DCB *dcb, MYSQL_session local_session); static int gw_read_and_write(DCB *dcb, MYSQL_session local_session); static int gw_read_backend_handshake(MySQLProtocol *conn); static int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload); -static int gw_receive_backend_auth(MySQLProtocol *protocol); +static int gw_receive_backend_auth(MySQLProtocol *protocol, uint16_t *code); static mysql_auth_state_t gw_send_authentication_to_backend(char *dbname, char *user, uint8_t *passwd, @@ -883,12 +884,13 @@ gw_read_reply_or_error(DCB *dcb, MYSQL_session local_session) } CHK_SESSION(session); + uint16_t code = 0; if (backend_protocol->protocol_auth_state == MYSQL_AUTH_RECV) { /** * Read backend's reply to authentication message */ - int receive_rc = gw_receive_backend_auth(backend_protocol); + int receive_rc = gw_receive_backend_auth(backend_protocol, &code); switch (receive_rc) { @@ -945,7 +947,12 @@ gw_read_reply_or_error(DCB *dcb, MYSQL_session local_session) if (backend_protocol->protocol_auth_state == MYSQL_AUTH_FAILED && dcb->session->state != SESSION_STATE_STOPPING) { - service_refresh_users(dcb->session->service); + // If the authentication failed due to too many connections, + // we do not refresh the users as it would not change anything. + if (code != ER_TOO_MANY_USER_CONNECTIONS) + { + service_refresh_users(dcb->session->service); + } } #if defined(SS_DEBUG) MXS_DEBUG("%lu [gw_read_backend_event] " @@ -2224,11 +2231,14 @@ gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload) * Receive the MySQL authentication packet from backend, packet # is 2 * * @param protocol The MySQL protocol structure - * @return -1 in case of failure, 0 if there was nothing to read, 1 if read - * was successful. + * @param code [out] The protocol error code, if -1 is returned. + + * @return -1 in case of failure, + * 0 if there was nothing to read, + * 1 if read was successful. */ static int -gw_receive_backend_auth(MySQLProtocol *protocol) +gw_receive_backend_auth(MySQLProtocol *protocol, uint16_t *code) { int n = -1; GWBUF *head = NULL; @@ -2258,6 +2268,7 @@ gw_receive_backend_auth(MySQLProtocol *protocol) else if (ptr[4] == 0xff) { size_t len = MYSQL_GET_PACKET_LEN(ptr); + *code = MYSQL_GET_ERRCODE(ptr); char* err = strndup(&((char *)ptr)[8], 5); char* bufstr = strndup(&((char *)ptr)[13], len - 4 - 5); From 3b2ec4ab5abd9537361a5efc9787000522ce5a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 14 Feb 2018 11:49:39 +0200 Subject: [PATCH 16/24] Change references from MySQL to MariaDB A few were missed when the renaming was done. Also renamed the file to mariadbmon.cc. --- .../modules/monitor/mariadbmon/CMakeLists.txt | 2 +- .../{mysql_mon.cc => mariadbmon.cc} | 36 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) rename server/modules/monitor/mariadbmon/{mysql_mon.cc => mariadbmon.cc} (99%) diff --git a/server/modules/monitor/mariadbmon/CMakeLists.txt b/server/modules/monitor/mariadbmon/CMakeLists.txt index af152bf4e..ba5aaebb0 100644 --- a/server/modules/monitor/mariadbmon/CMakeLists.txt +++ b/server/modules/monitor/mariadbmon/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(mariadbmon SHARED mysql_mon.cc) +add_library(mariadbmon SHARED mariadbmon.cc) target_link_libraries(mariadbmon maxscale-common) add_dependencies(mariadbmon pcre2) set_target_properties(mariadbmon PROPERTIES VERSION "1.4.0") diff --git a/server/modules/monitor/mariadbmon/mysql_mon.cc b/server/modules/monitor/mariadbmon/mariadbmon.cc similarity index 99% rename from server/modules/monitor/mariadbmon/mysql_mon.cc rename to server/modules/monitor/mariadbmon/mariadbmon.cc index 4de130849..7b02b5ee8 100644 --- a/server/modules/monitor/mariadbmon/mysql_mon.cc +++ b/server/modules/monitor/mariadbmon/mariadbmon.cc @@ -12,7 +12,7 @@ */ /** - * @file mysql_mon.c - A MySQL replication cluster monitor + * @file A MariaDB replication cluster monitor */ #define MXS_MODULE_NAME "mariadbmon" @@ -811,8 +811,8 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE() { - MXS_NOTICE("Initialise the MySQL Monitor module."); - static const char ARG_MONITOR_DESC[] = "MySQL Monitor name (from configuration file)"; + MXS_NOTICE("Initialise the MariaDB Monitor module."); + static const char ARG_MONITOR_DESC[] = "Monitor name (from configuration file)"; static modulecmd_arg_type_t switchover_argv[] = { { @@ -865,7 +865,7 @@ extern "C" MXS_MODULE_API_MONITOR, MXS_MODULE_GA, MXS_MONITOR_VERSION, - "A MySQL Master/Slave replication monitor", + "A MariaDB Master/Slave replication monitor", "V1.5.0", MXS_NO_MODULE_CAPABILITIES, &MyObject, @@ -939,7 +939,7 @@ void info_free_func(void *val) /** * @brief Helper function that initializes the server info hashtable * - * @param handle MySQL monitor handle + * @param handle MariaDB monitor handle * @param database List of monitored databases * @return True on success, false if initialization failed. At the moment * initialization can only fail if memory allocation fails. @@ -1671,7 +1671,7 @@ static MXS_MONITORED_SERVER *build_mysql51_replication_tree(MXS_MONITOR *mon) /** * Monitor an individual server * - * @param handle The MySQL Monitor object + * @param handle The Monitor object * @param database The database to probe */ static void @@ -2534,7 +2534,7 @@ monitorMain(void *arg) } } - /* Do now the heartbeat replication set/get for MySQL Replication Consistency */ + /* Generate the replication heartbeat event by performing an update */ if (replication_heartbeat && root_master && (SERVER_IS_MASTER(root_master->server) || @@ -2598,11 +2598,12 @@ monitorMain(void *arg) } /** - * Fetch a MySQL node by node_id + * Fetch a node by node_id * - * @param ptr The list of servers to monitor - * @param node_id The MySQL server_id to fetch - * @return The server with the required server_id + * @param ptr The list of servers to monitor + * @param node_id The server_id to fetch + * + * @return The server with the required server_id */ static MXS_MONITORED_SERVER * getServerByNodeId(MXS_MONITORED_SERVER *ptr, long node_id) @@ -2621,10 +2622,10 @@ getServerByNodeId(MXS_MONITORED_SERVER *ptr, long node_id) } /** - * Fetch a MySQL slave node from a node_id + * Fetch a slave node from a node_id * * @param ptr The list of servers to monitor - * @param node_id The MySQL server_id to fetch + * @param node_id The server_id to fetch * @param slave_down_setting Whether to accept or reject slaves which are down * @return The slave server of this node_id */ @@ -2899,9 +2900,8 @@ static void set_slave_heartbeat(MXS_MONITOR* mon, MXS_MONITORED_SERVER *database /******* * This function computes the replication tree - * from a set of MySQL Master/Slave monitored servers - * and returns the root server with SERVER_MASTER bit. - * The tree is computed even for servers in 'maintenance' mode. + * from a set of monitored servers and returns the root server with + * SERVER_MASTER bit. The tree is computed even for servers in 'maintenance' mode. * * @param handle The monitor handle * @param num_servers The number of servers monitored @@ -3938,7 +3938,7 @@ static bool query_one_row(MXS_MONITORED_SERVER *database, const char* query, uns if (columns != expected_cols) { mysql_free_result(result); - MXS_ERROR("Unexpected result for '%s'. Expected %d columns, got %d. MySQL Version: %s", + MXS_ERROR("Unexpected result for '%s'. Expected %d columns, got %d. Server version: %s", query, expected_cols, columns, database->server->version_string); } else @@ -4248,7 +4248,7 @@ static bool switchover_start_slave(MYSQL_MONITOR* mon, MXS_MONITORED_SERVER* old } /** - * Get MySQL connection error strings from all the given servers, form one string. + * Get MariaDB connection error strings from all the given servers, form one string. * * @param slaves Servers with errors * @return Concatenated string. From 5941f9d3b3004676ab30bc1d9c2b9ce34a958a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 14 Feb 2018 12:07:15 +0200 Subject: [PATCH 17/24] Silence debugging commands If verbose mode is not enabled, the exact commands don't need to be printed. --- maxscale-system-test/testconnections.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/maxscale-system-test/testconnections.cpp b/maxscale-system-test/testconnections.cpp index 5c44be7df..e41cab5a3 100644 --- a/maxscale-system-test/testconnections.cpp +++ b/maxscale-system-test/testconnections.cpp @@ -546,7 +546,10 @@ void TestConnections::process_template(int m, const char *template_name, const c tprintf("Template file is %s\n", template_file); sprintf(str, "cp %s maxscale.cnf", template_file); - tprintf("Executing '%s' command\n", str); + if (verbose) + { + tprintf("Executing '%s' command\n", str); + } if (system(str) != 0) { tprintf("Error copying maxscale.cnf template\n"); From 4853fb0c64cfc00ac32352fd204f7640f067c5d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 14 Feb 2018 12:36:00 +0200 Subject: [PATCH 18/24] Prevent double free of rerouted queries When the routing of a queued query fails, the route_stored_query function extract the SQL from and frees the already freed buffer. --- .../routing/readwritesplit/readwritesplit.cc | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.cc b/server/modules/routing/readwritesplit/readwritesplit.cc index 6c9863345..c45f86b8e 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.cc +++ b/server/modules/routing/readwritesplit/readwritesplit.cc @@ -485,18 +485,7 @@ static bool route_stored_query(RWSplitSession *rses) if (!routeQuery((MXS_ROUTER*)rses->router, (MXS_ROUTER_SESSION*)rses, query_queue)) { rval = false; - char* sql = modutil_get_SQL(query_queue); - - if (sql) - { - MXS_ERROR("Routing query \"%s\" failed.", sql); - MXS_FREE(sql); - } - else - { - MXS_ERROR("Failed to route query."); - } - gwbuf_free(query_queue); + MXS_ERROR("Failed to route queued query."); } if (rses->query_queue == NULL) From 754d80da753a384385b3d4c5c8aa9aa24750bb5a Mon Sep 17 00:00:00 2001 From: Esa Korhonen Date: Wed, 14 Feb 2018 16:21:08 +0200 Subject: [PATCH 19/24] Do not auto_rejoin if maxscale is passive --- server/modules/monitor/mariadbmon/mariadbmon.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/modules/monitor/mariadbmon/mariadbmon.cc b/server/modules/monitor/mariadbmon/mariadbmon.cc index 7b02b5ee8..d73bf4603 100644 --- a/server/modules/monitor/mariadbmon/mariadbmon.cc +++ b/server/modules/monitor/mariadbmon/mariadbmon.cc @@ -2563,7 +2563,8 @@ monitorMain(void *arg) // Do not auto-join servers on this monitor loop if a failover (or any other cluster modification) // has been performed, as server states have not been updated yet. It will happen next iteration. - if (handle->auto_rejoin && !failover_performed && cluster_can_be_joined(handle)) + if (!config_get_global_options()->passive && handle->auto_rejoin && + !failover_performed && cluster_can_be_joined(handle)) { // Check if any servers should be autojoined to the cluster ServerVector joinable_servers; From 11a7669df49d52bbc0d8e1814d0cc19b8b930495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Thu, 15 Feb 2018 10:56:37 +0200 Subject: [PATCH 20/24] MXS-1537: Add API overview to CDC Connector documentation The overview goes over the main functions of the Connector and Row classes. --- Documentation/Connectors/CDC-Connector.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/Connectors/CDC-Connector.md b/Documentation/Connectors/CDC-Connector.md index 63ecace82..32af1bc68 100644 --- a/Documentation/Connectors/CDC-Connector.md +++ b/Documentation/Connectors/CDC-Connector.md @@ -8,6 +8,20 @@ The C++ connector for the [MariaDB MaxScale](https://mariadb.com/products/techno The CDC connector is a single-file connector which allows it to be relatively easily embedded into existing applications. +## API Overview + +A CDC connection object is prepared by instantiating the `CDC::Connection` +class. To create the actual connection, call the `CDC::Connection::connect` +method of the class. + +After the connection has been created, call the `CDC::Connection::read` method +to get a row of data. The `CDC::Row::length` method tells how many values a row +has and `CDC::Row::value` is used to access that value. The field name of a +value can be extracted with the `CDC::Row::key` method and the current GTID of a +row of data is retrieved with the `CDC::Row::gtid` method. + +To close the connection, destroy the instantiated object. + ## Examples The source code From 1042b861bb6837a8632770d1fa28e4d652eadc9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Thu, 15 Feb 2018 10:35:12 +0200 Subject: [PATCH 21/24] MXS-1669: Fix load average tracking The output of `show threads` could have a negative historic thread load average that could be explained by the overflow of the signed 32-bit integer used to count the number of samples. The time that each thread started to process an event for a DCB used an old value that is no longer used. Updating this to DCB::last_read retains the 2.0 behavior. --- server/core/poll.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/core/poll.c b/server/core/poll.c index 0fabd8f8d..5fbaca1a8 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -125,7 +125,7 @@ SPINLOCK pollqlock = SPINLOCK_INIT; * poll completion, a value of 1 or less is the ideal. */ static double load_average = 0.0; -static int load_samples = 0; +static uint64_t load_samples = 0; static int load_nfds = 0; static double current_avg = 0.0; static double *avg_samples = NULL; @@ -755,7 +755,7 @@ poll_waitevents(void *arg) pollStats.n_fds[(nfds < MAXNFDS ? (nfds - 1) : MAXNFDS - 1)]++; load_average = (load_average * load_samples + nfds) / (load_samples + 1); - atomic_add(&load_samples, 1); + atomic_add_uint64(&load_samples, 1); atomic_add(&load_nfds, nfds); /* @@ -1368,7 +1368,7 @@ dShowThreads(DCB *dcb) dcb_printf(dcb, " %2d | %-10s | %6d | %-16p | <%3lu00ms | %s\n", i, state, thread_data[i].n_fds, - thread_data[i].cur_dcb, 1 + hkheartbeat - dcb->evq.started, + thread_data[i].cur_dcb, 1 + hkheartbeat - dcb->last_read, event_string); if (from_heap) @@ -1388,8 +1388,8 @@ dShowThreads(DCB *dcb) static void poll_loadav(void *data) { - static int last_samples = 0, last_nfds = 0; - int new_samples, new_nfds; + static uint64_t last_samples = 0, last_nfds = 0; + uint64_t new_samples, new_nfds; new_samples = load_samples - last_samples; new_nfds = load_nfds - last_nfds; From b1300fdb01ace7a4b795736da4b305cb24a75317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Thu, 15 Feb 2018 11:28:14 +0200 Subject: [PATCH 22/24] Sync slaves after creating new users After the users in the local_address test are created, the slaves need to be synced to make sure that users have replicated to all servers. --- maxscale-system-test/local_address.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/maxscale-system-test/local_address.cpp b/maxscale-system-test/local_address.cpp index ec6ee594d..1233c3cf2 100644 --- a/maxscale-system-test/local_address.cpp +++ b/maxscale-system-test/local_address.cpp @@ -277,6 +277,7 @@ void run_test(TestConnections& test, const vector& ips) create_user_and_grants(test, zUser1, zPassword1, local_ip); create_user_and_grants(test, zUser2, zPassword2, ip2); create_user_and_grants(test, zUser2, zPassword2, local_ip); + test.repl->sync_slaves(); test.tprintf("\n"); test.tprintf("Testing default; alice should be able to access, bob not."); From 13dea56c2d5f667ef4ab5ae28071aa7d3ea90145 Mon Sep 17 00:00:00 2001 From: Esa Korhonen Date: Wed, 14 Feb 2018 15:03:03 +0200 Subject: [PATCH 23/24] Add instructions on setting MaxScale passive/active to Keepalived tutorial --- .../Tutorials/Failover-with-Keepalived.md | 65 ++++++++++++++++++ Documentation/Tutorials/images/Keepalived.png | Bin 21984 -> 101243 bytes 2 files changed, 65 insertions(+) diff --git a/Documentation/Tutorials/Failover-with-Keepalived.md b/Documentation/Tutorials/Failover-with-Keepalived.md index c261229c0..bfc272c5d 100644 --- a/Documentation/Tutorials/Failover-with-Keepalived.md +++ b/Documentation/Tutorials/Failover-with-Keepalived.md @@ -188,3 +188,68 @@ Aug 11 10:51:57 maxscale2 Keepalived_vrrp[20257]: VRRP_Instance(VI_1) Entering F Aug 11 10:51:57 maxscale2 Keepalived_vrrp[20257]: VRRP_Instance(VI_1) removing protocol VIPs. Aug 11 10:51:57 maxscale2 Keepalived_vrrp[20257]: VRRP_Instance(VI_1) Now in FAULT state ``` + +## MaxScale active/passive-setting + +When using multiple MaxScales with replication cluster management features +(failover, switchover, rejoin), only one MaxScale instance should be allowed to +modify the cluster at any given time. This instance should be the one with +MASTER Keepalived status. MaxScale itself does not know its state, but MaxCtrl +(a replacement for MaxAdmin) can set a MaxScale instance to passive mode. As of +version 2.2.2, a passive MaxScale behaves similar to an active one with the +distinction that it won't perform failover, switchover or rejoin. Even manual +versions of these commands will end in error. The passive/active mode +differences may be expanded in the future. + +To have Keepalived modify the MaxScale operating mode, a notify script is +needed. This script is ran whenever Keepalived changes its state. The script +file is defined in the Keepalived configuration file as `notify`. + +``` +... +virtual_ipaddress { + 192.168.1.13 +} +track_script { + chk_myscript +} +notify /home/user/notify_script.sh +... +``` +Keepalived calls the script with three parameters. In our case, only the third +parameter, STATE, is relevant. An example script is below. + +``` +#!/bin/bash + +TYPE=$1 +NAME=$2 +STATE=$3 + +OUTFILE=/home/user/state.txt + +case $STATE in + "MASTER") echo "Setting this MaxScale node to active mode" > $OUTFILE + maxctrl alter maxscale passive false + exit 0 + ;; + "BACKUP") echo "Setting this MaxScale node to passive mode" > $OUTFILE + maxctrl alter maxscale passive true + exit 0 + ;; + "FAULT") echo "MaxScale failed the status check." > $OUTFILE + maxctrl alter maxscale passive true + exit 0 + ;; + *) echo "Unknown state" > $OUTFILE + exit 1 + ;; +esac + +``` +The script logs the current state to a text file and sets the operating mode of +MaxScale. The FAULT case also attempts to set MaxScale to passive mode, +although the MaxCtrl command will likely fail. + +If all MaxScale/Keepalived instances have a similar notify script, only one +MaxScale should ever be in active mode. diff --git a/Documentation/Tutorials/images/Keepalived.png b/Documentation/Tutorials/images/Keepalived.png index f500e5a176ad75c34f64bead2fd5ad02cb14d87b..f9d6d06371a6a650146200a33895f22ede55c3f3 100644 GIT binary patch literal 101243 zcmeAS@N?(olHy`uVBq!ia0y~yV2)&9U<&78V_;xNteN+nfkA=6)5S5Qg7M8=?wpY4 zGwuI9uRMQ4ZiDCCDR27oJYR2F;}u#LRnFY$snIh#WFhyI)uI6_W+Y5rmb)rQRq=>` zjhX|eXUMPDy1X+abTt&#MNZ-keE7Wa>`_jar|Xw$X6PqN-ibW_m%qdopbF!-|P6$#K5A!z{ugiz$DNx${al5;1I;JFX-Fe zrX?vYKClSdvC84WD$NOysJay9(7b$h^2du&2iyGPb23(}?fp5G_pIiBNx@Kq;($BX zqLiu*>^G~7JL=za;zXO^yGci?|Gchfheq;)TdV>pvAbp8wJ@+K7-TRll;rPQI_F35 zlQ^A)F`ZeiUFTSxT#HZfPdwq#HGAvDy|e2Bey#n~JjHpvN>~W9@$tAAuOlH}>>J}v z1g@&b9XEufqU-7j>)w~$;RPqDm0}!cS8)WctM)mayF>9G|3zEV``7-Tdp>i0SAe0k z@mv|MS6{is@7^z6fB${i-%U45Q&(zlYUAs%yZ5(hlil=lF-7mE?0j0faFgoMlc$7# zLKCTxBZF<^%nwrn+(FSL%T#`5rG&4_Z-_Uw~Z`p5c=jwohMK9usbvj!TjGZh-&t|%os!N`y>Ea0c6Fh~o#YRTpKslslN9-L#=Uo6#V>uh?5Dxq|4LW) zoHHb5+Ga6SZECwE>|U+N(0E47U{k>JpqV=???gM#$S~gc^36jppXJ3nRgTwQG?@P4 z=cJVnqhIr1Gka0kp~N`r?hoTc&287@&Xk^AqFH>J`{$z1Z(lTu`?aR&>Zw2bnp3gl zwph2%ykI$lBZ*0xXUgY3cw+gKU;b|N=WPA;mQU-I7Jd`ujVx<@HpRR<;PJ#-(|GSS z{C$d$9DY-yVcwdYnpGLXED95*GTqvIs56oSG?Dax87CnZTepJudkTal?6VR-M;6qOl*Jl+E98{zK(p~ySp{s z-G%=fJI+Zh`Wm-jS?2d^cf4Hs%cgu>QRmiBI@7`r9CZ%UxD-yDy2Rd{=E%TwQ+>kq zWA}pIp3IP(Y@+t;F>67a_K{0z^%9G|>xo>ATR&;#LnYt(g*X2;@8kaX?!~{e_g1wX zFS|NVahbDKkD=LC#mrKlHS#d8%~WZ4*fjIYmVj^$hlC97Ck4WhA9=PMKf&KNsd19< z^XiiVlFkcHZWb#)cU8zac}7Rm!3MU-dmEhA+i1tOD{~$76n?}CPO<_G4gb83a)V1l zBgY5Mrz~|Z3EruBt$#9BEcT6u=?10cJTsO5)xRm)x+CP)6%qT1oNnNR!^q*FAj@)L z@>D*5#!^sGdV!ts?tLwj>W_{|^YUb8dAr!YD|~vkd)7@0^IxBy&8_X4>C}TZ)9Zw1 z1wPb0x=!?(+?tccr}iK2^D+OO|Fd=8V?n>)9jwdNDT`a#{k~p$)p6sd=H8j>Dt|ES z`nmDRuK$nf`JO#t+xxiT<(%zLYu}w%|9RKEEi&2r*Vpc>u>BS;pJU(uzZFuhq%3Dx zrkVb{*mbo6L!*wk#@ukj%Tc@UZIH}9I#21Du}+AKQ@b6{lfNGAVpW+gVN#Di-iy(D zc=lrL?ETWSV*d$A&RW+vtHWf1^8LPdw?4Jy8PpW-`Ko?IL~W6qqLs4?>z!lXCOfkA zgRe&br#FL}VpyKdd~*tmj{&64i(3xdB~oi+LTBh}gxRU-`}I#=_|qq5!ckw@56e2IZgvT| zEmSbydfV!6XBxyim_X^(fq}_WghRzpKLwQk5>9ZnXb4UC@q71;f{zniJ(3RJ{NSNf zWpdy2mUP6lBWos#f*f+1#mQJs#+&gw-`)h?ezoh5@}HcZa_MnPVqQYKl)csKebdh^ zmb)-{s@(s$0B#Nkg~O~~`$O$|i+)Vy$#;ti`yaDz=g+;<<1Wn8-2-xhN~l7}whE!0 zf0T^-J+qFT$T`63qLMcAy3F0pm2Vrw%XnF5Wba_#4k^OS84EqC<330+Gzu0<+A`c! z^5$?z=-|F%xID>ZXAJ{mSlU15gl7w!w=64p_h{$K8%!*bFMostsDl&F4wVaPt<&uu za4-opI25sbT5~2f?N5y--}41em5yv?Tl+y_o3{G6|fpV_f!soqfdZ3AMbt|B1Dxg(lcwVF?=3VnGQ)$Ns}|pIqx_ zDXFg}JMUFwXzUTYklI|DzqTijMT;Nm6Ni4LAFTJ4x&53Nm;@v&8aY!R20kg0JzKfo z^2pQm2A|*UFM9Xz{@Y)vpASs!ngjL$1CxNqREDZeL8`q)pm-|bkhvXN-PW<~<)wo@ zdnUAeyZ>feoy4r*eflQZg+Ft-<&MmY{&AfNV&RDd#xE(U9}YWT1y#bL8KoJy^R&5V z-u!L3X112lMV+FGYaLb^53tr^u6G%NUC0`GhCobMOboxkd?DYXCA-yM7qS2s9h zv0j)wH7b7!8zYCqf?$PR*_Sy5Z{Dw5#Ls>v<_U-HREz&TX(oN|59@kBJ=);V1=5mK zAi@sP(%q1}>g1_4de5tVCV2L7fBa{rY<>S;aPh9`DHf1MnLxt<1#X2CQcu_$9w{<3 zF4SGHH!}EHh>VfX_ZUy7>OKEzns+Z)xXr9=X~_IN==A>FN6Vmwrhma}^gCb4yD}y~=LC zAl}Nc>C(@5^;c|+96X$jFaDjqs9Ah^aht`I8wrA$7c3+GSvuR;-7l?^o)u_lU6oM0 zw_ff&#K3t>Q>RWnDwUveZQatPPp=rCw^{sKwQQeU^_z`>KY#vAw)Pj8*kKYL9xm^1 zGyTlt01c5DHkF@5ju(2lESWHKcFc9#kJI=6dHUhG{r{hjUcGvi{m=IE-uJcZ6MlSn z7^?I(dTNJ9&5sWc&DA#ldpS>BY@f$>^_E|b3{1{W2MpGF=B$YL?bZF*Z%f!c51aF6 z7Hhcwvo+aW6Zoi72Ao_ResQueHR>CEUO(ffX|m7Uf8~dH&F@^_yG+@w=Yq-pkCz25 z#t8ll`CfAJ*Pg7at9CA3x^#cJOuDh)+`gkp`_&e?{jGVuc6(h$&(Epx*EXe|cFSHr zg{|q|&eePWf118OCvI!jRc4nGughI0IBmJ4@!WsseF1H2tMkGW-z`4cmhD`8s$OgnhntGZqX!b8f=7yTP2Aope!<+7 zXXmD-#9o)39C6e%`YyxV)dw^fiw?R6hAA2;A^>Ir!|^ zv(C`aQ0wdK&R%&_jZ2-)+3m!@ghA_Cu4o&f)!S<=}!|qJ}YT zUdh8lty@`HS$BPP+t^XU7FmA3_B(&BO1u2A?GaElVFBYRzYB zK3J3%=jZbA)TvXQudl7WT&wW@!{_|W%*xC5a$4_SoRre?mwMa6z+&Xo@c2(G@3yK{ zIVJID!#4fl{rhxA#ocHb<>R%vPLVs#KYl9w9@^>S>1ohoaCB+Cm3-vPy?<>|b283P z`sNjxt^M!U_5ESp9c(`Lw8gsjK9*k}wKZ$mxvNRflCs~LhpmkYJ$B~2bh4b;u?+u- z*B^^?AN{sv+cv!m_xWf2-;j8C)t5Nl4JP`seHE|QZqJIl_ntGY@7uOZ_b2$ZKq>s`><@aA2KhuiiZJ7buyVO?BsV?$!_msuS? zuPX9yY)EuoEXTi8ylKtCFIz5#aX2WvWnH%|Yk_&shO;wQ+z(MRb7Nl1l>N@jrac)F zk1>rCmEG?hJ#+7aeRl5i^KY%+?s4-^#_+kg9f>7L>BQvb3k()$Y@9-7#fyxzC-yV{+}U)wo0ZTcs;xKW_NVH@X* z4F|-I|DDxw<<+Jgx9noy#eS<6O-n5C$wsHCz)|HP;2OKeU=?N^f4XwJzf8xuJW77G1=Fi;Qpe5H|t~aM}shrZ>-&ZG|*SKC<9~BxJ z`uWLZ|FG;qzjI$)iURWOE& znF{-Y`zRNg*1h)IRq^pr@+}U*pUlS9Zxf%j&ae4&^8Yn{S65fne=)a@D0I)XuAZkC zx95koyi@gb6M5NB&*y)>pSR@OLlhlbjwiA#(R>!t66{8=2pq@uvtG(F5Q29efGBf-#O;I?REPN zYGUUFzOXGMD#0&ns>AMld^f^17HC8?7E#2+nkO+4XQzDD`N>%yas|99Pcz1@D} znuP^D51X7HYA)^tm5Cr%IxsM4ivHNW|M%|WrJTigPlR({J1Xy@vP}B3oL$Y2IRl4<>y0ZB+xx1pcZq@=Kq8`t-?6FtAncte(=YkUi#GCd_o+ zWwekjG0LyB^lM@E+U>g*7^VfO2>tXten=)HGBQ$zt2OTO-d!afiSCmBlDrD%IxovK z*}F|Wk+D~9`fT%K6}i{0vTgnI^z`)dbt_(6x4(T~FeUZ3FeFexZJ`DRmLRnSjptuo zT^+BabT`F9iigd-ROj$IXSVvhwXs6IZjV=ot)2Dl>-zfG%STP-{tFKX_^^4^Dy{YG zE7z^_YnIJ_xAtAP1P|NlS+i%?ySPYsyv(ZmTwGlIzFg+{gmdSw?%lR()v9gVw`}=y zD5`o-^1&YQ&!0Y>+G@jk;px3nL!P&9jgINanr2=3`RdiHZFla(++DE4N~qK3rL$!6 zwJwjv=T4tGefswD)R#)KpkiBVQTY7|n|HcJ5AQ$TfBf;sbXS+~5FH-2W_@01vo*yp z7S30@eg8IlTUxdDMLSS&!K@=ND|TN8@AYqCJv%~PZgmYZHub2<#q(k^4YU&Z;<(&g2N|%{rcr*&*8ni zY>E%BIPYoxKQFUNFSX8JRGpo-H)>Z%{P8(!Lb?~*fGmZj2cAt1$1i<6+Z@xoMpy1I z>*jA47bU{vz=3}tfkWYh6i?|CPH0;b+GAhK(6nYv?UoD)NIwqL+ye~>N-%M3Vsn;F z1+~{fnE=x1jnr;X(9V|Em4dYlA%^g@F*L0?7~nn=#YTr~pz)qt?%i#UP*Wj>G%GeJ zWE)%wR70_G0;mJIiFju_C}c;sflc;MW<34v-i0@x&Myy~dTE)~v^Np$ALhp2vJnVj z0ry2hFGG)gk2IKyuMSShZkr9>;dVBWLF|NR3D>Gh1 zcg>>lMdR78N<{{bwdOq&6`MGJ|MyGW>6iD+S|P`xFrkr&?`E)ML~h8=*$l#_W!6*0 zGzRdY0qjSNN~$+gbd`i@^olT5Je-K{TK44{SNOqGVS9mX#+7p@a%aERi5ax8PY zVa%LsQ_rk9CEA&NyjA1VQw`S*^L^87t*?kNNvbaRyeV&4gyB}nKe=-_{m^TbHs-D9x>5>a+9O8>@EhQsDe+vunMY?)F~?>>@k;xsQW9yDrcnW{q2EZ%O!m z-;6U?g%w#r9{b06XWN5=6O-PUC07VBt@(FzsdH8u-=>G|-p}>s&F1_1GLD@k@~-O# zNpR{0dsN{y>nHtN?>9W07cpB9R?koHfOSBjf&RdYiDT2cCC%9&M}jSY!&>t+n_Sf7V z%WLne3z#AKJV5|71gB)z)yBZG$^F3{_iv$snWyH7Ep_+4vPJd9l_l=Epy3*jMGp5_ z1X8}9lwHY>D&U=;9?G-^Q9Qzr0Xy1!y2; zFVjNH?sCJ~l{ar6dXqOZ!m`@#MUAEG{vPKEQ}6!&cEJi%YWx-9VDHQ_WM4Hu3lvr< z%NznNWd7W-OrNN@(_KPZIQ>*`%IW1Ng0`rd*FCwh?w0Y)p!_Ss;P`1<;qc(vdmCey z*?noCQlf!@Ws+LMyfsS#m6Sn7OX_|2&fjNp_{smL+bsSISbwf@Zrjdw6*QbML6B); zvUc4urOT7UA`hqQZQ03v%|E7p{$o$)xAks~|L!+ggF?tbL7MeULACs3&X_a#yQg>5 z&F#%~nGKRzGTWiyv9<1Vn>jsIoSu8l4hYx#QU7@<2nk6MUJJ zY~pVpPMY++H_ME1p)M#?*&Gs{{#brrVB+KJ^S53(^^@OAnPbDc`9_?U3)HnaJ5Dfx zdXvYvd-UX!XQ*dduURM{D0bk)kMu4!2L`5@$_ig}4BzgU#?>7#=ZN0=UA1?MuNT?B zlayfmlET}gT?Do^lBu$0ete>Hj6;0EyHECyWx*lF7PesB)3dfoxykk3f{WCy-+0Nf z;g`1ghnIpWyn772K-JNNZ%l0#b0SVQuq;!nI|iA4;@QIRf0?~%$Bkg8cSo*nUt7J` z{<~ss7K=fQf$2F7R*-9dan&S#tVola9N~C6?0Kr~v$I!-(zZ>^-=m$mXP({hFKv182AO5+xx8P$`uIBT?fbtT^Q9PB zB3Bl=X@WxeQiy`khClJ2t8bYIdhcBRQrUT{0z+euaL1L_X0!jBi*GJ$J@(1=kjRUF z#o=pm3wZv|o>1d{!eX!Kq?vp6-_PCi)_w2NgFg?7J4`VBah|~x6gUPIOz{=dssww|j{T-_h1AU+*`i+Z8NS1vsYoOBP<&yWCzGxogpa zIs1RO+|OzbX;y7e$lmZIP!Ck{If`?zubmjF_A&cvi`C1ZckA??{&TmQQy|q23Mz#Q zz6wF#_cH12cxji!WqeU({qa?|rS9#LTCg#sI_}Z!&z8^g_%1kUN^G+{Aado+oVYr% za_z33?CbWOyzRR;FS(n}5}EnkBR~-p6e|S__DwLJUgEz-dryhxcMHW6yO;#^Kw~~3 z3L)ZLQ=Z+mY%TV=p*kzws%fbU-}EOs+;0W8=T<-Zuy6Ujl`=<@mVGl^_v%d0iFyC_ z&)?JP+ivZ8>AON=NXD-)A=741IokMy+af-qsDbBo(A&NHj-1l`ecU(xohhRps3Ma{ zlAV~;3tJ1oH1V;2kE&7kjZ;o$X(ivEy?#}H=u4OA&9qte6{bN^(y!;a*@y4l{>apQ zM|`!=v73HJ_eI!dF1v5}C1vS-W5-@ln&jDY;J&>@P{gvhx3kT3p4xrrXHs=wV0x)9 zu(CQuMf}NK_aljFa__I+DEZ6zs>?R9C2Q%@(&{B&c5V*O7MFS3slT3@q#19a^3jU)N8pKFjC5^Sf6ww?Kn~7+1*N%{ewR=lt%>R21(2 zQWv83XHQ9M65qvt7PoWVXWy@~jgsn(*LME1$5!^l_WF%E`wEuYv^>4}>h`ty`+}rm zy!9DbB42*B36KVRLEm6kO;6&yE7zMgOsS4vI)RT#;6zAc>eth5&u2UQe$|k3?CTXi z#j3-i<+pb}EC?yK5=mR6^yW z4JXgoZa8`Sq1AlsCOOe9XO`=I-n_*|((!KU&qqfZxKv8&_%bX(;oQK$aw+0~OHZvwPgqKO6;Xoh=2=V zP;zp3AO+3P2VU5$-k@rH?4>6EMCZbVQI|hmJRQ1pf6hD2lV9gt=I!=9=)3>Y&bT_e zUGJw(I1^EOyWjui&gJ)3#%T6MzK`Gjahv?l;}z$1Km+pEK0D=t2KRY77^*h0wTRAi zVqj|4Sm4OZzrRpVnoGEN#qw1h5xjZZw(j`2R@%$V&O?{k@Nx?l7N`J-t7B znNs_|Yj=XK)oMIg`gik^va3I~@~bSac`~tz@k`3mdorp>Jro#YrzKO`{eDmLLrQ%YR2Als0#))p?Uy93LCu zG=nc{V$|h72UkzLbSpw@)%I6+MZX(=PHWd(@wD=Hte|a(X`=7hsi&^T?Kr`}6S*g7 z=8kDGj9*ezuM6))>Le|3Pzd^d!b9)G?*192_N#@~dtBc7|A1)qA&#qF-nY+ryfjV^ z3ea88areZJ*UIl!DLtB6H&gFqWZ&-8+DIQ}#%b%P?R?L%$>{sdh0nm{CIcgfLxKlq z#)qJ&g6k&9m5FyQe35Hs?wYgF#X2G-`|I1+eoLf0suyM)@zoc+Sh7DyuzHheUizB( zJN6y4Z~y*A%wfXRyXVE%f{Qh9_fb+`pmO`Bh#BH9Pu2L?1j#HqBFYrIFyg=^?cBb# zwzvLVdu@BR)Qh!gUD650;)YHubCYc@>jR1}H+_}(H@(Y!f?2A<39s4ija{I!5L9O| zFmn80y4O|n)AD=tveq`=jrDdPW4})gqsjRN_D4G*1#S*9G zf6e9m{z%&h$NNjG9%x);;@A|V+xJNUn%4gP^pWacoC+tr_NO;VIVN0S={ocuZi^B? zMU;RCH>5nWW}KTYx-I2cNwma|vF&*p zH!s`>o^{Y}`R^jbkBmxkmm|d&=3e@9v3%p7s^upp*f~rvT_SHUHQ%f8Ql+Tz+7n)4 zpVW?Y1t?2)O%9kagDL50Ky*X)y?ddPFMWJ^F*f?1!lFx>#iw8IanPQsaXsQ%F1MVF zrP8y1GtOPKRoOPLNW*N=)ww3Ad6ml2m75m(UY}u|2TpyBDcm9ZLo3an&)8saHfd4Q zyPw>FlRMsU6x94a_0j+J`=wiI*H*3n6eqUXdZVmTS?bl6((KFIF0F_-#VU}pbdC%w zUufg5yR+ljBn zb8@p-_{M^}Pa>c8%iWFt9Q@zr9;noFQ25Fe`d(N5amQwlH7z%1T#RZy5^t;|BEGCS zCw2Cgnh!-wO#Zg7w*Tt)^zpS>rn?l{x4A#>nt0;SD$dt&etQkPe9}P`&YzNi?Q4WD z{PdfD{hrt&@59_38dVQkgI&Iyz3}GKbeZI7yFW`cZ<$?pMZdvJ(}b`6$c`k*nHb^y1;7RRRqTVH_`P zmP&KA-F?1+b8|tbS=VmgZAC}t8CY#uw=}m}#rc`uOD6Gn`NHdJihREt7e(B@aLOe4 zZcC~9=0^_~3VMn-I&(i;#BEq+Sv{xPs-hcb+>1X%eeZG9`)}!=4_qM&u>~?;5 z=+Nx57D~%^D(-(9;?JE{arl?sjY4srxqZ)P&ghKi0nHGr8LkJ-F8|DJ+&Jsm+`Y5c zTYURhEN^X}a@bYr)8~87;x{f#_pDg8^~)5#W*?o`ph1ck_ukDr_tLiRZglaIjoTIH z{M&nr?J*lu`0Dzk*aC2=AI)OIFw^GIx$5E=;XdhE?+jRXZ$GPQ>FsnIQhr+1Z!h(q z-Zy{m-(7A`-YIACOYOCK)g+^v%Y7}?W5SHSbvNVG?Iq5CD_c}6;33Ue|L$_@w2FRi zpO$CS{&NfKi+G=R|DOAAU6_qYcHvHmbpoe%^In!nTDjrO#KqNS)sOctKcn}*JWcBG znZ-v=MJ9b>TJhrEtmvk>4nMd}_AAXV^E#;!{)KC%LN+ zPVsLjImmn5P>^@Sp5Nc|G=&!iC;j|6?^SxoIhmW$#vf1I(~Y0D<9m1Us}DOipZ3pA z|C`DxUDYAGIg)vq{e6M?3lD!+Q8@o2(<@zXXL!5qzsi>1zPwqBes9Z|^;c@g&rG*n z;@@8`lE1juG;UV^|KoqzHc#ovD7F6l@$#?tIw5P0UvjJecD}U!x}2&0fr~4aU)`y@ ztKOS8db5GyTs~!+P351>*GxUV&v)<5ZU4O9R-V_re__|>ebHW}8z()yR_Xcq!zX3V z*Bk#OIx_w<<$QnPz^Nmti>H3ezUH--E#jW-?rnPx7OoP|w!UO|z-!AvP+z-In=@m* z-`Cw!?bld^{ftgNlP~*h>0M?W#g*b4`HMfdM$g-m?0XZ`-93AxVacz%qTe?f{(r|F zaZko5dwN)Z{B9ND+r>+tcV(XxcbG7>Cin?Q<7*)Ul{oz=`?(&r%G}O5I&af7tK&7% z;eM~>zgnGnm(}X2{dYT?tY3pwxNgca;ai&@vuAcz9?{$3{^$I~>E`c6vf~Zg)Tf@) z-hbQrd`XmxANOYQ7hBj(OD4_S<9T-0vDDXBPe;e?Ro={f=BnR;3di1OOZR%biR1cG z@?&wtrPrVL-ZR=S#QFYK+Fyy?8NauL?6!ETZ5fx5`}=%Lj-IU4E2HJwCTnYAs`Ztw z|Kjeic<=Oe*QZCa#aesJy0ZVd8*dET_Hx3x&yJs$ur2wte*2!hZ?$>L*U4n|tn|of z&+xzNdgxT}^e=@hj2tN)4omc8VoGz4-Z}AcD*FzF_qAqeiw__Bed%<5Q^f5I&uh^| z`(sS&-X2-S`MOR}vv!@o{p!CqmtOAuwfB^k*`CAkjsfBJOU$gdzWP=g5u!O)E=1}& zYw@N_KOQc~a*jR_y|JUi>eVXyho9T(Uk2>(Kb~y7wb|!= z`MG$zynWUCrk!zY&)9X_uJPxGi?z|)geU%cem444|IObsT$)#%vy4+aE+csT*vYBe zoj0HUzWK0q%J&!HuQeX6-S{OUw#prExP4QZ4UjOf@7TL=igV^?DE|5>s!%Tp@K@v_A2IL>Bn<~ z!(Vl-eDSB_Vff!^8~3L7p6n=D*C8=0vQXYqXj#~I9?pExWx+nvt2S*ZU;ZWf>E;}V zd8WtCs4x6!^8D}Rg+Cs#UaY@cbSFYnB`x;%w;hVbnJ?xqRkkvGaYp0SCX2TFUb6Sn zdBi^({8PHPbe`@1UHi6wm)raPt3_-^-~al~>+9;)9G0B9W~p%7nWfdOeI4Fcu88c< zsYvv%+$I%l?31F(Y3t&mU;l2-=8nj1U#EyY2epBhOg^ybSL))=a}OvbaT(7%H~)9+ zs}sq^Y*nidpOPWcXYha&|7V0u# zY8pSw)kX&CZ(_*`?pYy=l^uTZa$c<}UVlq`lZ3P1eYf9jY18$SoVTu9`qcebZ_dHwG+Pc-g{ChYM;1p=@qxjum5d*7P>e6)SaTcAv-@W)&6{S@0X^y zYSS-kk3QBs(B1Juk@LcSfs51EK2&q>xG~GPR6qaIGu_gAHLc8sduDfZ9i8eawdc!> zEpPNyb9@hUUHQJvD5?K@rMho*{+xvoCHcQ=R^7Y&t|(#w z>Ae-({bDcc4kktp9#zJ-dpG_xKgVOx>M8#F3Q@#GlJ3T}~~qGhgTa+d#}CC{jT+Wla!Jrl>KUyEC}2uLI}Udo^9ul(ray;Duq z+qS%~$aiVaVp($5=KAzUx`ophmN;z*aW9`yyZy_{f2U7<2xC(*Vtkxikh8`n#nVsr z=XKq?*H4+I&yIN_LsYlE$k+g=_e#-)t(} z#Fpy&{LRaG(^lAjxBnO~a_@D1F)>dOo*Yi6u@ z(Igh!`Qm!#b(4roKMQMPm(7h$H)c(l$8yJ4spLh5z4>%M9cl2$C!3SPr*EGooGcXM z{J4i9aQc1OsCnm{H>vC{*4S72^vCks_3FGXu56a)UzLaH6t$K%YQBG;6#JlQO-RW7 zjb*PD!g-ITZ*aK3kL&ycwneW5JggaS+pV)LpRx1w`q_MimlZ377Ub$(cDrT%i~XOe zP~S_#=Qs6V?*1lJdAjSh<-Xv`B|4)1OJ}%&?hoqsX$h{|fZm8C;Z(skX{fy1& z($tmvH_d;x@UW7r%CRHCf3321{>y6p$E0w}E%t@;=NUHDAOF_<-1VUK$qxNb>L1s| z`+VIX-c#>?_w?+z>#W{0Rz7j+dn>fzXXXdcB#OdSa1(#?uOD5@SKVJ*bN>m;s};4y zch50+GxNwQsfRr~{qxxQ7hY92r4nBLi<|gZdtPFDwmxe_(XofyE@`nuto*lpX6aK^ zpZGJowk>oN@X%(A^|~7snYW|X*jccX`!eTU=`NS1M;{6g-$`Xo%5_+g<7s&GZGOkf zfXkabn5FCDTE0zQIwQ5}--~;*)J-4!_+$BeMxva$lCRR03o<493Z1*F+gUQq4Ue|I z5Q(<)o3`jlMRAMN+7FvS4bawilUeKyyu6|QHzwXDr z#G4*YzKgVZjrKc*J?eY-H7+3WZ28F(N@u-!`h^xYx2*_h>9TyM(Un=U-?PvS{F@J4)@N|d$wS~>sKGYTE_RMrXB9bs&-kWE`pK7)9 zt16BZzKD$d=^t^fW9eO~HAW{@6s->S*(~$kz5V^Hsm!zF!B&Fv?gT3b^xZZxh z-SfRs*kOWc!L}2UOrF9Y{(V>;QTS$0?w9A1qV0!T4=RZMn!nZH?b1%)TnXL7%pZ>= z=FZx-!62ZfZieN{{4cBbMl^;=f4Q7_zVFSxryXp;aS7MeT036~OFw4yNI7Owo8kY< z`P-K5>hsc*>i*5Tr~N(6c-_<=KKYH4uO%O0wO(iHE>-P4Iil>*#`}6@EBwxT&z^h1 z(8ka(@_FIOD+PfCEs}o~S^Z;j?PkT7|7w}Nt~B(($>LM*n95KrqzFqQ>D}26}(U3cKQKTQg?R&kGkwUlJw&hlTm6f&caK{PO*&T+;QEALPX^?mkhdwDRe*YjbDr@%-@B=IyKGsrS{5q-R=*?YQt) zc5O(=-F@qd=O2E3QvSP>LLh@<*dn$*MTW*6kqZxNjxPK#otyh?%)q9}H~#$ab7yUaly;jMCBDd8vf5dFdC!j5;XZ3V_w1d1E28tfoY!HMzuO+$nljzp z_uRvGA$T5(f#s4n!(rCTuPYar3B2%Ku&OSS)7tVo_vM=QADcvzN-Y*RZ;8H@lN0C{_J;dE#RX}C|t%H8~^h@9W{qh4}<7+_&|7%}gAZ>6kIKXuJ)%0Gu zgN?t}E-ZMI#2ecs+R63NEbrg#bD)9W`w@G+n-+dw_$lJ4g_xDY8Q1Ai`df?sHNSWB z%HI1nP;c&WL6%9Nl_ERmo#2I!oW*Q!Fqbj-zqy#%CoyTCdrAJ0yq#TJd7lKlZS5|5 z{j2k}^sZRBOY-5e>*qY1aP#1ueJ3})`=7cd_U9AX*Yo5q8D!L)Vi8DL+9SmZA1Q6r z=61OkCud}NPDyc|_=0Z?iXZtDv$m;N7lA6TxBmMlR`4Ew%XIa)R=B}T(|zr;cIG?} zzq|2W=zp1eiUt>$?(P?neDP_5J$QneXHmn?LzCpWE?;^VY9M{M|-Y`>Ii+`a_M2ip)XwBSL8D5 zK8Lcf)z%+beJ{4q-Z1}JUqh&FY>|AN?Ze~y-&N~*a5g^SRyg6cPqPTLS8>8MrfVn4 z+AC_~wK6?tz2yHm{r4oXOa+EUZ>C-L!q1;)GHjSI^LG1&STmV`K4H(bCfnZ~nXt{f ztkyQFw&rNC%brXA@4qq~ySwSC@OAgU#TD%b5;zlfJV-dXI0hUm8V_m;J!2m|o3l66 z^~l<-^(!hDY=3RR&&UxYbfHyz$Ait^xi+8MJnNj#^xB!a*UY*e%8I*gTQ_^dyC+L` z7hVZxoO|9)Ij`!ZfbaMB7k_47yKxgV%=~u#VQUt);0K%jf96k14KM?zw)jj&2RnNnQ>;LrA ze%?OaZIQrdaM8kE-1`fcsk!coV`^vYIPYC{U~mkRvSA5f1QmFzSYtZh8&3LMoVG9L zQEhsxi`2{h?Fpd={RCtj9!vsv58MkL)Maa&$vGCctLUXi$32CGQQ%C@!Jv0A=JCXL zifWeU^wi{DrYCw{b3ecTrwUVeJj?r+N(~CyvGZ77F@h#UrZVwv_5E{{onPqUntNTT z5AV86tjND!D97aN>(I`8>(BXfyauhU7AiiCEqvPj&TDcN+Ou?TzLnTDZBM=8)#G8) zgfD(>yVahM^?pG|$eMk%Z@)d6+B8RDf(;`}?my#Y zqJ6TUrE}ixH&<1qUx8xXVHc;$zaEe6yB6Ak%vUg2!1Qpz=hiv@-P^c#iz|ou-L%j9 zRrLMy51z(_N(+kX+n&yHeG)XI_vI$X?NTp-9{LFNa$lV_jsKgAS9Y@VQMJ&wF;UyM zd|1}>C-z89fBdoznd#5Ejg^+3pY!qjLs_PmpsklBHCih`yQLbZa9laoA%Dl$Mf7g> zW}S!+i>$fq()Tv3i#pC~e%IY6QEirslgqN~&8}}WlUHtwe01A0X`D$)6qRKXKY zV)xw7OnFnQzQwRa?bb zHi4D^K&Hkz4xh2Pmp%XGuiDMp-&zD$O`Ue_?ZivZ&!x?F+_lZUT4cZ7qjkQ&a{gGo z^6GUmu`c?(OZcDV9%qGM7J-!1QF?`>7v@o1m&xSbgxOv4g8(G{=${ zhyNA&x;wIG8MH@c?7HtfDMB!It>27ou_8Bj$@{TmPwbM<53J&L z9iOpf%hbe1?s%5>Gu1A9eLdS}we2fz@N}7{-~&U^{iZ2ho{(Z!T{Sp`snJnnMOFIE z3M0$!yMlIf!`1=_Uv^SY{2aC4YuEWn&RgvBa^7An&X+xwwr!tJ)_vvoVPeJ?8;>Z? z);sx3`T6}ndh&`piP+P(feb2G2D|VB$(I&+amylb-zY*s^(-9>ip^gvmx5PM?{*Gx@#YTz2;)`L+9M@A?M^ zGf!b^L^OK^8XS&sL@3{$nW6euvG3$l$tnY^@cs0+@)%nrich&Q~7dVl^$RmE{$@2DH&YEh|DH)Q7eJ2jX2wHJ2@TR8X}ty7Je)+|5& ze+pw;-Y=z!^J0uFkvBi7T;v1QFW^ND8Ryx>@07?-)=_yT@O8ufhHotb7q^L-?<;ja z*>+4P<-`xQ(5w2|hJNSl(%#ANKIqD^Df)Nz_=W?n$L!-w7O*q2MA|NRAOfyL92l6I z)gS2Yo>%@{fH>muh{B(GF*5?UHVZaqdhn0 z>p#~maQqVRwPmYm_-^s*iW62cacnaBdUD}Ca9POEs3Y7VQ=g5*e~xYbw183 z_UBq(E)ZR5dRBgql;+yrR7uA$Q}^bl7dm#&OUk<6?k~N(dXlA#ezfJkm*$&RZOq_d z*~O`F;uTv{Kg3K%jwODGNo{eX!p`tbFRx{*B4^xX>&i4*fw$M z+pF8xTVMRDWw&&*!`153$2XX=_k4)hKW|!wy}5a9wXK-)N6!!Qo-%Q4+VqEUF=U%C zLt}|x$DZg&oip7Xp4DsJx}2w2$XpQZV%6Du>Di52i_hlo?PC?Z^z`J{y>eIcL+|Cb zmK%IN;az@m)`=fm{o{W1D08IjXJ}gUrv6xlA|!$mF0g>tFZ`MFyHoQ_&atl{f{H84 zA=BEz-j&}~rbs>yldXPa?egq7-^B0Vm%a;i3)5Pa7r)!sII1DaNud(7?kv4?4k%}X zX3G^8dBj?r_&I-WrYzUyr`3N#p9&Qox#eaS^Lo?nt-rQ?T`s)-p~YsFk{{2f2$ugn zrMT`x_PWEiYjbA@)*f$r3@QN=G&mJbNO}27=YpGsj2t`*4$OMo@1M2!fRft0<1Vdz z?=q)uXlwnJV{kHWr^fA7?_$a;7*;o}307IaJ$**g13e|apRQTwmzc!QiH-erMiShd zzQQ7q!n;+y?;Cg~nSo`J#)dU@H(%7KFZjIX(6lo%j#!4xJ=!57funDv5oB2)f8CMU^up7fl|Oom zZwAcx5ybD7ROj@~g!Ae)=t2>-xWk3dxYt<4S)Ntg+}z2v#dKHu%#CGFCzr3Ow)z}> zy_j2VN~^o5#{<5?r5A+6|M)AEzXlyTvGe(ro2A>TZ=bIfxnBp`(j2?iCofw7wj#qh z=D~-DhqvV3Hk)OdEp~Q}<>v6-wl=m^>((s`&~WJ%(_M62uDZvqPsX#~{$IuV?<#Q_ zSy_t?9XfO**weP|*URNEudEFI@~B%s&MjzpUpg1!f*4z;rYh;1*KR2AM2C# zzP!wLaTC+~_eTGX?isr{g!es`5f)n(`A`0OXQ=ohHNl&TdAF~h{_Z&;k^S?@(TJLU9{wY1h5O}iht8go*v(kP6%&3;%2``>QIp_v z`-|V=iYJuL?5}!K5L|LyE&p`W>e%<^#AgKtI`OeC{%!8QJO1_Q^u71lQo0nSl6lQ7 zbiS7E&gOglGi=i4&Rl*r&)aers+-elsiGibur($`_D z)~;Rp^Yim+*Ejd}&hF~!S|^n<*Rr^6-`}_Smk+ga?|ral|JT>qznauVFg`(3*~ufa>!_IhycnBDWx zv+7>zt&E~a)w`B^9(xWtE+IK4&QnR-^M|j}E?tW|KXoS_$+6kc)=@XHr|90j(8b(a zY-DEz+s&FGx9^>eDTC=J=d^iCD?6vk-qE_U4RW%EXJuPE{#=?(4k#U#NW^|5;6b0nWX9S3e6||910f z_el%ge^0Kjzm%mQ&lB`;W?;#(h1<-o&9Az40tukZh7svE!W4!21C|KIn^clPnWR9?_6d86shPQKX&!qYR(-cV@^b6Iyo*zNiK zEn9N?6B?VpR8}yD2>7&Ipb6Pp%w@vV3h3 z`~QD|u4VZb3s>jjQ~%|S`xn)2ui4$FRA|5c-F4}_4fo&ae)zD*^PSNtipSuERetw{oBVV4tpAtye(A%0;Zuj)KixfGsPuBpWYNsBT{UMX&A9zl z{(eA4-3tq~pers*d0nnwQ7-?x)x(cZ&GM##IJlnqz^bKnE8OtjzS`aOt4{xx&fnu` z6=NX7S3YmPb$MR;fvc699zS?VIzAx1!lOK6gVTW%X7ZR$T5k_Z6?JP2r;F z`pLVu%g+y1UU0hLwax71_ab+CbG7Z2Pk3Hwf8bO0gI5z2C-z>uwLZ*0;``NAx3Al_ zGn~GD^4@pQvgGGYckciCFV}WgM1k)@eb)s+XB)jQYmZJZ^?n{1ea=OiJxX0+h3_h0Y-x$fso zwu)mHF1`DFx@5*u)r<2S_N)V)t#iGhEgDqW#CSS9mwEX|YwqmO(9qJzAXzO54we;r z_U!q5>-xTLrkCP2OpmKNX}vw+Ak+KJbr<5+B^bP5RsZ_+?d2G`+Ao1!E=qCv7yavh z1>f3HxVSvuv-A4P2TvDfn#%8uZ?>q-%%5~_@ukGNsx|s^<(D4jFFg^j^~|eR>Z+aV zVg387S^lM8U{QJ>CdR#a9p8=%igKEKfseQv*9GV#yqs!w{FoIR3v!#9Ukul@9>WcvLI z+w1pEAF|2`-M{tKCS8W;-Oe3*6xaQ;wUT+;Ce8d^dfG>ol4(q7yY1P%E`#@O{4}hd zAGf`2w#=f8yYJ5G|Nb8Ta<7IAU){Son@@1`Zs#+X-d4S6_qIKSORFc9_VS*8Y_{B| z=+1wIMFoKtf0pFmjFxyws6>}+pgPSNzz@4vVB;7Yse()PLU{B(>> zHb1hP?X0@&>Yu6w&zOFFef3h-G0b1fg1ymEOyX~Ap}oqqc2|!7^0H6TCr13a7an)| z=kfYK$BzWt%4It&*&8BtCu6~6i60sLSNdeF_cVAmYyDqp>m^n3Q~z!1rD{`wiwqw2 z_J2MczIRCQ_4W1N#jedTIXU~)gQXYeZG5*k_E+S2bMyFF(`}QF@#x3%UU;|bwcf8E zkNfxTOgwM@e~);A>bbR_UQasny~4)tc>nhQy34u~mi)SU>sHm_?Dc!EmC7UwX(z6& zExENNGki|@r~Lol^3NM=Hb1V^=~|w4b-L9X%N@U`%d^|>djDp_f4z>G5qZzgaoZ zy-ch7*H?6Pg#Y@P;lC_%^3QskFP+|PVzm+{ZWnLP{cFj2R-da~{`3D8`g3PQ0zt^&?aL&nv*SpSHZkFoU_fj<_PiUHH+u4Ze zCssSpx%14%=yONq8qv-StIKZfM?L1u6!)7MZFkFH?Zr5qz0-ai-&^-hY|@Fs*K4+( zKdyJ<)dPccuASc^Uhes{@*Wd^s&|*>vwz2o*8aJ0^7p~zcdz~Kto;Av=F`*t?^f@8 zw5rqUP2La7V0ES6$>MKrCGI>Iu5w`iOq=YFzZU=A9#Wkvwcx+z-0-^XJ3`hsx@3HN z)SPqXOZ55KnY=FHeIezx?TFSD_ASqHE9 zD+iy$Hm9OGB`@23KhJ$C{eSBGh|b{IpIKN{J=WcIExyNpIqp~5xw9fAYb9SxL@6KY zU3l}Us@3!}g6k$Y#2kNn{>55e=F)$c^1n1{G5&O7VEQYTFzxFRnJ2I1Kiz%5snGd7 z)5dAjy7$Jvt#S?LxuTH${M_8wrZu+J-zpsY?U!tL9UE((*|6mE`gi+&zdOg>_jm$Z zq*OwtZC}dlLivtKZ2E6s{hlcgi607G95#23IR5+q+i~5>6G_1u00`ENvysg#An}3+Q zro-`~a##*ik!V29#Y=KI!HnM8UM&oqH?#ZROKRUtR9A^9KasoU`Nh)N+2;)Fv(q;o zlQPeKni@TI&9A&;k}}gp{(8LlV9gNc#P+i3=DUWC&C9>f-Ftcdw5O5tkL*2TZ}M5x zXv)Mr_sy5=cxAWYaoWN;uR?Y79xUE|Ab@|{o~Msf<9IH()$h9QKTSjX(Xz0aSKqxW z=_|5VIaXlLVV;-1WDdjO_wutMb98P0M<#t} zo$yFq|A)ncbqUALO}O+}ep0FO&j-n;7a!$Hn|a)#&FbK-OIp`=ivM-qyiCyX-28x( zS+9T9u|KQL<|>k3=@j?I|NI&Awq;-UynZLXO|NQYn{{&Rc2(8fHy_vWPv!NW;WaHb zMbYEDS8$OJpG5Nv&n>rwwIbUzzASy+63KK}w|47Oy&Bu^XRjzeZu;=?)PeH{w#_1Cl+HA}d)%&`p*Z4R8=_zNH-xVx*HZ4>}w>$UolE?>B z9$j|&OFd4KP2@VXfL7&@{Q#h8>6bZcQ&g@H6$kL(S1j({rZnvdKMm`pOlHm*vcuH7i@X5?#(VP&*&%ycFBT>H4@%O?)LTXnj1D>;bYT|w$dkyFKg8tpOWl-LpyKP zImeLu{u|FMS(0x1M8f9%vbS{#KN}|V98YT(S#x2_b&)4~3NCk?*`6Fz$8aD+$*WAp zW^&Deo%)p@?r!(A57qw>tJ{9G)Ae%vn%D0V%;r_b-Z>RBfA@Fq_?)fP3dZ8XS4%8; zdZnYPPnzqn?bvo{mzY)F%rXnMeP!;=fBlzzIAO|`R{G-Btn7IK#s6>2JHGqO+ig{@ zed)cA!majqF5In>`j^48ZR5+UbAB=BcP3{){$-9~;m^!kVZZx-W6s~$EiZg@ za{T*G+a&+|T&^yC-k{~+EvcLHCXO!e1rf`ROcDv&<#%PW zM&!h}BYy*u4jnnAa+Ck*{#$u%6D5L^E*+U9zOSQ5^WC)G#DiQXFK)}dEwumseY-99 zC0^go+wIHMDI4#j({#w^p2g1MIgck>tmbK2X?;|+STOoYsLa2ln|oK@JYM6atZ}?^ zmsK=h{@$-*^H)iV_0{$(W+1zt5hx<%iuzyc*Xw}!> zM{^B-W~ZxgY<9i5De#*m!~Jyc+7k?Yr;jRHuF}y94}Bkg?ZYiaui#S~bXM+EEsRcj zYx(fL`1`UB%ePz!zkkZ!Wb?fY?g(S5f4x;B>e=2t^_Wz#6Tw2Cbfo^;9^6-X((zUjkFSSD`Q|^)#^Hel z*FPumS_f|bv|GqE+)3jX|7jhbt*NK&47v`knC`zKH+fCy$t<2%R?CC}nASEOI5AP# zu<((KK4Y6kZ?$gDpB4LeQ)P^^?S)qyDf#o%^q=fk zT-C!mtwsIVrIz8*EBP{JO%I%q;qbBY9jCm8(B#s(4S%LGizlI z%g?%SpD8r*#G;k=%HspqEz*6a+~Jb+C;j55m_mDP6}!&r^((h<7|#4-db%j>+O++O z-#O>FJ~df%rgXLF!5b`-xxL>@Iw!@h2|rmB6BYf^B&RRcC(9vmZ}pUkAMbX1&-v(b z!k~>!iHkY-((!X~!5@lFoc(0M`J&)LyM^ZUqtRjee|@s-Uu)&JAlN40J^x#g_1Dw9 z95^)?RRj1L15J*Y`U%DU`E`B&w<)@Td9PN_4fQuyx77(-yla~N{y&?JC9VuqE!|dB zRMZ#z<OXW2Bq`5K(RFhlC>f`RW52EzEU;M6HGj_gY2B%-ZVBn!WY+(8i$|L+ z>&lr45o`ZB8*g`56F6z@xuoTfJ!;KM_=|N{%ek8^(iIcDur_7?k-twuk7*jdsyomY z|MJsu1D3-v+pk*e$z|F8w|Vogh8;WlWWakfUpdCAUT?147p$p1`zfYVzB){3;)e6FDIId3ls`n& zYQ9MhS9||#;qFr^^HzV8nf2*kq2qer$cU-Fpb)=shoeW{{$BC%*_Or2mOt>B5wJe{ zucW{3l9bv%ACH^UnNi=>1v2p!W5Yb(4PT{{Fjix5lkC zOd85D2Pc`_*8AwStwvq`&fl|d;*5{4Y`SXm?(NPgMM)2j9C?5A{-0^i^NODEo;?%I zw^MZQX8#2V6O*ltY|O3ROBG(-Jngzrpwg+2k4`>wShnfF*T!vIOs`y%u+o$4*&%#r ztAE|YBQ{EUsb}W6yGVZ8B)7}&T3be2#PLJ@p?SqhJB$<$Uo`q|n#L!U=9wQS`(5>I z(52&cn%AWR^tauJT$|vj#ChT5-)-^xE2NFzPjOM4cP6oE$-Rk{yO#*@TZ`;GoAGZa z>ndTtmU5pn_v{(sf_gp(C*EGf6P>1SYrT1S`ZsvWu?vNf-P(z# zE}V&Pk1(q5N9FF(I;Ytj{$YMFRMMa`Oi_r1FPPtIk&v!5-^nJ!_tF~`&DXIsZv zuHLn;H>)e?A9?%ec2CKP6oK%4OD3(9d~+~od$+ZM{Hll?e{|?Ji)g2Q=UIg8K)px!sVp+RNYPna`GiLWicT^{JIK{ovJuL23 zp?JzIW@mKd0)CH4Ti*Te>x)ufSC^96e&u+VHn-gidBeQUwGX0a?AZNh*5cbg^4?co zzw5oIIWMVX=WpxNQ{;>IZJ4Uo=uS8|t^V=;&fQLn*_a63*ItcOPbwtG4sU@S(hue zs?c+~6_L(<(rO<*r6HvJPVJi;=8sO_ zDGzE-XFb(n-?#F?ziS6u*6-)J_R{X}M5WM^*7vG5G~D6cr{O508T?xX*zd%s`oU#0rl6|Is=wz$Q@PJC5%Hs^^>*`2kFT@5wmzPJ zW%t&ir(PcQ+~RsimQIg*b@kDtZI7O5JZ^tg+u9#r9sNX%RX66`)z#tEU8z4d-nwpj z?cekH^>Ie^|Nf+XHdkF2W54(R@$Gkw*8La0c=4j8olz!>RagRV!xg=xW8Mk-)C&%; zdFlH3{_TJ*3ALp)Zpj<-UKB2^n={2pY0;uTfByLL+Qxam`u}llaK33lSl8@`j5r@N zgT2?!{O%UZS+_mJ^;5^`UriY{jFb9mqy;A}TKh6^&*Q`8kJjycS^tYu^c5D#AG-Bk!Yp5=$JF1Q{qAXp zE6UF_rvGTzXv8O|=ku=a?)0PcYku5(dUstl&w+TxH!TaLC++_Bk6ZZn3B$=Zo-R)C z@pxBuxBlTP=48hku~Lu!^`ak>`Tqs| zna*$LyYI~}rmjPxXMSvCUSjBMB-;1?^8YjT0+SSLYQKtJ|HGo-IayybZae4t7ZH>H z^vlYxn_PB$u6m5d^W8fx3 zYZSHJXz!Q5_3wBezqxAp`>jmVZa4mLe^S8a{*c{Z%jW~(?`);(=fBppv(MwdBT{1pE2HOPLNee?5ke!h}77pon8 zCOm#xCGpRYg|JVxwrY^s^4xc-Lb@EmWS1cOraZlDvLkzn%}wb#JG&@ z-uzq4ZEk|qFIV&zKb*LP#je|Y&BH&3E|unAoBs2y$;XV(VGatv|E}b3IAgq!MO^0^ z+p~+8kDp~Y1zQVHeV%9Ofjm}`k}j_W4>?!tPB?6QO>jzsPyiDs2TyTW@Zq4Jh`8}7 zuWPzS^Q?ukYPqIXNH%<4v8Co@^2%cWs5@VlG-ox3IXkRbbl-bN<-Q~DTh-29dzY3_ z@SrU+>Ei`gPK`zmp#W9wCWEcostZ`aMlW|(2$&(5{aAljY?5S$VZa*ht$%;)6;E{j z*$^x6;_s8b%P-?^YcVPcXv~@7!fEKu_=Q_AF+o>;m4x7h8+!$WVznDPKxQto*lG+j zQ(fJl_VE+DCoa8-hYI9Z7`c|rxaxI>QTBo8x($`BPhW?xwtjGOW>)tu&W_ibjI41z zfu+Ldv~70e&H1-(RpW~`p$-ei&`nBxA=V)vuWK->7T7eNlvXeAE3Qdq=-g~{+-O&; zd8%GgfZf!(txrBy8SQB`zn-gFpu}`@w!AFUqCWvu^`39}xAFV#PYm1a`LAfv&zF{} z7p8Eom~?f@`@U1lAbvkPtKm7HMEOMnc|~Ry=2x?L4!>hj{C^^FcfvQ{&8sgPT)!ID zuh|%^I$>|=tCFNoMpsXnPI_?2wCsnlZF=R=djGBRxyxCm9GEE>p!)jEj+dd3=IsKO zSE>Rx436e6nq$Z#^^Upkw1=kt9ZZ1E z$?z`L_m#TVrt8;)HeB?aXUz0yl9yiyBgfuV?5S~E_ka1&QMvN7*Q)-l3wZx`6x!xo zxW~2Z!Suk3`rD2^ta$vZW_H}!k6G5H$5(m@J}T4jzqP@nJiT~IeCj%t1zyws34v1x zDDf#acD4!&-#&hvpV@H}bJfh-Ct6mAF>Joe=XOs~I>u=E_c>|5AC#DA4qe!%YZmd6>9 z1(7)+B{`LAq;oP<6;*XVGw!&S-(XZ!@cie&#j%d(<|=&q`XRmKX4sVLI-;lj@_w>0 z?fUs%qB{8EYyJGp4fczwtlm95?~yb8#c7ka-O$~cY zZfA7#>(@q|JazBO3yJI(<_qsHn*M-k#)P}oX?f0fs{;$p1eUWk*syG55L?=@>2T6* zt9rKGOAQ@uSQZ@AF-$txls#Xwyx=P1kvDH8bnd6s?BSc{W`1Rk^3D7rH@BQiaVk@% zE?lzB$iw2_Oret-{jW^dILG<)U0T{b-s5-r74FO2zP9IjwTs*Pv)-S-&3h4L8$P)~ zE7G*`#XLx%pwVc>>2ud+YqiNmiKHI2Whx(8dDdsD>TmO@XrA#oZ2G$D%?sDCmvSv< zk5*+2{PCC5{C|@}u+x6mw0ox=zpp#sySZD6%ggK5jhB7SjN9e}hD_M4kTd74=F7<6 zGR@C#7TtKrc7x|uV9JT@iJ5*L6RW-4UK$%bmWsR{79-`*wE30M&Lh{`9|cIrWmeI#46lhi+4Det)=z;M(qCjJcUCq0+_C@pvY#Q3;%;FE*HW;*}CzWzFzs}ogTM~2K>p_gb1QqR+vs|6GIeXI^pK9p-Jo%<=-TJh* z%`Q(iKlpRu#@6fCisTy3Jv<)V-Ya|T8V^I^8r55sM_7uT-=)v%j+$A$Tl9K#_YKq2 z#q+=NpOoS}%*?=bXzR{}H&pyja^K39+-5wZ=HC~emA33Z&bV{j%GUn zZ~8L6Z0T`1?tb+5ch>Oj+3$PWojuzZojJ3%JMPwV_XF*UyW0;Qcz^bK(Z_{m`^2Bj z>Cn=N$*#6EFlei4c@|JJZ@0?N?DQoXE5u&NNEsgq6iO;7IqfdFpuhagr(2I)c5kp) zZ`A3Rd-I>~#rI`vG|ro_*&eu2e&YE#UPJz`k=1WEYz`Fq7cKA0@?qI^^@X3W$M5vc z+J5z~uyBCt>mxN^)<6>c79pm~=DzP-)v|bm-+gJcs=Um%IcjH*5qpJdM$W%k&adx> zmLCZFbT}jF@|igMuVSaS%vkZt{ME_h#!P$D?8^LHQh9{JBZZ%={o1R}<$C4c;<%Sg zowmE4G~~B#z0=wE$$wvlbnu;xi{2cxu=xL4-tgPDMN9S9m;SFb$q=rc%kwcu;?`^b z^RLomryP7*d+dRogp_Vx!@Q}hnuK*NZVDW2da!xgUY~hvKTa@tvT;mER`J^ub@J2l zbUmiR`N|94N2yEXyq@LMFlo)x%7T?Gr<$TK9=m?ra7KdTqqLm?&(b6|8q9bmF5`wC3|#FB{jWxZZYNPv~aaDgT=0zipw4rroM}_XDY6I@oxK*U$uTERfi59o||;r zs`ca3gVvLcjn)abo+w?p+34&X9 z^M7AHzAv#y@`?ZXIpt-KvUBUaezx@8^^CbK@r*WLQ_QPOECO z)iI6T^;ORpHicX`Jio9q^v{($|D286g?F$wo!gwvrFHw)z2lGD zwil0g+&H)W{j0PNwupj@$Gz)AxfYnH+I}|gGu%9Rzlm*EWAD7Bdb+3i*(Ki;1^$rf zY7`H?bX?7Pf#yQPRN35(CvMkoJ-y>B2TSVicKgTaow9Rdb7SwnXQ=sKaWg4z)g;D$ zU(Qq{zwq10BBuK_Y3-ri>o@x9{bf5Ayv$f5BVQ|O;^U)jKi^CIW^%uHIpyM99)F7u zQ){;$Yuy#x45~Z|Ui3lpQVG*M>x4V5hih7R*nZA@z-=5+c{x41`=P@76M?%IC_avk zvdW$tpTbeWsrM+q?wmlVHshoRhi-Kp^f!6sNwc3< zQJa;>ptV^+=+uE5(Z&y(e{T6CWv5)8+hr#1SXA&~;|wKcy|1fou)d6*(66B$rNjR4 zN{v&8>8neLkx3VBD|wwc-k>2J>vVU?l2kvFY1do71wNg{@mypxTiZ#k+8^xcUlkXK zH_z8!6|~{Wj_3Pk*ljx@A*C`+FK|=VX|YKMjoufyJn9lIp0Z}*G=n=VnF=y>%yv;% z4$r?BeN1S&@Ba-xfgzu{rtjUOb7lLw*J=yA!tTa=Spf|U1Exma;6E}?dz3EBwL4Ip z%2i(~w7P*+e;HSKqH|hWc49=S6|axOr1dj?+*qoxYTG%33gzi?zUTdFf6Y;MPk6TA zNXk(+>B5z^iEo!|YCJmk_5tzpEsvj+)ZEZK)&F(oJKoNKq-8?Z7S+5L4ZTelPCv8w zO~>wCipRvfrylWNx};xLHB47+&Rv<>nxz`8*FF_qbACNzE+6wopYZv)r~X_~e4N*M z`16e$@5S`y?l)7l&0dt!WwX9Hf2Dlm?Jnc4+8PGie}(g`*D3DUy2UQ^WL9Q*$n(W4 z;P%^978S>aMoCt2$&?=P-GQ}1c6r`wn09EKIAPrWP3N@VS{?=d{KdDu7Hs5T*=BR8 z*Fl@%Rg^BX@_g^_J=`Xj@~28lcV0Lzby@zv%(w>Kr)p_Ut z*d0%pctj$y-79gTo1;`!73R(#k3LRjdU5Ep zj=0&oT9)QX`fH}2IeuDX=DeGSB~Cs161#ujjw3hEIrwQ@JQm4!{gHmS>guESljbe} zMbUy%!3kHciQG?A;gCG?;`!NoS5gk-luLB)3F6b6b2+_Fe0kvJ)_0nX$5cQ3n6`4e z@R_7ln|6hXNo;F;xi|f6j?YPs6O0$mOU!%V{@`Z8_pK9RCe75}xcKuOakXdjBDTlG zF!UFHEtZ`Wp<^XPs_RC6pMwvw8WC1OtiPMwLN{Gj7Lvyz^L-`|I7uzJ={Kwnn<1 zj{kN?Ve)0;^Q*EqrL9kS*l=FvxS&d>J%@YWF8TRa6+T_`oD{?0;nOi~iA>x#SCNvP z$Ctf-rPehq@m^>6?wHbTkGD*Fo&9(7<)~$AKSTOCjniBllEUQfTYbHzZss3-yE9u3$_-n4V8=F6SGwHAQ+O;9#(vWO%> zg)D1Z|D4M+x_(k?{O%XAY4{OOrGj)!Y+a zJzIHqai`nFrx#Ps6zV&F`Z}L8U%-3g1KWJ_Y2BfdnXfakRJ~rieb4hHM_BKc-Okm0 zWU1*H=~MIkr$P_kT_w*$L4FcFc|4M4hXo0opMLa#{>G;}f?jD0 ze%`jI>5iun`^rYqc)6N>3G43jo0X4TJ+nIUX@Q;KeMzqc3SJS?3CsuPKKSrmb?a^o zLGkGpk7e7R8GimWY5kq~oxkH#qwCJEKAQUScf5;hHK&Hn&Y0)2&R1kbZ8|`+g&Lfi z&c?^36XZN^ec#|ZW%A);d$mKXPuZ8e2~sk?vvtRL1G{Z@Jc_4lc>?998?3*R^ln*r zaoKP8p11DT_N33;9^7iIWE1G_RdwyWYG3EtTIQT*QHQRkRP12LGe@ABDN%%uA4ra3d`MJFwtWGy4= zm*v4$A2n^hj7V3`)AqXu7u8fwJNoV1dhN|RpQfBYS3H01>8JiihDu#roFeCg*v~#y zT6x`-kJre>_(svZl<6tm_Zv1oNs!)b8}eJ5XLVkfV1TN3J(t%4PN4wR)tvW4L|2{^ znBc-7B5y3TfJbT7udJA0o3wjO&uZ*K_8CmD`o1IKn(*cGQGkU6a)#Wx`+#` z*mPmd9g$~B(NSiLH2<|dRlUEg-s}=Xd6UOJo@rg)axtgYdToyTyZIB>@3I29DG_>; z&Q!M4T6pP;tUYm4qjyizk*Du2Ull*$*7{jw&V#cCAum5^%gaex^BuL?$+`7*RGjv@ z%B`<04nDl2FR**<;^==H6jh?lMVyayw)qHkY(B7O(~1XA4;n4e$ShpkL=@IJdbE}?7Ok4E)!Gf(3l?#rgrmbcA?wfC?Zy+2MDi-F zS|co?H@`+O&FNp@GgjZ1tLu04?2@%)()Bz!$>~O04eP^e5#n<;|9Y^iddrKiH~*$- zaSI0Te^hqxbar&U*7=407gz7pJtS0Bw&cqz58(?(#3!n)`l|^UlsLk1;og9{ei*+G>*YV(a2!7lq${-Q5pOI3iGG==A8(t3!L= zci!{gSJCH^aq+N0A-}=5t6>|o)X#oo2tB5_HG|7)=P`u^USY`r*A1tF`s!W_;+Q6z z`@Ne3YC|TN1l~0*iQwum`m|3^H`YwQG%i(aO;z<3VXp<5LKR7;7w>1ti1M(S){`e% z_CvUK{**`CcDXb#G(WR!tD9_O^LqL-j_1>M=4GyVeB^e9oa(!3ciD<{O@b0$y91a^ zIaW*xWp00`0r6n6z=Vc+>GF#PMFzJb)>kaoKa=pZQ-zb^M8H1pcTI2RZ7w%!n`5<1 zsDp)3)3~99Z$I+{u~+`5xFV9-)4yN6U)JHNaxFXVZ0*JR>StCi7uR+iW8V1WhtB7? z<4d>xshWP=%p^eTyT^%jwI=yYt5Qtg|6YCxJl-?Qv{5oz?p-+JeF>(!FNMoBPl}5# zi>*BPu!aD%WoE?*+z=SaWc%?UM_C;&N?X6a!=Erlh_gI7BtwSYiwLGGVxz4O^ z>ai)#IKS!T%F0wz|5x*bGUl;7S=@B`T#(YISEeU*bSl2RVty@mx#G~XO8?L-)c|?M z&`qzD7axbjlR^^95!nN>60oV`4C zSI_+xqhzlp?uc_-cPxq>H_xBr=fJ7a_?TnGq*56nTj;>#M1==SWBXs;p1;Vajhn~3 z<%ZP028Ngqc1b#E+mjN@=3B;{o#WB7wpOEYnUljmzF)`h|1l9%YfJgWbzzt2%U`qk z1ut$D%BW-sIhj@YJtTbzs4x9Mk^kw%v%f1%kJ~DwOD6xh3V!oU~aF z7Cqvga`T%=e#i3GN2eb3-Dqbxvvywc4Yu81wisS<=i9lCSHeQRb?&vZ9KxW=;ij*{ z&1Xw1tCjC;Eh}eZ2{~!SoKe*YYDhV7GR(710F@DeY{qP1yO^)3DCY(GoM?aAdei*O zt+3B)-f1>&R+^v~9-Tcq#%nb{l8UC91aLukMI+YLE4_2Q~dG^TkbbQ{m;(WgEt3kEYwM{9BzPWs#wv|YRp3Hh# z9`SrRC^|X}8eh&<``*+k#d;`%sr1vE&_p-w>4DD}PB*7~zCLALee~vKu0Pl^%H5%lgREQK!}#=X`6}Dd8|v(fESB#cKbHU2~)i zr(VoGQ^9q~_(Ni$_ss3*oH^(4F@|pPYoE3)6g1qlC5Wl39D!CmpD>*WgbYmRq)@=4Zu-5PoND7)92&7s$fez^C%Zsgj& zoYhKt##Q#)Gu{?HeaFo9g6G&iXS?#e-0c?iQPbqx+8wjrF)l5r@O&$=0o+&TOtRsa zyT@$W_C^g2^EG$cOQokht7<)WR7m{xv7bAy_pRjVQFT3CyeFzwC_627m(;Y$F58sZ ztdkEsb~W?f^4VMX?;B7Dbe2`l8-s13A1mzQ0;0tprd+m{&g@`2@#9+3?exxf-A5}c zQy2a)=T>P9+?H1PZnNggWcSKkRb$o5hYBiJCEuSh`OnLl$xHS-+kJm~t7nh=vVZUA z2pBw15s`I)^zvuPHaaA_<$U|y-#2I9*NfXV?9#*~e_F){ADlGZqal5V$ex<2^^*5% z7k!_szpCl#o4l=DHPcw0D7$1i?RQd-ImmSF)55NMjbf`3I5(X?xB0Y03|BK~G$YAb z;$>g#cA?~@8r%z$AHJ6R*K@=#?`E3w72fq_lI=xjOkKXuy?(G#`^vgE39g(SY!-c- z4HY#`ksr2im=JL;$mmPJ?FE}nu7q9FbT+PMJj~iIQ=V36{avnO^)m0)d7HwnUZ_8Q zBhFAvKFV3ub^Wt{XN>Yyjz3|rxnrb${6I$$Ti~Lk+g9?E9`?pr-`M(O!G-x|VN*OA z{8lnva@w@D@vrKPZ%u-)8H~^IPt*OhJl*c>v|ka&$^_UBE-kkaKXr;vVNb=4b>%#Y zZxecqUru;z=fvk0Uv#0;|D5L^=^3?c28Si8PRyTYDeq98y>gTN;rAVfH0}z{?o-;o zowsXh?$7g<8j`W4nL42QL99|X92D3WTsS=rUU?ZUH`kwY?tjlVG4Hf36JAg5IPFGp;`U7-uYh`km$N-@k6VEMJnO*~q4BQ2P1GI}!1%jSY3j*&gmW)SMm6 zywZRB3l^4nLa7^PID9-AZ>{Y7IlWz7;l-1-Z`tc_mw)o~~7@MVY zx9$;h*?jbu%G-pOn(O18axSjc?~e$c@R^Bg*PoV|<&zAX9~g6Ya}}v~o|*PjQK_r9 zuXI)F&K*Z=d>qzKTK~r4Qo8^zy8Ub=23G5@$}A28VCY+}j&8=AS6`Zw^nG z@pj5f^E0cAZ^yB;tgMLWAE z1@r7Fczj{aInB(O{1Q&`Y9;)q=NB(J{n{q{hu6E^Nv&S8^GsV}c}hb-`>5X0Ss^*)~sycJG2(55+u=AVogYUEB4&xFpJ2!)h55l(d*Icg>&blpheVT@U z(!@nEJ&K1K9(_9~yi8#F67lD|Q}?s(kpG$C^ibRK{IVszbNSj|`K&6|I-rgYIe^W3&uslhS7f-Y@J@)eo3jOXkb<<66OlRdv(L+U=FBTg+1Jc>o>;1(df^F2MWor|#o-MBkp} zppmYVq0K4P(5~}&PeJ*fU3rgw9$f4{+3@g9&@j~5*y!-tmo1-x`Z7g1e9fP`p-B%QI2@_!GB4eg@t}DV~3()@P(~ zG9Kp&ZEv|!+O4?2E3A9xR4YMnRQNJA9%8q?`Qt?*-%K8+uOH9Nn#E_ScRROj;_-H^ zXTKI?K@RrXeOagDE8c{Z z9uB_yVW)Xl_JY!#x6bNaE9~nI-?d=R9{WWr#KS*K-MG;%e$CjQmW26xIo*$595Y$aMB>SXkN+Qdndx%ts6AuVwcJ~h{a<&>m!JE;UW>k0 z9P~-zPTB2T-d}TS{`_@!7Yy`!@&2TD0i(~1d)01xCBH-|)o)~pJ@C{#O8mTpvu#Xv z`s~G90yZ&+T`iD`{gU-AcTvpL{u@(eQZtwA5Hu>jV3aP?^>wfA%r8N0>3=UJ`lLLw ziHJ(zy`R(&=VEf9H21)ceX6SL{qJ(G-@EfpVsie$=su}Cs-|mPI6G70RBp1ycK_yk z!>{M#)8Xed<+u7zU5~2r>svpDZe8xy?Jc*{WTl1S4#Rf=(f5Dm{S1;+|MSnFc;;3c z>nRJ*ug*WZC1Tywp87Yl^c`!gJ0`16UT~ynt9QvU3%;|HecIg}9=lu=>6Th_XM2Z+ zq^Qk{_p*1&g}Vi%?`?atp}Ifi?_|4kuM^BXF7aj?9yZ8b6%?l)a6z(NRQ%nM2j_Qt z)iYR4K6qgN@!hYjrnw(KE?ek+^2W4{t9X9Q?9u)Fk^k(U-92v&MY?4!+dFODa_IT$ z+t1q?qBfo5O_y~A)fpESurR&%e|yj+*+JrMgVjdnmfg&|dW_~Dl@{$g8y&ps-`i{7 zp6+#gnEhOLT0_m259)XRa5K*mnze-cp1WhY%Y$V%;}UOO_;_uDoxEu5T?OxFyPvK* zeLD4=8P|4(8+xXjC+#n=o0P2j@6nGk(X=TdH3f|hqO;e%)ymOqxV~@6i{nQ3bk&W@|Sxp~H^8DeIEzXWe4F=#gY zSyS4ioH+5h=q`g7Q@4oAA6NS|>G18arG?+S^x|zF-Mc5-{M6o@#a>!2LnqhLspR@H zQT?~yL@bYod{tj?Q9o1PE>}2zed)o(MD&MpVF@x#Q8i)46hFHGVv z*`n$#6r-^4uo5#5S7GwD+x;wWAKWxQd+nFAqQ=>j*woZtleboQWQDhO>$*0nda~^{ z^Uexxoqsu3wO|>`l}V+`o_w(ams!dJ93p8)g6_CF-?)&GRN>lmST{^bD0=s7o~MyF zS{vim8sCmoz9S{OiB)jMzEZF7P0Jb@UgeaFRWL7AEkAors_^V5zu=y|LOyoKHy&s0 zJgVlRddTR(tp3?gpM<FO%^$n>+d^>^ix3P7a6+5Ki335wy5n z;`Gi#&wSrod&jzDJ-TeGT5t-y%zvhA=k1pzZz#*LzOw^WYy-99pN-nFfa-X^(cyJU1DFW$+^5uO%4b&Xn0afpfP0+uLq*fJcU z^r?x7yRLchL~yq6?9l!6}@i(hvniOUy**N<}U+nfn3&MRS{JLqj>`1DX9{b&GnUSfVI@Ih1 zMK|0O2vA*p^NyBi2&YElH3x@B4l8nhC#FnbRH~0Ho_1(?!V}q|X6|QSW){zR?Hzml zg`w(&S)3=>ySMFo@jReIuv9ZDuBrRS?D@tn!cKEkxYcuxK2Xn_BivbXcVS-X-42#6 z0ggwd>%WCIU)i5^WaY~Xz7ra>B7HwBTjAm5z`4ba>E`R@_na=8%yK-;X|Zk}H?!)Q zJvZDBwqCBXExmTsI$Az)Zeh0C1c!_JQxtT!#@=`D4wxc)&gs?3nLlp0Do6=fojVh~ z}u=-q!ar3RFB4Sb;j@vQf9fKs*6QCZU-38;sj@(1fwqUPoZ1?d z(?4r6&Sy7X*|Uj*Z+)z0W0>Ou(9*@!V+Hw}uKApfvoFon$TQsVR8X^PH`9W3R}Cb7 z#_UR;^KWmc@I_wL1uW+p8nhzQ8GQA@Yb)kxLe}pb-7fiZ!byc?c9;0Ca&4Pra`6%0 ziFPe9wlChlW-hw+dJ4myoH;$uoi#chJk~hHFXFfBoSMs5l^I7LPD@U+&aHYMY3%&A zbS=1v5zMqIWv-^>UO$jG3c6TS?kTG-e7`nu-AN89o+6HoTlJ?hEl+qN{JH4>@8)e+ z?biPWRbqCGlM5~`HeD0)DX>|i^HK8sR!qRH-qQFnLj5T4|@J?wcSE#F9%MSo`%HFGOspBU6(j;)V*d$ z%>kXi)@vGF%cnF5SyY3($F!`d&wIYBZh@t^n1=t?Arr@>$IO@E&-vJD|4V%MPIcrgR?%d7bngKm8CU zuLWC$XY4C1k}q0x%ph?G|CN)E1)t4QdDp=Afh+vRo&dAW*UtGoU(X^nt3hRYA;VE+{?nGM?YXbIR)N#jLC6t=_)=$^npjQM$VV4ymmwNrfvFro2#$4%mpRD2cSXrQmrXldW8a*bZ0fN zoZ8-d+ry4hoHn>Q6c( z#RiLRk4w^-t}`FBmNHxH;4Y1qhN=r#ltAkSJ%q3Ro6;bZafxMF-n?73vod%L-GqZD z{a|XlzGc#u*DevBXDU~FU*Ee@KgIV~*{T9BhTqBGwkNV5J{;H)tuGuFb-MfPLfg~J zR!8Ss$lVQN@_Ha65TN>6#^IVG$k-TgyF4)FjE47#f)igpELr)Imm}>SQ-R#nY5JT? z&fUGfL+JGjP*&$+Y&*Jchre~pEu#%$IpUlD$+k~;0ZR04N(;QglpC)nPCd}cv0-am z4&%Wob5_iqw|c(A0t4l1$Kp$ND^9Xl?Kr7W=T4Gp_@=G9ZwA;Uh_h7L?_B)v-j^Ps z04CoF4#(n!?d75xAMl>}R_U8?k>&k_t|cr{hK*78i=quV=k5}+XlG%&|2IKBTZ8lI zIafasb;<4&rb#yxIwgW!HXCKy7{!q*@kT9enZjo?o z*uG(DsA%B3N#^yRdumo(0ymxo44GD?xbiG5yK;+jNve-$nM`?yw}-OP-*Ydy4|6^+ z{_NL2F+4DB+Map$f3TWwHuwKqX}O^)?0sbVmmp#Inp;1Inzt*xccmf9j_BWe-f1(c zUZ`NnoBtu;`;7&Xha9A42kXn+xgd19U331^J<591wwU=hw56^7tKE3b%VFx8YgNxn z?+GeSc*uW5?$5P_A03?~+g2E5$GTMI&G0*t+NU#5^F-yVt!A2rT`*P1al`FHAyNW(7d>ZMrr)y1RR^_=jizde}&;^gVlnMu^uFlh|3gMhH z#o^bElZ$l>lpk$mR+qJ8;?>D7=bcyi_s}-(^RAbA93C!F@#={5aNmoGg}0o0k2U`9^Xs3y9#`FxAJrY4MVpqoMV-|e8%^pm-D=j zZq0`*C^$CZsdct?vQzLK#+e`344)UioVWd|?1rCzkA*zC=ICJOBzRNZ@yhb0XJ<&R zej~VRx#p2=+f24u$*W!v;#@K5s?hsY=QJ0wED7@t>8ZRF(UYfjQb)<^pw!$#KY@43 z+HtdXuRr$C_(mmU8uAvWzG%0|4(-6Zj33VIVLkJ+W<^b+!q+#cRtt5if;crAjnxc( zymQ}WSukHE;Fe_hB_6#kJw~0`zJIoyJ+o(#L!_}lq${ZMp9q@X^>|QvBh5iU;KS0l zc7HU4eJ!tR-jJT$$NJv5r<3*ba~&IDOOefH~0mpwtJWDb<5%urUobrCztGb}-_y8#P$tEw1_F6E@ zA$6|y<|#cN!{u{QrKe5!{xv-Jo&DUVxp86+*<2ky-!C6j?KF@{sJw7v52!edo)RTu zGxzn@wL$?*&*wEvS*tKVmeG0n*Y9=jRC5;y9_^i3dF<1<-1K?fEKa;8+;77;H5%DK z6#;YO)x6pIjD^)76(bmCwyaF%cl=khG4Oo6z@-A!s^5)<9 zTuc6~`cks)@-{CAP7}GtFT3U6xlfzEY2lJ%lNV+7=xmH~*M8%_Wnb9k9r9YOLK#{t zKEZ-6PXm~I8y#-_IJw>8OQ{LZujJm&;w`^pTY0AQUB8Hg+my&kpM#rf7JYm8 zTqfZA;*XujukPalEsS#DG?8Vx_qic(1y|TpTg5{S5%RSf|LaWV?p`tpw2tKlC^NjV zUhvpllF8XvUe147nA!0vJzlPf8uu8V@}8dcC*y6Q%F|z8bo%bvDOQq4_fccYmp8lskFEBkCKljvLf!5%Ee$ zp>fVs7AD5{U+)f|KX{=f%<})`879&5w%eqit3Rc>m78b2oB455+o_L^9FJYX4r=$M zv#1<&O?vdu)uqIZGxyxg1-=Oik8gFJE}CDrjk9Bs63FxpmN{-R(d}VOy?zJgn;C9w zKfQk9LV43&24@`@lwK7-Ej2Iye{uc3@8;@l{~SbSHk2!eZHNet`f{my^=w8q(Ll~E zT1=B3Eb_g*`2D1Xb!)R8rCUUrnS59kSNpg;C-(n2$+CshH5pYeFmbFJGgFo$vQ>v=Sw~dN(;w6zOnLMNmjjF zP~INCyX$wn3DIAfSAO?u_=9J0*TdeMA8BLcmD%+B!=knq(Z4}?EK^{D(;Jp3K~L7# zr%vmwGu-LDJ0>Fee@WRSy%!x-D(`8DDBY8!3oB1LCm)wZ>Y$1m)g+8~s%3l#Oc zzPqVrJ20t+%gj38R^?jM@lx10`%m)!54QG4%XgL9zEy0y_v*O!W_ibBALJi(vcI>> zb=9t2Ab&l+_Ge~)^)7J<=fjsbsr~;{vi|ZnP@-mLYHZNAx~0P!cy_&ex?+`6jZB)) zEQZL_LZVL(pYaqfIN7>)Uwq zcJ14ww!9{Bug1%o5?{M-bxQh-Nq38Up3a~9rajIqWy-g=LVNySV*hsh(Dl0hjg!+J z9hCgvYyVznotV=tkNXQ<($9qpGSHmPD)>zb9%GsmJ|O{#p7G1 z*j<0TbI($V&kytsDzAP1@qPMlXWu>9N2C?DoRCLlB|K)t+O^myB z!}IXDW&C?V<;yd7g-`jhXZsty?sRe7`M0?}-&D+4;9utvu9(Lc8{clHddaqgfZs!H*Z7IID{zjd!=NLPnwMaSyz2xZop1;ny_>$r4R@QkLNxi>r+m|Ijw=b*yy-4M6__bJ$-p^qVtM-I$Vf;Tg_NVNM zMM@o(`p=SI&o2w{_noqOVl#V!!~T07Inx{Tzt{Il{{I{O=ke#gS98x*H9tr`{)GSB zj6LbD_vZAb-<@B!fMtrqW`zYeS!W;34N_EgO!#oOzogr!Otd3O`C@#9{PsI{q{U0J z`u${uKK^r`pKw9fT-nU()NTEWYSXfsU;H|i$)anr3lEouC;#sA|JeRD`oi+(rY~yW zZvWUkMf!t%eMJA%)#i`h@Ba7lC>PI*a^_QgVHNsSF68iVjAcH>uJ~x4UOCT;_8;4FZB}2B ze!uRk$TH>Brx};ku2q-){Wy82%%@QxW&rkTE`?uifcD;|+ z_D4oE^vdTQ-~X+))$V$1@B6QBJJ;{C>!^Qovpe&@q1ZIZ#`tsXHs$4Y+t}y-&z}GN zW9Hdo{1<=US}h=dT};~U#=Ebo=WlUal{y^zaC>9cTd^nNYg|t8+7{faye zj6v=fBr5&B{k$8$JG$op-ZT8awP=WG=|Fg--KBceB>*{^hma{-@RN%Ma~cDmO3*mDCwsKV=xffM? zJwVM(b%m9;W^UZEkc;>9=jXkluLHv3`V0@(cifmEp%cCHR`9MPi&Un4|8M-3amlx} zJk$Sv6P@ljuYCWnyGD0zJkDD4|AGI!quvf{Z+=nym;CGh!T5jQB-Q$4ISU=9q(9ho zw*JVwz3~b6|E=Hn{eFCvUW4%Qe;odPJH=&h&2P_Mze-ZQy7s%ag4ntzdiRg?v+*BT zcsTV%b?s7hrz80sf$8k${&aj_Eeje6Q2{moRPwvIL<5-`8{Y5XUL}M9TJFyiv)#UH?`u6H&wH$^{QAS=|3B_1UzeO@{eI34(XLIUCtW?~ zEfSek9{DryO#Gi+%R@YcxGOU=q{XHyysdk&pL2TIK7sFc-*}!q4Xb)}bgSjE$8YZa z&VT>(;ne>>ng8tNtD8ZJ2EagtrW@NM+oOz9&*{|_FoKlsi5{g+3szhmlqzYD(l$?9GB{qR)IpNm#M z^2mSjG55Wt=FPCf_Cjy%3oaDPiiBqb&O35df8E=S=?l(0c5h}oP^x>(w^FEk+W&oS zGHd3De}C)j-dAznqtdU-Nqoli%K{vG>^P^G=@egL<~3_5Tf;KNVKS&=J9($5mWQ*T z#HXJN<2_D&Yel$_w{x$Ef|31$TI~L-dGri{L-c_%c-q^GD(p}emeDkmCF>0EB`_Odw>FQi( zU6+#hs%wXxrB>Cy4d>KoY*UW(g*H+BDW)4O}tthy97Z)Q-RlgOrco8Lw*D`(Z5_uun;ZHnrY=L?P$cCyCDFg%Ua z+!%Ve?uYGrh#J@9iPgJ-@mUopIYhH zmbAyFQTjo>V{)4J-;Hc9qIQGYC!B&8W~@;wF%Fq>Liht$=A@JTHRq34z4>&OyP$6Q zw~E@U)f0X+E%AG+_>rys^r?w61o*F~uDSh7{mYMUPv@nsEO^{L@9L}B&&v;}|Bvoz z+TQ));J5t`ZcmTz;_H0-;Irk9Wzpdg+bT8}FyD*aEjj=1=lG7kE~oSF!WaFXdjHVA z_4|&UI>dXA`^eYpF`e75=QvF{|8dHS?cw=HmWs!B+3tu zfBVB7FRx>(R>PbV`H1oUn@iPoANzV!c`xiOTgfuTp@s8AyPy)6%Z}SpcWbqG8qbh) zm9{?+9xv~(eckkm!c~sfkFv@N@4d0I{>@MEs=DRU|GwRP{^P~ux%b?cpVr$a;QHF$ z;o>s>4-dcXfAH&FxRRNbRPOB~P9mH1_h~sEJasirXN`ut?CtH%Ho~cUZ0G;K-TnI4 zGjpqluTJY9?F!AFI76WQ(cS8e51Z{DKH}crXrFWA)lSiGd!A{P{Jy4oH`)~f%{BuvAJ#(D&o9E5vpDNGi)P9Sre*1oB`Tf1u;`pyzc~S8-`DGM~ z4%10jg=2=-CRt0|-tDR&)EIgF&ZpNE?~+`o1 zrhA5zoot%j?0I<7k*2rTloA9jY?ywQ`i4g{zW!iwbaC726*bRH&5s^s*OU7bHA{@K z+u^^!hRRL9+NZCz?GOmK;B9%0b7Pgnev6d(HqTsm__=K^I$vEPYHqfDM!|=NCwm_s z<2g8e+1&q31&()qZD`SD5^G!`Fd<{X?~5h;?ygJodsQWOsmM?BSn=ratX1tlw(R@; z@c56{=lma^QxZ)5`M_gJ|IfnrXUY-;H*l!PFlOt`C^(VZ-szyQKjmZ2r;VjOU@Yh5v*1UfakIvU!Pu!R|NHD=AI_FH8Mf-l6GCRrOK&-m=!_Z^Pl^mN>z~cDvtHz4#eJYD?+ykW{Pq&08;+N_)o@ISZdn~U$zxU$t z{+@F4!iDuWx9fX!WG?=}cYDIS!phcZD_j*;azxBuv*b{|b-yW7=NChX>ZGzYH~lsC z2K%2g^z3_lcct323m0BLx_kbj-~IXV&#qs%JVj~q)~LhJsck6#siIozUCVj zwRqUCe6#27^ywduUOfJNY1EZck-&K_RcqEo1PPmNv=EqKw>)Q>^o6-X&033Y&02M8 ze);#D`sTWd?6X~M78`^_PqwukxHj>)#o>s=z~g+b9w(%B-~YLA@ryn|-FK%d^q;)i z95{b>_cev)_iBr3%ok*@ogjO4b#LY4FAqz$C#4*lQ((@r*c1P$veD-estxHRk9R3_$^6kF&b6=@^ zrYj3X?mo0wCDX^X<=2NUlbiFG#Wnh;dhQG|@!I+7=$ct~exwz@YrTF?uJgh6hc{0> zcdS_FZTl=YXqo8VyH6u~xU<67WUQ>*_bE4H)6e>(o?M+1PsQ&~TW#{}Xw$T%g3c@) zcBU@>71~5}H9=u`5)_6f^$(QETeE!Y&EBUWXvenk@sAe^U0S%0x@d~J|M_*RYnSiU zsY(J@IO}uSnf>?fT6HO7^3g4RnR6c--4EWp?Ni&VucGU(F0h%<^_b)1kr#*VFI)B0 z|KqGVTYR&%-tk`DEbgw(^s>r~<64(0>wP=Mqlp%LpKS&+t84e-+CKKj!MK!nmWfu|(ShT)l?xfGIJknN6 z)?a-b=Fc3?AYo#yc{zRhnY3rc8_IIFpLC zvgqY=<=0h~{hSui(9!20%5F60sB+YoyFBw;TA~cMuU@(C#gpS^wb%Z1-?$iVpuv8` zj&1LfYftW6pUv=8Ut@2S^_1l%>6MNee^{4#J6b%^x%}=<_~w5fbN~IB6r?dL=|}pT zbt_lJ=v)ux_F5O>QY>LIXMyyBtI8Aics}6OsI_%YooV%;s_^-C_g4xApJ&Z>6HE@$ z+A}S-`rD(;w$;H*GMoj9inoQI*Izxop;l$tob0NViSm&wI!w(hjM^!@lf+YRzL9Ng z%FdhG`f#CZ^82fgKYe-o-Tu&H|InpV8lLig`4W8m(XIMZ?(b#@?_G3czNqgMgQHjd zb$B@yJJT2C+jebO==izJTGIIb%ab-63XWf9nR@j@dF+<0X_bes9J;i7>b3n}?>e{OyvewRK+Pg>M zT^W;BZ!9?eF;{2~)9y<~^DXDyR-5$9)7Ngh!zmYq7a7mg-HNs1h4*?vh`I&ZkFO(@=kiBuA*G1daHRwk=z({EG6mc^gub{wqai&+GdiZ`6lBKE6F}`j+sk zALr%yOEK5Jh-l6hRbJ4LdinX3yzgb%hh}Rns^rPb$;{6d+-(1T<`hX`XNEO_JdYf@ zUz?S!I;*-{Tt4RB7LW>{TsemDrwm{ZjbrGx8d1>^Lq;;y5A>q?o%v1r>k|& zjiIq|RvqWu%+220Cmh3UsPjM4j3=EXXnHIcjjxE&6ciq}-D=lQqhvP6TG(wyX1 zEMKNBIniDgm;288UtvQ`(IM|QrAC4i8n}M1(9~F=-Z+uDm;Gb+D)E9(oi`(D-cI#= zu;9Di{;Ffs3m;A?{&@boP0y)#yLMOAMf_fu7ApKZ8g{}<=+Cz3Zih7j9&4{AtZ_?y zDHF;OWA=VqAw$3awFTvMLH&2DzdxLm@8@aBc>1u*mQ6`qn_qt2Ua(=MWv6v+)}Qh& z@$~;$M=w?NZx6BFZo2#Y68?{-R$QkeK4<+uldaahKZs@iv(M8kuk2hMY?*9o$U6D2 zkS~kCiy-zDY>zi^Hku~Sc5dKK{WWRsQclPo$R{)wmVCj&)~ zv)@wDIH^2o!;FRD6)7_eF3$M#^TjWpc=gUqZib)C!cRSA)1Eu8pKH5Zj%l}F=DcZs z2V*a!6sSMDqPsTt$G0o%)ffM^`&t?FEkl`Q-`8`$Ygfr{_u{F)lM#IgltvB-bi87> zN{qSHr^B>YVL{ug$de@-{{Ogqo~L~Ivy!uoI=f@)tG+WQR~fx~^2E*H`y~GNKfV~x zG1S}g^Ah)_kCjuN9X4S&wnoR!*2TXxIP|D;@bf9X#SYyiQ46x1E|xxbo59C+;KZ89 zXi2Xh(l@o6qeWJp;my{nS|faO+3o7-y(brO9(lMetl`S3TglA#MTPC_6Ej1sg||lj zT6yR17Y4y2Q$7f?#spTc(c}7fFs1C&EXVRL`>+)@Z<-D;e*SxT-CtYI!>U*HE?=(j zGkShfc0SAVlZNW0bJcI(X1?+1dAZ@YBRL%lCZBO`ia)XL_Po8n3;vu)o_wfliISww zztx_MC(5z}B~&u&hJLfi+@AK*jyzu4ji4*ZcT~Q~Ux;92Bwf*Gw z{(q}8?uW1S*{?p64s{2Ax7w-Lx%KrojmRY*72i#xKZKWgsg2=QyaAxrdR-fsKH)WFFi zc%*N;(8|Jp-d^f$O)(`6T7s-czw|SB{;|GSA9>PJ$alm38QM(~PlZbD*DPjxzg%7N z#=ecK9##KcdNsIK@XE1sn$Zsp#7@dAQgS1gt!%={S#6US#jy2H>O6CP>3YG7PHG<)J1oC&UMWFxm)>3# zo3Gc}FZ4aJ4t*c2sZyxomNe}-XT+zR)AP6SdYo8w_owE+&*It2C%;$ie|XjW<5te) z>ZV>{{XAN7BFhXu&9%C&xi4$R>piY6KZDb!|GnV-%$qT)(d3MyRUL;L=uwDU_2oJ){x&+A%K{Kg~QHnex9+&+eh+u|B{1XpdC|H<@owsg4eeVu;+COt-x z()D`GYtN{1Y~g#K`S1;=qwT)-KK50iwrwSQJp|ubzSxm$b@ltoFLEo-iC-`5-;@^@Ez+%Elpf93xtJv$lld9i3->~W37DxOte+#T=w%Pti& zDBjCASCISG`?i@>oa7w3)m7A4_(j zv&Gv7x0;<@bzaLYy2E#Hy{qOaW{vzA-rRp&RgJU5bnoYAZI*NOdfL@+?8t4`8IvA3 zuld?@(sgP2)iql8-|CKvb z;Z#ai-O1R##iwG!r{}MV`?vUm;H(Mf99r%5*;rP$#7>Xh@b68^T*G%y zu83^lValq}YSs95eoxw-Z!hzia>N$SJUnOjUsu)sll{9hf|kdJMYWmOJZJd+gWLO) z$Hm3cVc~Y~^)+f6MDD)P*N|M-Ij`AG&2k3&QFAHB$B{Ctf+J=v?bR3i*-t(T*c{}@OgP$9@yyF>C z{#h=u6x-+GY-76rOWM*84C3$pybaN-4muV2cFy7hr>$BJwXI}L?LN}(D}L?ot@BI$ zv)rbsotaoMe^avk)(u)LPl^5T>~ep1{)_Y0 z|9rYLH+!3RY-QX%LoQSB@kE>T8+6zcge|Akx-Go3_JNXDe7)n#X|q;&ytK5ZY*8?`OndXFV;9YWXC>S+xn+fb+yX{FYXO4$$R`4&GysQh+QG#`|-Ti z?mOLOr;gYw3TQOAN>_QEyl7qiZKZ311ILmlk4hYrJsaKJx_M&`&MNP2W4F^|O;Bp& ztdqewP2Fp?as%oW-Wsw`tD$|7z7!N9zcNB&oOaBfqK5 z%xIbM$l}kTeP(E zj<&#vXZo}LAOE28c5ms;#7P$QQI0PyH?1x`<1s(tS;_0Fg;Q4*^W}C)ZhG>mH{c7K z%s%z)J1Sz|**z}`nzCF{KeuMvr=RzJZ9A{Sw9!rBOKZ33!^IQl`LMa1DB=9Bag0eL z#&F?_UDCF1bJ<>JE}3$E1_SQ__r>}%j4pEtOf%@7YfCTRb1`PFxcD zx2gtA=e?hA_B4xXK z7kGN{H&k#oD$9Rgnj8O$<1XLYLUrT&AO2afY(Dq!eYhjb+=Lxp6Q1hb|Hvn`_g9(A zyB+P{wXe%^FWGm2LvyNC#+M`hDdOMk`ZzZ5TZ(Ly=uIx)J89Yip^5Epe#P7Tm7aLi zbLaQ6E0Zo&x-8!q*0>&p9wwBFO|9z-wZL(m8RHI1bJU83EDGCl=+nzL* z9X+4XdX+`0ZqMy14Mh&;E#DV;_wlgH8vl##v}yMI=?qvDM#{UM6-Po}nBjbnlKFsG-axpdib$Xi~#E zzS~ESUB73QGdCr4!jexbRZ=Xan9b`sm^Yr}j8Q!m`R1ios@@22aZB+Ni{v-d!)83?);ZRk|?jd~q!#z^B9J-juL~ z9(Hk&tLD#~sQcKv_3>l>*M+C|>pCBFyfyub)!!cdU;8ig)Cc9B2}z3! zIyi&X3!^OKDA`K(7s*yZivE8^TbIz#aj!HuK9a>{*}c^Pd6Jb7Uy?`u{2-R{B1tV_#o3JGpfS#Zp8{_Vw2DsH=M zN-Ue9>d!a#accqJn4n!K9qoaHh*WS6R| z=F@D2iJSiIT@=r?JEX}taZkYUb?**X>zq3>y=Jq_3T=s+l`IVjE`JX2>V>a*+6 z3A2*!u|6W|bB620a=%T97lfJWv&t8}@GSMI=I-5*w)OQ6?T-g%hzqtJ-WPVlPj$2C z%~1cPbH9fCH8>I?Df&hE@6VP+udns+ZL#t7iaoVX`(hyf)1%fr0?)-n(+~45^C^tU zny{7cz-@+I0gHGS&9;nSF{}?f8B>XTqS|{odPt#>`nzyE8b*F9~Im-Bo#FdedKpIcdVM}2qa^YtM<=UMEk z_JsdGsMoBe|9z$ZZ1xYeubnj0Snq%IKem0@-1dc%l7@>Vc@?i;t*Ct+|KZR7ykqb7 z{$8XgdU>0U^#nt^Bkp(VBTx1(DA06x{-yoTgoa{MO|Es)mtX8$An19#evzat>j8oN zA)P_5EGky$|MmRm*f~k3bgG+tbLfs|-xuhA$(8MPSOgk^;h7*On=#k7t1bJ3SW#wS zhstB_Nt+qFp8IO-%KNx_^}piX`!}R)ZINkR9qv0nc$b4r!1;OAXICViZG7!$T^!K* zbKy7UJqD9A5?^KsG%agjd{?L_e#NEq-HL^Z8@Af>t(qIH{>@LZv}k{iO&W{X)R?@c zSQW9>d)1Q95RF4v!_40%Asq3x8eu^Y%j3(!As61Ism>a{UFKUf=daVej(go%+*XG^Q4(tL}Sz z_>0Bs+u{$T)BTSe+AZf&{d=M)$7Sw@*IMD@$B7MQoan;p_Puirxn`?|*e(zd1~8W#!Hv(T14N70-p(gF*Q|C=xS5?Gw_d(_8;6Pzqjt(shTLf``_-iQw9LZ7OS<^X z)-L#B#_6opG~>x4ix)4X+jh-Z;nBwF7couyel8{bZFYL!@zd+~JQP*^ znj_Y`w_w7|y$ah?BOZ7iHR%`Web2Gxo;UaJ6G{ao3JQ)a4=lkQBw9zOq&u4;C$AwAN zO?lCc%yz=H-b~I1T<6zL?U80loU>#_U}&-&_xaD}wb%aeXzU9)$a3JvM7Qrh-WD0{ zx4xBo_Vv5++l43I6j{p7552ahXuAI9?n{wH!hZ8(%Qm-n_cSxj_MxV_(w+MUsS%#dO^;y+&xs9;!!aI*1Z9ZnU;`P)=+>vLN&5)A# z6SeuV-J{m(?=LLuwoWx&KVfsYnAPte&Se{!X6>HQe}Zr3{sm7g*}~dhwZ|HK?%Hts z-1K#qPhQ;e`S6vUmml>n4Q`(=>@I)3b>_5dW|P&mU(XPnkTUb6ja#pc+0480``!z$ zmt5MmW3yydob^l1z6#Box~mUAPRo|r%CTY6k;^50i?*=;@cx`FlI)stfMeGe=jGg}XPABehw#3VPo5UZF*#4V8v88ImOs($J`u_t@iHk)?NFhzaBgmPi9Fxu zT&{yhrSuI7b(O9$&idlnmD$RcdsF10{E63oRg$dM+72JKioHE^_Q|{Jy2nmEn{

0rJJ^SHW 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 N;OXk;vd$@?2>{>(k%IsL literal 21984 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ℜ%UbUb|T>L`pwNqPIkD9)o^l=V1 z+wlH&DT2g-N9aQ{5dKUw+osd;^w(4ss0XUn5 z`W2`2ZX2V6#-#5O4L8|0zAR&Ya=tt}-e=k8wV>Li{mA9jHww3J(0)H{*Vf}%Q?#xc zM={2(WZYEn@X)nWr%u^qzb$6)lUlI-EW-qEqwk;d13sO9A82tW_Z3Gj5?Xog-oEMy_s!iSAN&k3dC$22>wP(nH8Vmts z1uBQEoOgNATrb`QhYlU;kB*Ms&;Gztw)gKZ-F7T$@{Efhg#o{WlJaS z`Ly(+w;FFrb@RamkwP;|^E4)Xw{e{}vDtqK!vkL1w^LqO{+;Q+l7)kV;=~W%@1m_uR7^C$7y+6}P*~*1+zu=j;r_ z^}L3X61kc?Kb$dCn&B}~bAt_M)0?=hJwlqiS6ED>Ahx((3JD8~bNiIepjJEgm!8sY z&wFnz&OK^sYI>HEldLhR+`6Iu{qnop8Gf)F(c_q<(81Uc(2}CoAS1!UZphQHU;f_z z()n92cXiAE4^a*T_u48CCR~_4d$#rF%{!h;O57=ylJ?a5Y?J@-&(F`>RV$-aMP}~g zm~flXqFKHB`02VI>1u~tDnU&^udkIcZi_EY_F!W;b1;1RKaaD1ofDo^O*(z~@@4rs z*5!H0T3hQuu`3eE_F#pGy@=QY=ChHR_K`EzyIO&L_Y_-CUiFfJ&-0*4 zmhs8ZV>8^1jEv&ETT5BLFW*!1>%x~gisp_HY~PC31tslKobuX>$u!$!*A!3zy?*Yi zSFg4#Tei%YVNQO}Ot&JgUn@UV=nJV&x}&R@H8!p|IM=flwl6E5&AOWycqyRqAC z+fT_IQxsI+$$ZKUsxwu({of-z`==(zN3XIMFIuG3{zT+>p`YMHO_hFj1Gxhi8ar|) zy;a)e>~c?ar=0B8uDG+OPF1OIJZi>%?$IktNlD#}H`|sm9NF(UX{CVC_X*E94P(AJ z-hJ|%J=$qCsNuJ=E-*HB?!_xtOpZwy-}}5LCizSRLo!2;l4X!f8{-K__tX;h__c+i z%nulEFh2-p*zNhw=va>W&R7>ah7DIg@2SepJ-i|DaM_Yi=gVqW+St^F%#tiJ)X@`p zXvyHFwm|YW!=Hm3^ES-yZcN=34LV6jl!s zUUIMRy-fOX^^Kl(^NXX7C!MrmJW$Bcwpf4OC6O)7H~3Dmab1^w@U>$1n!Q Date: Thu, 15 Feb 2018 14:41:26 +0200 Subject: [PATCH 24/24] Update release notes of 2.2.2 --- Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md index 613e870f7..fe8535a21 100644 --- a/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.2.2-Release-Notes.md @@ -25,6 +25,12 @@ The MaxScale C++ CDC Connector is now distributed as a part of MaxScale. The connector libraries are in a separate package, `maxscale-cdc-connector`. Refer to the [CDC Connector documentation](../Connectors/CDC-Connector.md) for more details. +### Output of `show threads` has changed. + +For each thread is shown what state it is in, how many descriptors are currently +in the thread's epoll instance and how many descriptors in total have been in the +thread's epoll instance. + ## Dropped Features ## New Features