From 890902e33830a896a582f3801f9d627410a6b7e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Fri, 13 Apr 2018 13:12:01 +0300 Subject: [PATCH 1/7] Add maxinfo SQL interface test Added a test for the maxinfo SQL interface. --- maxscale-system-test/CMakeLists.txt | 3 + .../cnf/maxscale.cnf.template.maxinfo_sql | 71 ++++++++++++++++ maxscale-system-test/maxinfo_sql.cpp | 82 +++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 maxscale-system-test/cnf/maxscale.cnf.template.maxinfo_sql create mode 100644 maxscale-system-test/maxinfo_sql.cpp diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index 442a255fc..77ab4cc62 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -381,6 +381,9 @@ add_test_executable(max_connections.cpp max_connections replication LABELS MySQL # Test of Maxinfo interface (http) #add_test_executable(maxinfo.cpp maxinfocpp maxinfo LABELS maxinfo UNSTABLE HEAVY REPL_BACKEND) +# Test of Maxinfo SQL interface +add_test_executable(maxinfo_sql.cpp maxinfo_sql maxinfo_sql LABELS maxinfo REPL_BACKEND) + # Test of Maxinfo interface (http), python impelemntation add_test_script(maxinfo.py maxinfo.py maxinfo LABELS maxinfo LIGHT REPL_BACKEND) diff --git a/maxscale-system-test/cnf/maxscale.cnf.template.maxinfo_sql b/maxscale-system-test/cnf/maxscale.cnf.template.maxinfo_sql new file mode 100644 index 000000000..1def8d09f --- /dev/null +++ b/maxscale-system-test/cnf/maxscale.cnf.template.maxinfo_sql @@ -0,0 +1,71 @@ +[maxscale] +threads=4 + +[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 + +[MySQL Monitor] +type=monitor +module=mysqlmon +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql +monitor_interval=1000 + +[Maxinfo] +type=service +router=maxinfo +user=maxuser +passwd=maxpwd +# Added here to allow users to be fetched from the backend server +servers=server1 + +[Maxinfo-SQL-Listener] +type=listener +service=Maxinfo +protocol=MySQLClient +port=4008 + +[RW Split Router] +type=service +router=readwritesplit +servers=server1,server2,server3,server4 +user=maxskysql +passwd=skysql + +[RW Split Listener] +type=listener +service=RW Split Router +protocol=MySQLClient +port=4006 + +[CLI] +type=service +router=cli + +[CLI-Listener] +type=listener +service=CLI +protocol=maxscaled +socket=default diff --git a/maxscale-system-test/maxinfo_sql.cpp b/maxscale-system-test/maxinfo_sql.cpp new file mode 100644 index 000000000..036544965 --- /dev/null +++ b/maxscale-system-test/maxinfo_sql.cpp @@ -0,0 +1,82 @@ +/** + * Test MaxInfo with the SQL interface + */ + +#include "testconnections.h" +#include +#include +#include +#include + +using namespace std; + +int main(int argc, char** argv) +{ + vector commands( + { + "SET SERVER server1 master", + "CLEAR SERVER server1 master", + "FLUSH LOGS", + "SHOW VARIABLES", + "SHOW VARIABLES LIKE '%version%'", + "SHOW STATUS", + "SHOW SERVICES", + "SHOW LISTENERS", + "SHOW SESSIONS", + "SHOW CLIENTS", + "SHOW SERVERS", + "SHOW MODULES", + "SHOW MONITORS", + "SHOW EVENTTIMES" + }); + + TestConnections test(argc, argv); + vector threads; + atomic run(true); + atomic wait(true); + + // Create some threads so that the SHOW SESSIONS will actually do something + for (int i = 0; i < 25; i++) + { + threads.emplace_back([&]() + { + while (wait) + { + sleep(1); + } + + while (run) + { + MYSQL* conn = test.maxscales->open_rwsplit_connection(); + for (int i = 0; i < 100; i++) + { + mysql_query(conn, "SELECT REPEAT('a', 10000), sleep(0.01) FROM dual"); + } + mysql_close(conn); + } + }); + } + + wait = false; + + MYSQL* conn = test.maxscales->open_readconn_master_connection(); + + for (int i = 0; i < 100; i++) + { + for (auto a : commands) + { + test.try_query(conn, "%s", a.c_str()); + } + } + + mysql_close(conn); + + run = false; + + for (auto& a : threads) + { + a.join(); + } + + return test.global_result; +} From 41626202ed4322c337175446837deaf0a608c2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 16 Apr 2018 08:45:14 +0300 Subject: [PATCH 2/7] MXS-1803: Simplify docker image The docker image now simply installs the latest MaxScale version instead of building it. This significantly reduces the amount of maintenance that the image requires. Updated the configurations to allow runtime definition of servers and updated README.md to reflect the changes in the files. Pointed links to 2.2 instead of develop. Removed text from the readme that was not strictly related to running the MaxScale image. --- docker/Dockerfile | 54 ++---------------- docker/README.md | 85 ++++++++++++----------------- docker/config_extension_example.cnf | 24 +++----- docker/maxscale.cnf | 12 +--- 4 files changed, 51 insertions(+), 124 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 388710437..8855ddeed 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,53 +1,7 @@ -# This Dockerfile builds an image for MariaDB MaxScale: -# https://mariadb.com/products/technology/maxscale -# The example configuration file maxscale.cnf should be in the build directory -# when building the image. - -FROM alpine:latest - -# Packages required for building MaxScale and Avro-C -ARG DEPENDENCIES_PKGS="bash bison cmake curl flex gcc git gnutls gnutls-dev g++ \ -jansson jansson-dev libedit libedit-dev libgcrypt libgcrypt-dev libstdc++ lua \ -lua-dev make ncurses ncurses-dev openssl openssl-dev perl sqlite sqlite-dev \ -sqlite-libs tcl-dev util-linux-dev xz xz-dev" - -# Packages that can be removed after build -ARG REM_PKGS="bison bash cmake flex gcc git gnutls-dev g++ jansson-dev \ -libedit-dev libgcrypt-dev lua-dev make ncurses-dev openssl-dev perl sqlite-dev \ -tcl-dev xz-dev" - -# MaxScale-specific parameters -ARG MS_DIR=/MaxScale_workdir -ARG MS_CMAKE_PARS="-DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RelWithDebInfo \ --DWITH_SCRIPTS=N -DTARGET_COMPONENT=all" -ARG MS_BRANCH=develop -ARG MS_REPO=https://github.com/mariadb-corporation/MaxScale.git - -# Avro-specific parameters -ARG AV_DIR=/Avro_workdir -ARG AV_PREF=avro-c-1.8.2 -ARG AV_ARCH=$AV_PREF.tar.gz -ARG AV_URL=ftp://ftp.funet.fi/pub/mirrors/apache.org/avro/avro-1.8.2/c/$AV_ARCH -ARG AV_CMAKE_PARS="-DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RelWithDebInfo \ --DCMAKE_C_FLAGS=-fPIC -DCMAKE_CXX_FLAGS=-fPIC" - -RUN apk -U add $DEPENDENCIES_PKGS && \ - mkdir $MS_DIR && mkdir $AV_DIR && mkdir $MS_DIR/Build && mkdir $AV_DIR/Build && \ - cd $AV_DIR && \ -# Download Avro-C, build and install - curl --output $AV_ARCH $AV_URL && \ - tar -zxvf $AV_ARCH && cd Build && \ - cmake $AV_CMAKE_PARS ../$AV_PREF && \ - make install && \ - cd $MS_DIR && \ -# Download MaxScale, build and install - git clone --depth 1 --branch $MS_BRANCH $MS_REPO && cd Build && \ - cmake $MS_CMAKE_PARS ../MaxScale && \ - make install && (./postinst || true) && \ -# Remove unneeded packages and work directories - apk del $REM_PKGS && \ - cd / && rm -rf $MS_DIR $AV_DIR +# Dockerfile for the 2.2 GA version of MariaDB MaxScale +FROM centos:7 +RUN curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash && yum -y install maxscale COPY ./maxscale.cnf /etc/ -ENTRYPOINT ["maxscale", "-d"] +ENTRYPOINT ["maxscale", "-d", "-U", "maxscale"] CMD ["-lstdout"] diff --git a/docker/README.md b/docker/README.md index ff3d51972..01f9f38fd 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,60 +1,48 @@ # MariaDB MaxScale Docker image -This Docker image runs MariaDB MaxScale. The MaxScale version used to build the -image is an unreleased development build so this should not be used for a -production system. +This Docker image runs the latest GA version of MariaDB MaxScale. + +## Building + +Run the following command to build the image. + +``` +sudo docker build -t maxscale . +``` ## Usage -MaxScale is a proxy so its configuration is dependent on the use case and there -is no generally valid default. The configuration file inside the image (shown in -[Default configuration](#default-configuration)) includes only the bare minimum -to start MaxScale and has no useful services. The simplest way to add more to -the configuration is to place another file (*my_config.cnf*) in a directory -(*/my_dir/*) and then mount the directory to */etc/maxscale.cnf.d/* inside the -container when starting it. MaxScale will add any files inside -*/etc/maxscale.cnf.d/* to its configuration. +You must mount your configuration file into `/etc/maxscale.cnf.d/`. To do +this, pass it as an argument to the `-v` option: ``` -docker run --network host --rm -v /my_dir:/etc/maxscale.cnf.d/ maxscale +docker run -v $PWD/my-maxscale.cnf:/etc/maxscale.cnf.d/my-maxscale.cnf maxscale:latest ``` -In the examples, the Docker network mode is set to *host* so that the container -has full network access (`--network host`). - -To replace the configuration file completely, start MaxScale with `-f `. -Adding custom options removes all default options defined in the image. When -adding new flags to MaxScale, one should add back `-l stdout` to print log to -stdout. +By default, MaxScale runs with the `-l stdout` arguments. To explicitly +define a configuration file, use the `-f /path/to/maxscale.cnf` argument +and add `-l stdout` after it. ``` -docker run --network host --rm -v /my_dir:/container_dir maxscale -l stdout -f /container_dir/my_config.cnf -``` - -To save logs to */my_dir*, remove the `-l stdout` and set */container_dir* as -log directory with the option `-L /container_dir`. - -``` -docker run --network host --rm -v /my_dir:/container_dir maxscale -L /container_dir -f /container_dir/my_config.cnf +docker run --network host --rm -v /my_dir:/container_dir maxscale -f /path/to/maxscale.cnf -l stdout ``` ## Default configuration ``` # MaxScale documentation on GitHub: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Documentation-Contents.md +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Documentation-Contents.md # Complete list of configuration options: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Getting-Started/Configuration-Guide.md +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Getting-Started/Configuration-Guide.md # Global parameters - [maxscale] -threads=2 +threads=auto # This service enables the use of the MaxAdmin interface # MaxScale administration guide: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Reference/MaxAdmin.md +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Reference/MaxAdmin.md [MaxAdmin-Service] type=service router=cli @@ -66,27 +54,21 @@ protocol=maxscaled socket=default ``` -## Example configuration extension +## Example base configuration ``` -# Server definitions -# Set the address of the server to the network address of a MySQL server. - -[server1] -type=server -address=127.0.0.1 -port=3306 -protocol=MySQLBackend +# Global parameters +[maxscale] +threads=auto # Monitor for the servers # This will keep MaxScale aware of the state of the servers. # MySQL Monitor documentation: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Monitors/MySQL-Monitor.md +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Monitors/MariaDB-Monitor.md -[MySQL-Monitor] +[MariaDB-Monitor] type=monitor -module=mysqlmon -servers=server1 +module=mariadbmon user=myuser passwd=mypwd monitor_interval=1000 @@ -95,23 +77,21 @@ monitor_interval=1000 # Service Definition for a read-only service and a read/write splitting service. # ReadConnRoute documentation: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Routers/ReadConnRoute.md +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Routers/ReadConnRoute.md [Read-Only-Service] type=service router=readconnroute -servers=server1 user=myuser passwd=mypwd router_options=slave # ReadWriteSplit documentation: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Routers/ReadWriteSplit.md +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Routers/ReadWriteSplit.md [Read-Write-Service] type=service router=readwritesplit -servers=server1 user=myuser passwd=mypwd max_slave_connections=100% @@ -131,3 +111,10 @@ service=Read-Write-Service protocol=MySQLClient port=4006 ``` + +For base configurations, servers are defined at runtime. Run the following +command to create a server and link it into all services and monitors. + +``` +maxctrl create server --monitors MariaDB-Monitor --services Read-Only-Service Read-Write-Service +``` diff --git a/docker/config_extension_example.cnf b/docker/config_extension_example.cnf index da707dc9c..ee12f9581 100644 --- a/docker/config_extension_example.cnf +++ b/docker/config_extension_example.cnf @@ -1,21 +1,15 @@ -# Server definitions -# Set the address of the server to the network address of a MySQL server. - -[server1] -type=server -address=127.0.0.1 -port=3306 -protocol=MySQLBackend +# Global parameters +[maxscale] +threads=auto # Monitor for the servers # This will keep MaxScale aware of the state of the servers. # MySQL Monitor documentation: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Monitors/MySQL-Monitor.md +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Monitors/MariaDB-Monitor.md -[MySQL-Monitor] +[MariaDB-Monitor] type=monitor -module=mysqlmon -servers=server1 +module=mariadbmon user=myuser passwd=mypwd monitor_interval=1000 @@ -24,23 +18,21 @@ monitor_interval=1000 # Service Definition for a read-only service and a read/write splitting service. # ReadConnRoute documentation: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Routers/ReadConnRoute.md +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Routers/ReadConnRoute.md [Read-Only-Service] type=service router=readconnroute -servers=server1 user=myuser passwd=mypwd router_options=slave # ReadWriteSplit documentation: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Routers/ReadWriteSplit.md +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Routers/ReadWriteSplit.md [Read-Write-Service] type=service router=readwritesplit -servers=server1 user=myuser passwd=mypwd max_slave_connections=100% diff --git a/docker/maxscale.cnf b/docker/maxscale.cnf index 9f7942abd..b0141f6a9 100644 --- a/docker/maxscale.cnf +++ b/docker/maxscale.cnf @@ -1,18 +1,12 @@ # MaxScale documentation on GitHub: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Documentation-Contents.md +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Documentation-Contents.md # Complete list of configuration options: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Getting-Started/Configuration-Guide.md - -# Global parameters - -[maxscale] -threads=2 +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Getting-Started/Configuration-Guide.md # This service enables the use of the MaxAdmin interface # MaxScale administration guide: -# https://github.com/mariadb-corporation/MaxScale/blob/develop/Documentation/Reference/MaxAdmin.md - +# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Reference/MaxAdmin.md [MaxAdmin-Service] type=service router=cli From 5855b307bd428be7b5d8d31eb8217e6329463c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 16 Apr 2018 09:54:40 +0300 Subject: [PATCH 3/7] Add raw REST API calls to MaxCtrl Being able to perform raw REST API calls that leverage the value extraction capabilities of Node.js gives more control to the end user. It also doubles as a handy tool for creating scripts that only require one particular value from the REST API. --- maxctrl/lib/api.js | 42 ++++++++++++++++++++++++++++++++++++++++++ maxctrl/lib/core.js | 1 + 2 files changed, 43 insertions(+) create mode 100644 maxctrl/lib/api.js diff --git a/maxctrl/lib/api.js b/maxctrl/lib/api.js new file mode 100644 index 000000000..716924110 --- /dev/null +++ b/maxctrl/lib/api.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016 MariaDB Corporation Ab + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file and at www.mariadb.com/bsl11. + * + * Change Date: 2020-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2 or later of the General + * Public License. + */ +require('./common.js')() + +exports.command = 'api ' +exports.desc = 'Raw REST API access' +exports.handler = function() {} +exports.builder = function(yargs) { + yargs + .command('get [path]', 'Get raw JSON', function(yargs) { + return yargs.epilog('Perform a raw REST API call. ' + + 'The path definition uses JavaScript syntax to extract values.') + .usage('Usage: get [path]') + }, function(argv) { + maxctrl(argv, function(host) { + return doRequest(host, argv.resource, (res) => { + if (argv.path) { + res = _.getPath(res, argv.path, '') + } + + return JSON.stringify(res) + }) + }) + }) + .usage('Usage: api ') + .help() + .command('*', 'the default command', {}, function(argv) { + maxctrl(argv, function(host) { + return error('Unknown command. See output of `help api` for a list of commands.') + }) + }) +} diff --git a/maxctrl/lib/core.js b/maxctrl/lib/core.js index c3bd62a1a..74868a16f 100644 --- a/maxctrl/lib/core.js +++ b/maxctrl/lib/core.js @@ -100,6 +100,7 @@ program .command(require('./rotate.js')) .command(require('./call.js')) .command(require('./cluster.js')) + .command(require('./api.js')) .help() .demandCommand(1, 'At least one command is required') .command('*', 'the default command', {}, function(argv) { From 957f9865d69b7bc9eed087c8fdec0d501417caf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 16 Apr 2018 10:04:39 +0300 Subject: [PATCH 4/7] Update MaxCtrl documentation Updated MaxCtrl documentation. --- Documentation/Reference/MaxCtrl.md | 23 ++++++++++++++++++++++- maxctrl/lib/api.js | 4 +++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Documentation/Reference/MaxCtrl.md b/Documentation/Reference/MaxCtrl.md index d5effed0d..4b602e466 100644 --- a/Documentation/Reference/MaxCtrl.md +++ b/Documentation/Reference/MaxCtrl.md @@ -32,6 +32,7 @@ For more information about the MaxScale REST API, refer to the * [rotate](#rotate) * [call](#call) * [cluster](#cluster) +* [api](#api) ## Options @@ -39,7 +40,9 @@ All command accept the following global options. ``` -u, --user Username to use [string] [default: "admin"] - -p, --password Password for the user [string] [default: "mariadb"] + -p, --password Password for the user. To input the password manually, give -p + as the last argument or use --password='' + [string] [default: "mariadb"] -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"] @@ -664,3 +667,21 @@ due to a network failure or some other ephemeral error. Any other errors require manual synchronization of the MaxScale configuration files and a restart of the failed Maxscale. +## api + +``` +Usage: api + +Commands: + get [path] Get raw JSON + +``` + +### api get + +`Usage: get [path]` + +Perform a raw REST API call. The path definition uses JavaScript syntax to +extract values. For example, the following command extracts all server states as +an array of JSON values: maxctrl api get servers data[].attributes.state + diff --git a/maxctrl/lib/api.js b/maxctrl/lib/api.js index 716924110..835e43057 100644 --- a/maxctrl/lib/api.js +++ b/maxctrl/lib/api.js @@ -19,7 +19,9 @@ exports.builder = function(yargs) { yargs .command('get [path]', 'Get raw JSON', function(yargs) { return yargs.epilog('Perform a raw REST API call. ' + - 'The path definition uses JavaScript syntax to extract values.') + 'The path definition uses JavaScript syntax to extract values. ' + + 'For example, the following command extracts all server states ' + + 'as an array of JSON values: maxctrl api get servers data[].attributes.state') .usage('Usage: get [path]') }, function(argv) { maxctrl(argv, function(host) { From ff7f06cd6649d32c207e0a032a3009d934a91a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 16 Apr 2018 10:07:55 +0300 Subject: [PATCH 5/7] Add 2.2.5 release notes Added the release notes for MaxScale 2.2.5. --- .../MaxScale-2.2.5-Release-Notes.md | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Documentation/Release-Notes/MaxScale-2.2.5-Release-Notes.md diff --git a/Documentation/Release-Notes/MaxScale-2.2.5-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.2.5-Release-Notes.md new file mode 100644 index 000000000..b13f160d6 --- /dev/null +++ b/Documentation/Release-Notes/MaxScale-2.2.5-Release-Notes.md @@ -0,0 +1,63 @@ +# MariaDB MaxScale 2.2.5 Release Notes + +Release 2.2.5 is a GA release. + +This document describes the changes in release 2.2.5, when compared to +release 2.2.4. + +For any problems you encounter, please consider submitting a bug +report at [Jira](https://jira.mariadb.org). + +## Changed Features + +## Dropped Features + +## New Features + +### MaxCtrl: Raw REST API Calls + +MaxCtrl is now able to perform raw HTTP GET calls that return the JSON +data from the REST API. It also supports value extraction with JavaScript +style syntax. + +For example, extracting just the state of all servers as a JSON array can be +done with the following command: + +``` +[markusjm@localhost ~]$ maxctrl api get servers data[].attributes.state +["Master, Running","Slave, Running","Slave, Running","Slave, Running"] +``` + +## Bug fixes + +* [MXS-1787](https://jira.mariadb.org/browse/MXS-1787) Crash with mysql client test `test_bug49972` +* [MXS-1786](https://jira.mariadb.org/browse/MXS-1786) Hang with COM_STATISTICS +* [MXS-1785](https://jira.mariadb.org/browse/MXS-1785) request 16M-1 normal sql + 'select 1' core dump with debug mode +* [MXS-1776](https://jira.mariadb.org/browse/MXS-1776) Hang with mysql test case `test_basic_cursors` +* [MXS-1773](https://jira.mariadb.org/browse/MXS-1773) LOAD DATA LOCAL INFILE confuses readwritesplit +* [MXS-1765](https://jira.mariadb.org/browse/MXS-1765) Internal client connections write data in wrong order +* [MXS-1757](https://jira.mariadb.org/browse/MXS-1757) Problem while linking libavrorouter.so on Ubuntu 14.04 +* [MXS-1751](https://jira.mariadb.org/browse/MXS-1751) Maxscale crashes when certain config is in play (with nodes down) +* [MXS-1747](https://jira.mariadb.org/browse/MXS-1747) Rejoin functions should print better errors +* [MXS-1746](https://jira.mariadb.org/browse/MXS-1746) The session-specific gtid_domain_id is queried instead of the global one +* [MXS-1743](https://jira.mariadb.org/browse/MXS-1743) Maxscale unable to enforce round-robin between read service for Slave + +## Known Issues and Limitations + +There are some limitations and known issues within this version of MaxScale. +For more information, please refer to the [Limitations](../About/Limitations.md) document. + +## Packaging + +RPM and Debian packages are provided for the Linux distributions supported +by MariaDB Enterprise. + +Packages can be downloaded [here](https://mariadb.com/downloads/mariadb-tx/maxscale). + +## Source Code + +The source code of MaxScale is tagged at GitHub with a tag, which is identical +with the version of MaxScale. For instance, the tag of version X.Y.Z of MaxScale +is X.Y.Z. Further, *master* always refers to the latest released non-beta version. + +The source code is available [here](https://github.com/mariadb-corporation/MaxScale). From 0adb4b6ffa219bb0239281afc0f43e241c8d051b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 16 Apr 2018 14:58:22 +0300 Subject: [PATCH 6/7] Add basic docker-compose setup The setup contains a three node master-slave cluster with both readwritesplit and readconnroute. Removed the duplication of the configuration files in the README and provided links instead. --- docker/README.md | 102 ++++-------------- docker/docker-compose.yml | 34 ++++++ .../example.cnf} | 36 +++++-- docker/sql/master/users.sql | 10 ++ docker/sql/slave/replication.sql | 4 + docker/sql/users.sql | 7 ++ 6 files changed, 103 insertions(+), 90 deletions(-) create mode 100644 docker/docker-compose.yml rename docker/{config_extension_example.cnf => maxscale.cnf.d/example.cnf} (72%) create mode 100644 docker/sql/master/users.sql create mode 100644 docker/sql/slave/replication.sql create mode 100644 docker/sql/users.sql diff --git a/docker/README.md b/docker/README.md index 01f9f38fd..fbe4ca69b 100644 --- a/docker/README.md +++ b/docker/README.md @@ -4,10 +4,10 @@ This Docker image runs the latest GA version of MariaDB MaxScale. ## Building -Run the following command to build the image. +Run the following command in this directory to build the image. ``` -sudo docker build -t maxscale . +docker build -t maxscale . ``` ## Usage @@ -29,92 +29,30 @@ docker run --network host --rm -v /my_dir:/container_dir maxscale -f /path/to/ma ## Default configuration -``` -# MaxScale documentation on GitHub: -# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Documentation-Contents.md +The default configuration for the MaxScale docker image can be found in +[this configuration file](./maxscale.cnf). -# Complete list of configuration options: -# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Getting-Started/Configuration-Guide.md +## MaxScale docker-compose setup -# Global parameters -[maxscale] -threads=auto - -# This service enables the use of the MaxAdmin interface -# MaxScale administration guide: -# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Reference/MaxAdmin.md -[MaxAdmin-Service] -type=service -router=cli - -[MaxAdmin-Listener] -type=listener -service=MaxAdmin-Service -protocol=maxscaled -socket=default -``` - -## Example base configuration +[The MaxScale docker-compose setup](./docker-compose.yml) contains MaxScale +configured with a three node master-slave cluster. To start it, run the +following commands in this directory. ``` -# Global parameters -[maxscale] -threads=auto - -# Monitor for the servers -# This will keep MaxScale aware of the state of the servers. -# MySQL Monitor documentation: -# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Monitors/MariaDB-Monitor.md - -[MariaDB-Monitor] -type=monitor -module=mariadbmon -user=myuser -passwd=mypwd -monitor_interval=1000 - -# Service definitions -# Service Definition for a read-only service and a read/write splitting service. - -# ReadConnRoute documentation: -# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Routers/ReadConnRoute.md - -[Read-Only-Service] -type=service -router=readconnroute -user=myuser -passwd=mypwd -router_options=slave - -# ReadWriteSplit documentation: -# https://github.com/mariadb-corporation/MaxScale/blob/2.2/Documentation/Routers/ReadWriteSplit.md - -[Read-Write-Service] -type=service -router=readwritesplit -user=myuser -passwd=mypwd -max_slave_connections=100% - -# Listener definitions for the services -# Listeners represent the ports the services will listen on. - -[Read-Only-Listener] -type=listener -service=Read-Only-Service -protocol=MySQLClient -port=4008 - -[Read-Write-Listener] -type=listener -service=Read-Write-Service -protocol=MySQLClient -port=4006 +docker-compose build +docker-compose up -d ``` -For base configurations, servers are defined at runtime. Run the following -command to create a server and link it into all services and monitors. +After MaxScale and the servers have started (takes a few minutes), you can find +the readwritesplit router on port 4006 and the readconnroute on port 4008. The +user `maxuser` with the password `maxpwd` can be used to test the cluster. + +You can edit the [`maxscale.cnf.d/example.cnf`](./maxscale.cnf.d/example.cnf) +file and recreate the MaxScale container to change the configuration. + +To stop the containers, execute the following command. Optionally, use the -v +flag to also remove the volumes. ``` -maxctrl create server --monitors MariaDB-Monitor --services Read-Only-Service Read-Write-Service +docker-compose down ``` diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 000000000..773951561 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,34 @@ +version: '2' +services: + master: + image: mariadb:10.2 + environment: + MYSQL_ALLOW_EMPTY_PASSWORD: Y + volumes: + - ./sql/master:/docker-entrypoint-initdb.d + command: mysqld --log-bin=mariadb-bin --binlog-format=ROW --server-id=3000 + + slave1: + image: mariadb:10.2 + environment: + MYSQL_ALLOW_EMPTY_PASSWORD: Y + volumes: + - ./sql/slave:/docker-entrypoint-initdb.d + command: mysqld --log-bin=mariadb-bin --binlog-format=ROW --server-id=3001 + + slave2: + image: mariadb:10.2 + environment: + MYSQL_ALLOW_EMPTY_PASSWORD: Y + volumes: + - ./sql/slave:/docker-entrypoint-initdb.d + command: mysqld --log-bin=mariadb-bin --binlog-format=ROW --server-id=3002 + + maxscale: + build: . + container_name: maxscale + volumes: + - ./maxscale.cnf.d:/etc/maxscale.cnf.d + ports: + - "4006:4006" + - "4008:4008" diff --git a/docker/config_extension_example.cnf b/docker/maxscale.cnf.d/example.cnf similarity index 72% rename from docker/config_extension_example.cnf rename to docker/maxscale.cnf.d/example.cnf index ee12f9581..28b629cce 100644 --- a/docker/config_extension_example.cnf +++ b/docker/maxscale.cnf.d/example.cnf @@ -2,6 +2,24 @@ [maxscale] threads=auto +[server1] +type=server +address=master +port=3306 +protocol=MariaDBBackend + +[server2] +type=server +address=slave1 +port=3306 +protocol=MariaDBBackend + +[server3] +type=server +address=slave2 +port=3306 +protocol=MariaDBBackend + # Monitor for the servers # This will keep MaxScale aware of the state of the servers. # MySQL Monitor documentation: @@ -10,9 +28,10 @@ threads=auto [MariaDB-Monitor] type=monitor module=mariadbmon -user=myuser -passwd=mypwd -monitor_interval=1000 +servers=server1,server2,server3 +user=maxuser +passwd=maxpwd +monitor_interval=2000 # Service definitions # Service Definition for a read-only service and a read/write splitting service. @@ -23,8 +42,9 @@ monitor_interval=1000 [Read-Only-Service] type=service router=readconnroute -user=myuser -passwd=mypwd +servers=server1,server2,server3 +user=maxuser +passwd=maxpwd router_options=slave # ReadWriteSplit documentation: @@ -33,9 +53,9 @@ router_options=slave [Read-Write-Service] type=service router=readwritesplit -user=myuser -passwd=mypwd -max_slave_connections=100% +servers=server1,server2,server3 +user=maxuser +passwd=maxpwd # Listener definitions for the services # Listeners represent the ports the services will listen on. diff --git a/docker/sql/master/users.sql b/docker/sql/master/users.sql new file mode 100644 index 000000000..ca1f44596 --- /dev/null +++ b/docker/sql/master/users.sql @@ -0,0 +1,10 @@ +RESET MASTER; +CREATE DATABASE test; + +CREATE USER 'maxuser'@'127.0.0.1' IDENTIFIED BY 'maxpwd'; +CREATE USER 'maxuser'@'%' IDENTIFIED BY 'maxpwd'; +GRANT ALL ON *.* TO 'maxuser'@'127.0.0.1' WITH GRANT OPTION; +GRANT ALL ON *.* TO 'maxuser'@'%' WITH GRANT OPTION; + +SET GLOBAL max_connections=10000; +SET GLOBAL gtid_strict_mode=ON; diff --git a/docker/sql/slave/replication.sql b/docker/sql/slave/replication.sql new file mode 100644 index 000000000..b38bf05c5 --- /dev/null +++ b/docker/sql/slave/replication.sql @@ -0,0 +1,4 @@ +CHANGE MASTER TO MASTER_HOST='master', MASTER_PORT=3306, MASTER_USER='maxuser', MASTER_PASSWORD='maxpwd', MASTER_LOG_POS=4, MASTER_LOG_FILE='mariadb-bin.000001', MASTER_CONNECT_RETRY=1; +START SLAVE; +SET GLOBAL max_connections=10000; +SET GLOBAL gtid_strict_mode=ON; diff --git a/docker/sql/users.sql b/docker/sql/users.sql new file mode 100644 index 000000000..4e2abd0f8 --- /dev/null +++ b/docker/sql/users.sql @@ -0,0 +1,7 @@ +RESET MASTER; + +CREATE USER 'maxuser'@'127.0.0.1' IDENTIFIED BY 'maxpwd'; +GRANT ALL ON *.* TO 'maxuser'@'127.0.0.1' WITH GRANT OPTION; + +CREATE USER 'maxuser'@'%' IDENTIFIED BY 'maxpwd'; +GRANT ALL ON *.* TO 'maxuser'@'%' WITH GRANT OPTION; From dac1b252ff9c71f85537f17ce417d20b554e0c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 16 Apr 2018 15:44:40 +0300 Subject: [PATCH 7/7] MXS-1807: Make module command domains case-insensitive As the module names are case-insensitive in 2.2, so should be the domain names of module commands. --- server/core/modulecmd.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server/core/modulecmd.cc b/server/core/modulecmd.cc index 717fd19e1..970703eaa 100644 --- a/server/core/modulecmd.cc +++ b/server/core/modulecmd.cc @@ -124,7 +124,7 @@ static MODULECMD_DOMAIN* get_or_create_domain(const char *domain) for (dm = modulecmd_domains; dm; dm = dm->next) { - if (strcmp(dm->domain, domain) == 0) + if (strcasecmp(dm->domain, domain) == 0) { return dm; } @@ -210,7 +210,7 @@ static bool domain_has_command(MODULECMD_DOMAIN *dm, const char *id) { for (MODULECMD *cmd = dm->commands; cmd; cmd = cmd->next) { - if (strcmp(cmd->identifier, id) == 0) + if (strcasecmp(cmd->identifier, id) == 0) { return true; } @@ -463,11 +463,11 @@ const MODULECMD* modulecmd_find_command(const char *domain, const char *identifi for (MODULECMD_DOMAIN *dm = modulecmd_domains; dm; dm = dm->next) { - if (strcmp(effective_domain, dm->domain) == 0) + if (strcasecmp(effective_domain, dm->domain) == 0) { for (MODULECMD *cmd = dm->commands; cmd; cmd = cmd->next) { - if (strcmp(cmd->identifier, identifier) == 0) + if (strcasecmp(cmd->identifier, identifier) == 0) { rval = cmd; break; @@ -625,7 +625,7 @@ bool modulecmd_foreach(const char *domain_re, const char *ident_re, { int err; mxs_pcre2_result_t d_res = domain_re ? - mxs_pcre2_simple_match(domain_re, domain->domain, 0, &err) : + mxs_pcre2_simple_match(domain_re, domain->domain, PCRE2_CASELESS, &err) : MXS_PCRE2_MATCH; if (d_res == MXS_PCRE2_MATCH) @@ -633,7 +633,7 @@ bool modulecmd_foreach(const char *domain_re, const char *ident_re, for (MODULECMD *cmd = domain->commands; cmd && rval; cmd = cmd->next) { mxs_pcre2_result_t i_res = ident_re ? - mxs_pcre2_simple_match(ident_re, cmd->identifier, 0, &err) : + mxs_pcre2_simple_match(ident_re, cmd->identifier, PCRE2_CASELESS, &err) : MXS_PCRE2_MATCH; if (i_res == MXS_PCRE2_MATCH)