diff --git a/CMakeLists.txt b/CMakeLists.txt index 62abd54a7..89066dcf6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,6 +171,9 @@ install(FILES ${CMAKE_BINARY_DIR}/Changelog.txt DESTINATION ${MAXSCALE_SHAREDIR} install(FILES ${CMAKE_BINARY_DIR}/ReleaseNotes.txt DESTINATION ${MAXSCALE_SHAREDIR}) install(FILES ${CMAKE_BINARY_DIR}/UpgradingToMaxScale110.txt DESTINATION ${MAXSCALE_SHAREDIR}) install(FILES server/maxscale_template.cnf DESTINATION ${MAXSCALE_SHAREDIR}) +if(WITH_MAXSCALE_CNF) + install(FILES server/maxscale_template.cnf DESTINATION ${MAXSCALE_CONFDIR} RENAME maxscale.cnf) +endif() install(FILES server/maxscale_binlogserver_template.cnf DESTINATION ${MAXSCALE_SHAREDIR}) install(FILES ${ERRMSG} DESTINATION ${MAXSCALE_VARDIR}/lib/maxscale PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) @@ -216,6 +219,7 @@ endif() # Only do packaging if configured if(PACKAGE) + execute_process(COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE) # Install the files copied by the postinst script into the share folder install(FILES ${CMAKE_BINARY_DIR}/maxscale DESTINATION ${MAXSCALE_SHAREDIR} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) @@ -236,7 +240,7 @@ if(PACKAGE) set(CPACK_PACKAGE_VERSION_MINOR "${MAXSCALE_VERSION_MINOR}") set(CPACK_PACKAGE_VERSION_PATCH "${MAXSCALE_VERSION_PATCH}") set(CPACK_PACKAGE_CONTACT "MariaDB Corporation Ab") - set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}") + set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}-${CPACK_PACKAGE_ARCHITECTURE}-${DISTRIB_SUFFIX}") set(CPACK_PACKAGE_NAME "maxscale") set(CPACK_PACKAGE_VENDOR "MariaDB Corporation Ab") set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/etc/DESCRIPTION) @@ -250,7 +254,8 @@ if(PACKAGE) if(NOT ( ${RPMBUILD} STREQUAL "RPMBUILD-NOTFOUND" ) ) include(cmake/package_rpm.cmake) message(STATUS "Generating RPM packages") - elseif(NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" ) ) + endif() + if(NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" ) ) include(cmake/package_deb.cmake) message(STATUS "Generating DEB packages for ${DEB_ARCHITECTURE}") endif() @@ -266,7 +271,7 @@ add_custom_target(buildtests ) add_custom_target(testall - COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N -DMAXSCALE_VARDIR=${CMAKE_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N -DWITH_MAXSCALE_CNF=N -DMAXSCALE_VARDIR=${CMAKE_BINARY_DIR} COMMAND make install COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/testall.cmake COMMENT "Running full test suite..." VERBATIM) diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index fc51d83ec..fd13f3bf1 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -19,7 +19,8 @@ ## Upgrading MaxScale -- [Upgrading MaxScale to 1.1.0](Upgrading-To-MaxScale-1.1.0.md) +- [Upgrading MaxScale from 1.1.1 to 1.2.0](Upgrading-To-MaxScale-1.2.0.md) +- [Upgrading MaxScale from 1.0.5 to 1.1.0](Upgrading-To-MaxScale-1.1.0.md) ## Reference @@ -43,33 +44,35 @@ - [Replication Proxy with the Binlog Router Tutorial](Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md) - [RabbitMQ Setup and MaxScale Integration Tutorial](Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md) - [Nagios Plugins for MaxScale Tutorial](Tutorials/Nagios-Plugins.md) + - [Simple Schema Sharding Tutorial](Tutorials/Simple-Sharding-Tutorial.md) ## Routers - - [Read Write Split](routers/ReadWriteSplit.md) - - [Read Connnection Router](routers/ReadConnRoute.md) - - [Schemarouter](routers/SchemaRouter.md) + - [Read Write Split](Routers/ReadWriteSplit.md) + - [Read Connnection Router](Routers/ReadConnRoute.md) + - [Schemarouter](Routers/SchemaRouter.md) ## Filters Here are detailed documents about the filters MaxScale offers. They contain configuration guides and example use cases. Before reading these,you should have read the filter tutorial so that you know how they work and how to configure them. - - [Query Log All](filters/Query-Log-All-Filter.md) - - [Regex Filter](filters/Regex-Filter.md) - - [Tee Filter](filters/Tee-Filter.md) - - [Top N Filter](filters/Top-N-Filter.md) - - [Database Firewall Filter](filters/Database-Firewall-Filter.md) - - [RabbitMQ Filter](filters/RabbitMQ-Filter.md) + - [Query Log All](Filters/Query-Log-All-Filter.md) + - [Regex Filter](Filters/Regex-Filter.md) + - [Tee Filter](Filters/Tee-Filter.md) + - [Top N Filter](Filters/Top-N-Filter.md) + - [Database Firewall Filter](Filters/Database-Firewall-Filter.md) + - [RabbitMQ Filter](Filters/RabbitMQ-Filter.md) + - [Named Server Filter](Filters/Named-Server-Filter.md) ## Monitors - - [MySQL Monitor](monitors/MySQL-Monitor.md) - - [Galera Monitor](monitors/Galera-Monitor.md) - - [Multi-Master Monitor](monitors/MM-Monitor.md) - - [MySQL Cluster Monitor](monitors/NDB-Cluster-Monitor.md) + - [MySQL Monitor](Monitors/MySQL-Monitor.md) + - [Galera Monitor](Monitors/Galera-Monitor.md) + - [Multi-Master Monitor](Monitors/MM-Monitor.md) + - [MySQL Cluster Monitor](Monitors/NDB-Cluster-Monitor.md) ## Utilities - - [RabbitMQ Consumer Client](filters/RabbitMQ-Consumer-Client.md) + - [RabbitMQ Consumer Client](Filters/RabbitMQ-Consumer-Client.md) ## Design Documents diff --git a/Documentation/filters/Database-Firewall-Filter.md b/Documentation/Filters/Database-Firewall-Filter.md similarity index 100% rename from Documentation/filters/Database-Firewall-Filter.md rename to Documentation/Filters/Database-Firewall-Filter.md diff --git a/Documentation/Filters/Named-Server-Filter.md b/Documentation/Filters/Named-Server-Filter.md new file mode 100644 index 000000000..3e41092de --- /dev/null +++ b/Documentation/Filters/Named-Server-Filter.md @@ -0,0 +1,92 @@ +Named Server Filter + +# Overview + +The **namedserverfilter** is a filter module for MaxScale which is able to route queries to servers based on regular expression matches. + +# Configuration + +The configuration block for the Named Server filter requires the minimal filter options in it’s section within the maxscale.cnf file, stored in /etc/maxscale.cnf. + +``` +[NamedServerFilter] +type=filter +module=namedserverfilter +match=some string +server=server2 + +[MyService] +type=service +router=readwritesplit +servers=server1,server2 +user=myuser +passwd=mypasswd +filters=NamedServerFilter +``` + +## Filter Options + +The named server filter accepts the options ignorecase or case. These define if the pattern text should take the case of the string it is matching against into consideration or not. + +## Filter Parameters + +The named server filter requires two mandatory parameters to be defined. + +### `match` + +A parameter that can be used to match text in the SQL statement which should be replaced. + +``` +match=TYPE[ ]*= +``` + +If the filter option ignorecase is used all regular expressions are evaluated with the option to ignore the case of the text, therefore a match option of select will match both type, TYPE and any form of the word with upper or lowercase characters. + +### `server` + +This is the server where matching queries will be router. The server should be in use by the service which uses this filter. + +``` +server=server2 +``` + +### `source` + +The optional source parameter defines an address that is used to match against the address from which the client connection to MaxScale originates. Only sessions that originate from this address will have the match and replacement applied to them. + +``` +source=127.0.0.1 +``` + +### `user` + +The optional user parameter defines a user name that is used to match against the user from which the client connection to MaxScale originates. Only sessions that are connected using this username will have the match and replacement applied to them. + +``` +user=john +``` + +## Examples + +### Example 1 - Route queries targeting a specific table to a server + +This will route all queries matching the regular expression ` *from *users` to the server named *server2*. The filter will ignore character case in queries. + +A query like `SELECT * FROM users` would be routed to server2 where as a query like `SELECT * FROM accounts` would be routed according to the normal rules of the router. + +``` +[NamedServerFilter] +type=filter +module=namedserverfilter +match= *from *users +options=ignorecase +server=server2 + +[MyService] +type=service +router=readwritesplit +servers=server1,server2 +user=myuser +passwd=mypasswd +filters=NamedServerFilter +``` diff --git a/Documentation/filters/Query-Log-All-Filter.md b/Documentation/Filters/Query-Log-All-Filter.md similarity index 100% rename from Documentation/filters/Query-Log-All-Filter.md rename to Documentation/Filters/Query-Log-All-Filter.md diff --git a/Documentation/filters/RabbitMQ-Consumer-Client.md b/Documentation/Filters/RabbitMQ-Consumer-Client.md similarity index 100% rename from Documentation/filters/RabbitMQ-Consumer-Client.md rename to Documentation/Filters/RabbitMQ-Consumer-Client.md diff --git a/Documentation/filters/RabbitMQ-Filter.md b/Documentation/Filters/RabbitMQ-Filter.md similarity index 100% rename from Documentation/filters/RabbitMQ-Filter.md rename to Documentation/Filters/RabbitMQ-Filter.md diff --git a/Documentation/filters/Regex-Filter.md b/Documentation/Filters/Regex-Filter.md similarity index 100% rename from Documentation/filters/Regex-Filter.md rename to Documentation/Filters/Regex-Filter.md diff --git a/Documentation/filters/Tee-Filter.md b/Documentation/Filters/Tee-Filter.md similarity index 100% rename from Documentation/filters/Tee-Filter.md rename to Documentation/Filters/Tee-Filter.md diff --git a/Documentation/filters/Top-N-Filter.md b/Documentation/Filters/Top-N-Filter.md similarity index 100% rename from Documentation/filters/Top-N-Filter.md rename to Documentation/Filters/Top-N-Filter.md diff --git a/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md b/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md index 95236ed7e..96147c0f1 100644 --- a/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md +++ b/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md @@ -22,9 +22,9 @@ After following the instructions on that site you should have a working MariaDB The full list of dependencies for the most common distributions is provided in this section. If your system is not listed here, MaxScale building isn't guaranteed to be compatible but might still be successful. -## RHEL, CentOS and Fedora +## RHEL and CentOS -You will need to install all of the following packages for all versions of RHEL, CentOS and Fedora. +You will need to install all of the following packages for all versions of RHEL and CentOS. ``` gcc gcc-c++ ncurses-devel bison glibc-devel cmake libgcc perl make libtool @@ -39,7 +39,7 @@ rpm-build There are also some version specific packages you need to install. -#### RHEL 6, 7, CentOS 6, 7, Fedora: +#### RHEL 6, 7, CentOS 6, 7: ``` libedit-devel @@ -51,17 +51,11 @@ libedit-devel mariadb-devel mariadb-embedded-devel ``` -#### RHEL 5, 6, CentOS 5, 6, Fedora 19, 20 +#### RHEL 5, 6, CentOS 5, 6 ``` MariaDB-devel MariaDB-server ``` -#### Fedora 19, 20 - -``` -systemtap-sdt-devel -``` - ## Ubuntu and Debian These packages are required on all versions of Ubuntu and Debian. @@ -87,16 +81,13 @@ You will also need some version specific packages. #### Earlier versions of Ubuntu or Debian -For these, you will need to obtain the MariaDB embedded library. It has to be manually extracted from the tarball. But first ascertain what version of glibc is installed. Run the command: +For these, you will need to obtain the MariaDB embedded library. It has to be manually extracted from the tarballs at the MariaDB site. But first ascertain what version of glibc is installed. Run the command: ``` dpkg -l | grep libc6 ``` -which will show the version number. If the version is less than 2.14 you should obtain the library from: -[https://downloads.mariadb.org/interstitial/mariadb-5.5.41/bintar-linux-x86_64/mariadb-5.5.41-linux-x86_64.tar.gz](https://downloads.mariadb.org/interstitial/mariadb-5.5.41/bintar-linux-x86_64/mariadb-5.5.41-linux-x86_64.tar.gz). -Otherwise, from: -[https://downloads.mariadb.org/interstitial/mariadb-5.5.41/bintar-linux-glibc_214-x86_64/mariadb-5.5.41-linux-glibc_214-x86_64.tar.gz](https://downloads.mariadb.org/interstitial/mariadb-5.5.41/bintar-linux-glibc_214-x86_64/mariadb-5.5.41-linux-glibc_214-x86_64.tar.gz) +which will show the version number. For versions older than 2.14 you should obtain the library which supports GLIBC versions older than 2.14 and for newer versions, the library which supports newer GLIBC versions should be used. The suggested location for extracting the tarball is `/usr` so the operation can be done by the following commands: @@ -107,22 +98,6 @@ The suggested location for extracting the tarball is `/usr` so the operation can where /path/to/mariadb.library.tar.gz is replaced by the actual path and name of the downloaded tarball. -## OpenSUSE - -At the time this guide was written, the MariaDB development packages for OpenSUSE were broken and the build failed. - -The packages required are: - -``` -gcc gcc-c++ ncurses-devel bison glibc-devel cmake libgcc_s1 perl -make libtool libopenssl-devel libaio libaio-devel -libedit-devel librabbitmq-devel - MariaDB-devel MariaDB-client MariaDB-server -``` - -If zypper ask which MariaDB client should be installed `MariaDB-client` or `mariadb-client` - please select `MariaDB-client`. This is the package provided by the MariaDB repository. - # Obtaining the MaxScale Source Code Now clone the GitHub project to your machine either via the web interface, your favorite graphical interface or the git command line @@ -152,16 +127,15 @@ wipe the build directory clean without the danger of deleting important files wh something goes wrong. Building 'out-of-source' also allows you to have multiple configurations of MaxScale at the same time. -The default values that CMake uses can be found in the 'macros.cmake' file. -If you wish to change these, edit the 'macros.cmake' file or define the -variables manually at configuration time. +The default values that MaxScale uses for CMake can be found in the 'macros.cmake' file under the `cmake` folder. +If you wish to change these, edit the 'macros.cmake' file or define the variables manually at configuration time. To display all CMake variables with their descriptions: ``` cmake .. -LH ``` -This is a useful command if you have your libraries installed in non-standard locations. +This is a useful command if you have your libraries installed in non-standard locations and need to provide them manually. When you are ready to run cmake, provide the following command: @@ -241,7 +215,7 @@ $ make install This will result in an installation being created which is identical to that which would be achieved by installing the binary package. -By default, MaxScale installs to `/usr/local/mariadb-maxscale` and places init.d scripts and ldconfig files into their folders. Change the `CMAKE_INSTALL_PREFIX` variable to your desired installation directory and set `WITH_SCRIPTS=N` to prevent the init.d script and ldconfig file installation. +When building from source, MaxScale installs to `/usr/local/` and places init.d scripts and ldconfig files into their folders. Change the `CMAKE_INSTALL_PREFIX` variable to your desired installation directory and set `WITH_SCRIPTS=N` to prevent the init.d script and ldconfig file installation. Other useful targets for Make are `documentation`, which generates the Doxygen documentation, and `uninstall` which uninstall MaxScale binaries after an install. diff --git a/Documentation/monitors/Galera-Monitor.md b/Documentation/Monitors/Galera-Monitor.md similarity index 100% rename from Documentation/monitors/Galera-Monitor.md rename to Documentation/Monitors/Galera-Monitor.md diff --git a/Documentation/monitors/MM-Monitor.md b/Documentation/Monitors/MM-Monitor.md similarity index 100% rename from Documentation/monitors/MM-Monitor.md rename to Documentation/Monitors/MM-Monitor.md diff --git a/Documentation/monitors/MySQL-Monitor.md b/Documentation/Monitors/MySQL-Monitor.md similarity index 100% rename from Documentation/monitors/MySQL-Monitor.md rename to Documentation/Monitors/MySQL-Monitor.md diff --git a/Documentation/monitors/NDB-Cluster-Monitor.md b/Documentation/Monitors/NDB-Cluster-Monitor.md similarity index 100% rename from Documentation/monitors/NDB-Cluster-Monitor.md rename to Documentation/Monitors/NDB-Cluster-Monitor.md diff --git a/Documentation/Release-Notes/MaxScale-0.5-Release-Notes.md b/Documentation/Release-Notes/MaxScale-0.5-Release-Notes.md index 3ae56ce9e..5f09d7bfd 100644 --- a/Documentation/Release-Notes/MaxScale-0.5-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-0.5-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 0.5 Alpha Release Notes 0.5 Alpha diff --git a/Documentation/Release-Notes/MaxScale-0.6-Release-Notes.md b/Documentation/Release-Notes/MaxScale-0.6-Release-Notes.md index ff7033e4d..4b2c445c3 100644 --- a/Documentation/Release-Notes/MaxScale-0.6-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-0.6-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 0.6 Alpha Release Notes 0.6 Alpha diff --git a/Documentation/Release-Notes/MaxScale-0.7-Release-Notes.md b/Documentation/Release-Notes/MaxScale-0.7-Release-Notes.md index bc43ee00d..21d9320ec 100644 --- a/Documentation/Release-Notes/MaxScale-0.7-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-0.7-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 0.7 Alpha Release Notes 0.7 Alpha diff --git a/Documentation/Release-Notes/MaxScale-1.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.0-Release-Notes.md index a15757e0f..4ce52f6c3 100644 --- a/Documentation/Release-Notes/MaxScale-1.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.0-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 1.0 Beta Release Notes 1.0 Beta diff --git a/Documentation/Release-Notes/MaxScale-1.0.1-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.0.1-Release-Notes.md index a82083ac9..5586696a4 100644 --- a/Documentation/Release-Notes/MaxScale-1.0.1-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.0.1-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 1.0.1 Beta Release Notes 1.0.1 Beta diff --git a/Documentation/Release-Notes/MaxScale-1.0.3-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.0.3-Release-Notes.md index 67c5e3ece..db8329366 100644 --- a/Documentation/Release-Notes/MaxScale-1.0.3-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.0.3-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 1.0.3 Release Notes 1.0.3 GA diff --git a/Documentation/Release-Notes/MaxScale-1.0.4-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.0.4-Release-Notes.md index db341e893..9103c830a 100644 --- a/Documentation/Release-Notes/MaxScale-1.0.4-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.0.4-Release-Notes.md @@ -1,4 +1,4 @@ -# MaxScale Release Notes +# MariaDB MaxScale 1.0.4 Release Notes 1.0.4 GA diff --git a/Documentation/Release-Notes/MaxScale-1.0.5-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.0.5-Release-Notes.md index 4b65fd92f..e979ff6c1 100644 --- a/Documentation/Release-Notes/MaxScale-1.0.5-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.0.5-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes 1.0.5 GA +# MariaDB MaxScale 1.0.5 Release Notes This document details the changes in version 1.0.5 since the release of the 1.0.4 GA of the MaxScale product. diff --git a/Documentation/Release-Notes/MaxScale-1.1-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.1-Release-Notes.md index c3ed66b73..e196335b9 100644 --- a/Documentation/Release-Notes/MaxScale-1.1-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.1-Release-Notes.md @@ -1,4 +1,4 @@ -# MaxScale Release Notes +# MariaDB MaxScale 1.1 Release Notes ## 1.1 GA diff --git a/Documentation/Release-Notes/MaxScale-1.1.1-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.1.1-Release-Notes.md index 6c1631d4c..689323543 100644 --- a/Documentation/Release-Notes/MaxScale-1.1.1-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.1.1-Release-Notes.md @@ -1,6 +1,6 @@ -# MaxScale Release Notes +# MariaDB MaxScale 1.1.1 Release Notes -## 1.1 GA +## 1.1.1 GA This document details the changes in version 1.1.1 since the release of the 1.1 GA Release of the MaxScale product. diff --git a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md index caf7e28c6..4ffdcba1f 100644 --- a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md @@ -1,4 +1,4 @@ -# MaxScale Release Notes +# MariaDB MaxScale 1.2 Release Notes ## 1.2 GA @@ -27,31 +27,73 @@ A quick list of changes in installation directories and file names: ### Client side SSL encryption MaxScale now supports SSL/TLS encrypted connections to MaxScale. -### Monitor scripts -State changes in backend servers can now trigger the execution of a custom script. With this you can easily customize MaxScale's behavior. +### Launchable scripts +Now you can configure MaxScale monitor module to automatically launch a script when it detects change in the state of a backend server. The script can be any customer script defined by you to take diagnostic or reporting action. With this you can easily customize MaxScale's behavior. + +### Lsyncd configuration guide +A new tutorial has beed added which helps you keep MaxScale's configuration files in sync across multiple hosts. This allows for easier HA setups with MaxScale and guarantees up-to-date configuration files on all nodes. The tutorial can be found [here](../Reference/MaxScale-HA-with-lsyncd.md). ## Bug fixes Here is a list of bugs fixed since the release of MaxScale 1.1.1. -| Key | Summary | -| --- | -------- | -| [MXS-24](https://mariadb.atlassian.net/browse/MXS-24) | bugzillaId-604: Module load path documentation issues ... | -| [MXS-40](https://mariadb.atlassian.net/browse/MXS-40) | Display logged in users | -| [MXS-113](https://mariadb.atlassian.net/browse/MXS-113) | MaxScale seems to fail if built against MariaDB 10.0 libraries | -| [MXS-116](https://mariadb.atlassian.net/browse/MXS-116) | Do not run maxscale as root. | -| [MXS-125](https://mariadb.atlassian.net/browse/MXS-125) | inconsistency in maxkeys/maxpassword output and parameters | -| [MXS-136](https://mariadb.atlassian.net/browse/MXS-136) | Check for MaxScale replication heartbeat table existence before creating | -| [MXS-137](https://mariadb.atlassian.net/browse/MXS-137) | cannot get sql for queries with length >= 0x80 | -| [MXS-139](https://mariadb.atlassian.net/browse/MXS-139) | Schemarouter authentication for wildcard grants fails without optimize_wildcard | -| [MXS-140](https://mariadb.atlassian.net/browse/MXS-140) | strip_db_esc does not work without auth_all_servers | -| [MXS-162](https://mariadb.atlassian.net/browse/MXS-162) | Fix Incorrect info in Configuration Guide | -| [MXS-163](https://mariadb.atlassian.net/browse/MXS-163) | Reload config leaks memory | -| [MXS-165](https://mariadb.atlassian.net/browse/MXS-165) | Concurrency issue while incrementing sessions in qlafilter | -| [MXS-166](https://mariadb.atlassian.net/browse/MXS-166) | Memory leak when creating a new event | -| [MXS-171](https://mariadb.atlassian.net/browse/MXS-171) | Allow reads on master for readwritesplit | -| [MXS-176](https://mariadb.atlassian.net/browse/MXS-176) | Missing dependencies in documentation | -| [MXS-181](https://mariadb.atlassian.net/browse/MXS-181) | Poor performance on TCP connection due to Nagle's algoritm | -| [MXS-212](https://mariadb.atlassian.net/browse/MXS-212) | Stopped services accept connections | -| [MXS-225](https://mariadb.atlassian.net/browse/MXS-225) | RPM Debug build packages have no debugging symbols | -| [MXS-227](https://mariadb.atlassian.net/browse/MXS-227) | Memory leak in Galera Monitor | + * [MXS-24](https://mariadb.atlassian.net/browse/MXS-24): bugzillaId-604: Module load path documentation issues ... + * [MXS-40](https://mariadb.atlassian.net/browse/MXS-40): Display logged in users + * [MXS-113](https://mariadb.atlassian.net/browse/MXS-113): MaxScale seems to fail if built against MariaDB 10.0 libraries + * [MXS-116](https://mariadb.atlassian.net/browse/MXS-116): Do not run maxscale as root. + * [MXS-117](https://mariadb.atlassian.net/browse/MXS-117): Allow configuration of the log file directory + * [MXS-125](https://mariadb.atlassian.net/browse/MXS-125): inconsistency in maxkeys/maxpassword output and parameters + * [MXS-128](https://mariadb.atlassian.net/browse/MXS-128): cyclic dependency utils -> log_manager -> utils + * [MXS-136](https://mariadb.atlassian.net/browse/MXS-136): Check for MaxScale replication heartbeat table existence before creating + * [MXS-137](https://mariadb.atlassian.net/browse/MXS-137): cannot get sql for queries with length >= 0x80 + * [MXS-139](https://mariadb.atlassian.net/browse/MXS-139): Schemarouter authentication for wildcard grants fails without optimize_wildcard + * [MXS-140](https://mariadb.atlassian.net/browse/MXS-140): strip_db_esc does not work without auth_all_servers + * [MXS-162](https://mariadb.atlassian.net/browse/MXS-162): Fix Incorrect info in Configuration Guide + * [MXS-165](https://mariadb.atlassian.net/browse/MXS-165): Concurrency issue while incrementing sessions in qlafilter + * [MXS-166](https://mariadb.atlassian.net/browse/MXS-166): Memory leak when creating a new event + * [MXS-171](https://mariadb.atlassian.net/browse/MXS-171): Allow reads on master for readwritesplit + * [MXS-176](https://mariadb.atlassian.net/browse/MXS-176): Missing dependencies in documentation + * [MXS-179](https://mariadb.atlassian.net/browse/MXS-179): Keep configuration changes in synch across MaxScale Mate Nodes + * [MXS-180](https://mariadb.atlassian.net/browse/MXS-180): MariaDB10 binlog router compatibilty + * [MXS-181](https://mariadb.atlassian.net/browse/MXS-181): Poor performance on TCP connection due to Nagle's algoritm + * [MXS-182](https://mariadb.atlassian.net/browse/MXS-182): SHOW SLAVE STATUS and maxadmin "show services" for binlog router needs updated when used with MariaDB 10 Master + * [MXS-212](https://mariadb.atlassian.net/browse/MXS-212): Stopped services accept connections + * [MXS-225](https://mariadb.atlassian.net/browse/MXS-225): RPM Debug build packages have no debugging symbols + * [MXS-227](https://mariadb.atlassian.net/browse/MXS-227): Memory leak in Galera Monitor + * [MXS-244](https://mariadb.atlassian.net/browse/MXS-244): Memory leak when using prepared statements without arguments + +## Known Issues and Limitations + +There are a number bugs and known limitations within this version of MaxScale, the most serious of this are listed below. + +* MaxScale can not manage authentication that uses wildcard matching in hostnames in the mysql.user table of the backend database. The only wildcards that can be used are in IP address entries. + +* When users have different passwords based on the host from which they connect MaxScale is unable to determine which password it should use to connect to the backend database. This results in failed connections and unusable usernames in MaxScale. + +* LONGBLOB are currently not supported. + +* Galera Cluster variables, such as @@wsrep_node_name, are not resolved by the embedded MariaDB parser. + +* The Database Firewall filter does not support multi-statements. Using them will result in an error being sent to the client. + +## Packaging + +Both RPM and Debian packages are available for MaxScale in addition to the tar based releases previously distributed we now provide + +* CentOS/RedHat 5 + +* CentOS/RedHat 6 + +* CentOS/RedHat 7 + +* Debian 6 + +* Debian 7 + +* Ubuntu 12.04 LTS + +* Ubuntu 14.04 LTS + +* SuSE Linux Enterprise 11 + +* SuSE Linux Enterprise 12 diff --git a/Documentation/routers/ReadConnRoute.md b/Documentation/Routers/ReadConnRoute.md similarity index 100% rename from Documentation/routers/ReadConnRoute.md rename to Documentation/Routers/ReadConnRoute.md diff --git a/Documentation/routers/ReadWriteSplit.md b/Documentation/Routers/ReadWriteSplit.md similarity index 98% rename from Documentation/routers/ReadWriteSplit.md rename to Documentation/Routers/ReadWriteSplit.md index e58367789..7fb6d5cf0 100644 --- a/Documentation/routers/ReadWriteSplit.md +++ b/Documentation/Routers/ReadWriteSplit.md @@ -100,6 +100,10 @@ disable_slave_recovery=true master_accept_reads=true ``` +### Routing hints + +The readwritesplit router supports routing hints. For a detailed guide on hint syntax and functionality, please see [this](../Reference/Hint-Syntax.md) document. + ## Limitations In Master-Slave replication cluster also read-only queries are routed to master too in the following situations: diff --git a/Documentation/routers/SchemaRouter.md b/Documentation/Routers/SchemaRouter.md similarity index 98% rename from Documentation/routers/SchemaRouter.md rename to Documentation/Routers/SchemaRouter.md index d1de66b2b..55c3ad706 100644 --- a/Documentation/routers/SchemaRouter.md +++ b/Documentation/Routers/SchemaRouter.md @@ -64,4 +64,4 @@ The schemarouter router currently has some limitations due to the nature of the ## Examples -[Here](../../Tutorials/Simple-Sharding-Tutorial.md) is a small tutorial on how to set up a sharded database. +[Here](../Tutorials/Simple-Sharding-Tutorial.md) is a small tutorial on how to set up a sharded database. diff --git a/Documentation/Upgrading-To-MaxScale-1.2.0.md b/Documentation/Upgrading-To-MaxScale-1.2.0.md new file mode 100644 index 000000000..a48750076 --- /dev/null +++ b/Documentation/Upgrading-To-MaxScale-1.2.0.md @@ -0,0 +1,24 @@ +# Upgrading MaxScale from 1.1 to 1.2 + +This document describes upgrading MaxScale from version 1.1.1 to 1.2 and the major differences in the new version compared to the old version. The major changes can be found in the `Changelog.txt` file in the installation directory and the official release notes in the `ReleaseNotes.txt` file. + +## Installation + +Before starting the upgrade, we recommend you back up your configuration, log and binary log files in `/usr/local/mariadb-maxscale/`. + +Upgrading MaxScale will copy the `MaxScale.cnf` file in `/usr/local/mariadb-maxscale/etc/` to `/etc/` and renamed to `maxscale.cnf`. Binary log files are not automatically copied and should be manually moved from `/usr/local/mariadb-maxscale` to `/var/lib/maxscale/`. + +## File location changes + +MaxScale 1.2 follows the [FHS-standard](http://www.pathname.com/fhs/) and installs to `/usr/` and `/var/` subfolders. Here are the major changes and file locations. + +* Configuration files are located in `/etc/` and use lowercase letters: `/etc/maxscale.cnf` +* Binary files are in `/usr/bin/` +* Libraries and modules are in `/usr/lib64/maxscale/`. If you are using custom modules, please make sure they are in this directory before starting MaxScale. +* Log files are in the `var/log/maxscale/` folder +* MaxScale's PID file is located in `/var/run/maxscale/maxscale.pid` +* Data files and other persistent files are in `/var/lib/maxscale/` + +## Running MaxScale without root permissions + +MaxScale can run as a non-root user with the 1.2 version. RPM and DEB packages install the `maxscale` user and `maxscale` group which are used by the init scripts and systemd configuration files. If you are installing from a binary tarball, you can run the `postinst` script included in it to manually create these groups. diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index e25bd0a8d..a14ef05c5 100644 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -5,8 +5,7 @@ set(MAXSCALE_LIBDIR ${CMAKE_INSTALL_LIBDIR}/maxscale CACHE PATH "Library install set(MAXSCALE_BINDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Executable installation path") set(MAXSCALE_SHAREDIR ${CMAKE_INSTALL_DATADIR}/maxscale CACHE PATH "Share file installation path, includes licence and readme files") set(MAXSCALE_DOCDIR ${CMAKE_INSTALL_DOCDIR}/maxscale CACHE PATH "Documentation installation path, text versions only") -set(MAXSCALE_CONFDIR ${CMAKE_INSTALL_SYSCONFDIR} CACHE PATH "Configuration file installation path, this is not usually needed") -# This is the only hard-coded absolute path +# These are the only hard-coded absolute paths set(MAXSCALE_VARDIR /var CACHE PATH "Data file path (usually /var/)") - +set(MAXSCALE_CONFDIR /etc CACHE PATH "Configuration file installation path (/etc/)") diff --git a/cmake/macros.cmake b/cmake/macros.cmake index 3c9d16cc0..848b3290f 100644 --- a/cmake/macros.cmake +++ b/cmake/macros.cmake @@ -23,6 +23,9 @@ macro(set_variables) # Use C99 set(USE_C99 TRUE CACHE BOOL "Use C99 standard") + # Install the template maxscale.cnf file + set(WITH_MAXSCALE_CNF TRUE CACHE BOOL "Install the template maxscale.cnf file") + # hostname or IP address of MaxScale's host set(TEST_HOST "127.0.0.1" CACHE STRING "hostname or IP address of MaxScale's host") diff --git a/cmake/package_rpm.cmake b/cmake/package_rpm.cmake index 0f65bcdd2..7f11587a7 100644 --- a/cmake/package_rpm.cmake +++ b/cmake/package_rpm.cmake @@ -1,15 +1,5 @@ # RPM specific CPack configuration parameters set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MaxScale") -set(CPACK_PACKAGE_VERSION_MAJOR "${MAXSCALE_VERSION_MAJOR}") -set(CPACK_PACKAGE_VERSION_MINOR "${MAXSCALE_VERSION_MINOR}") -set(CPACK_PACKAGE_VERSION_PATCH "${MAXSCALE_VERSION_PATCH}") -set(CPACK_PACKAGE_CONTACT "MariaDB Corporation Ab") -set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}") -set(CPACK_PACKAGE_NAME "maxscale") -set(CPACK_PACKAGE_VENDOR "MariaDB Corporation Ab") -set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/etc/DESCRIPTION) -set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") set(CPACK_RPM_PACKAGE_RELEASE ${MAXSCALE_BUILD_NUMBER}) set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE ${CMAKE_BINARY_DIR}/postinst) set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE ${CMAKE_BINARY_DIR}/postrm) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index a87157be7..79c2ace30 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -1457,7 +1457,7 @@ int skygw_log_write( * Write log string to buffer and add to file write list. */ - for (i = LOGFILE_FIRST; i #include #include -#define _XOPEN_SOURCE +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif #include #include #include diff --git a/server/core/buffer.c b/server/core/buffer.c index 4c788cdd2..c3adacd34 100644 --- a/server/core/buffer.c +++ b/server/core/buffer.c @@ -197,6 +197,7 @@ GWBUF *rval; rval->gwbuf_info = buf->gwbuf_info; rval->gwbuf_bufobj = buf->gwbuf_bufobj; rval->tail = rval; + rval->next = NULL; CHK_GWBUF(rval); return rval; } diff --git a/server/maxscale_template.cnf b/server/maxscale_template.cnf index feec5695d..0928a750d 100644 --- a/server/maxscale_template.cnf +++ b/server/maxscale_template.cnf @@ -128,6 +128,10 @@ module=regexfilter match=fetch replace=select +[hint] +type=filter +module=hintfilter + ## A series of service definition # @@ -218,11 +222,21 @@ router=readwritesplit servers=server1,server2,server3 user=myuser passwd=mypwd -#use_sql_variables_in= -#max_slave_connections=100% +max_slave_connections=100% +#use_sql_variables_in=master #max_slave_replication_lag=21 -#router_options=slave_selection_criteria= -#filters=fetch|qla +#filters=hint|fetch|qla +#router_options=slave_selection_criteria=LEAST_CURRENT_OPERATIONS + +# Uncomment this to disable the saving of session modifying comments. Some scripting +# languages use connection pooling and will use the same session. MaxScale sees them +# as the same session and stores them for the slave recovery process. +#router_options=disable_sescmd_history=true,disable_slave_recovery=true + +# This will allow the master server to be used for read queries. By default +# MaxScale will only use the master for write queries. +#router_options=master_accept_reads=true + [Debug Interface] type=service @@ -265,27 +279,26 @@ service=Read Connection Router protocol=MySQLClient address=192.168.100.102 port=4008 -#socket=/tmp/readconn.sock +socket=/var/lib/maxscale/readconn.sock [RW Split Listener] type=listener service=RW Split Router protocol=MySQLClient port=4006 -#socket=/tmp/rwsplit.sock +#socket=/var/lib/maxscale/rwsplit.sock [Debug Listener] type=listener service=Debug Interface protocol=telnetd -#address=127.0.0.1 +address=127.0.0.1 port=4442 [CLI Listener] type=listener service=CLI protocol=maxscaled -#address=localhost port=6603 ## Definition of the servers @@ -314,18 +327,18 @@ port=6603 [server1] type=server -address=192.168.100.101 -port=3000 +address=127.0.0.1 +port=3306 protocol=MySQLBackend [server2] type=server -address=192.168.100.102 -port=3000 +address=127.0.0.1 +port=3306 protocol=MySQLBackend [server3] type=server -address=192.168.100.103 -port=3000 +address=127.0.0.1 +port=3306 protocol=MySQLBackend diff --git a/server/modules/filter/namedserverfilter.c b/server/modules/filter/namedserverfilter.c index b7a5b91c1..822b5eaf2 100644 --- a/server/modules/filter/namedserverfilter.c +++ b/server/modules/filter/namedserverfilter.c @@ -35,7 +35,7 @@ extern __thread log_info_t tls_log_info; * that routes to a named server if a regular expression match is found. * @verbatim * - * A simple regular expression query rewrite filter. + * A simple regular expression based query routing filter. * Two parameters should be defined in the filter configuration * match= * server= diff --git a/server/modules/include/blr.h b/server/modules/include/blr.h index 6f6d61fb6..5c1270633 100644 --- a/server/modules/include/blr.h +++ b/server/modules/include/blr.h @@ -26,7 +26,8 @@ * * Date Who Description * 02/04/14 Mark Riddoch Initial implementation - * 11/05/15 Massimilaino Pinto Added mariadb10_compat to master and slave structs + * 11/05/15 Massimiliano Pinto Added mariadb10_compat to master and slave structs + * 12/06/15 Massimiliano Pinto Added mariadb10 new events * * @endverbatim */ @@ -45,7 +46,77 @@ #define BINLOG_EVENT_HDR_LEN 19 -/* How often to call the binlog status function (seconds) */ +/** + * Binlog event types + */ +#define START_EVENT_V3 0x01 +#define QUERY_EVENT 0x02 +#define STOP_EVENT 0x03 +#define ROTATE_EVENT 0x04 +#define INTVAR_EVENT 0x05 +#define LOAD_EVENT 0x06 +#define SLAVE_EVENT 0x07 +#define CREATE_FILE_EVENT 0x08 +#define APPEND_BLOCK_EVENT 0x09 +#define EXEC_LOAD_EVENT 0x0A +#define DELETE_FILE_EVENT 0x0B +#define NEW_LOAD_EVENT 0x0C +#define RAND_EVENT 0x0D +#define USER_VAR_EVENT 0x0E +#define FORMAT_DESCRIPTION_EVENT 0x0F +#define XID_EVENT 0x10 +#define BEGIN_LOAD_QUERY_EVENT 0x11 +#define EXECUTE_LOAD_QUERY_EVENT 0x12 +#define TABLE_MAP_EVENT 0x13 +#define WRITE_ROWS_EVENTv0 0x14 +#define UPDATE_ROWS_EVENTv0 0x15 +#define DELETE_ROWS_EVENTv0 0x16 +#define WRITE_ROWS_EVENTv1 0x17 +#define UPDATE_ROWS_EVENTv1 0x18 +#define DELETE_ROWS_EVENTv1 0x19 +#define INCIDENT_EVENT 0x1A +#define HEARTBEAT_EVENT 0x1B +#define IGNORABLE_EVENT 0x1C +#define ROWS_QUERY_EVENT 0x1D +#define WRITE_ROWS_EVENTv2 0x1E +#define UPDATE_ROWS_EVENTv2 0x1F +#define DELETE_ROWS_EVENTv2 0x20 +#define GTID_EVENT 0x21 +#define ANONYMOUS_GTID_EVENT 0x22 +#define PREVIOUS_GTIDS_EVENT 0x23 + +#define MAX_EVENT_TYPE 0x23 + +/* New MariaDB event numbers start from 0xa0 */ +#define MARIADB_NEW_EVENTS_BEGIN 0xa0 +#define MARIADB_ANNOTATE_ROWS_EVENT 0xa0 +/* New MariaDB 10 event numbers start from here */ +#define MARIADB10_BINLOG_CHECKPOINT_EVENT 0xa1 +#define MARIADB10_GTID_EVENT 0xa2 +#define MARIADB10_GTID_GTID_LIST_EVENT 0xa3 + +#define MAX_EVENT_TYPE_MARIADB10 0xa3 + +/* Maximum event type so far */ +#define MAX_EVENT_TYPE_END MAX_EVENT_TYPE_MARIADB10 + +/** + * Binlog event flags + */ +#define LOG_EVENT_BINLOG_IN_USE_F 0x0001 +#define LOG_EVENT_FORCED_ROTATE_F 0x0002 +#define LOG_EVENT_THREAD_SPECIFIC_F 0x0004 +#define LOG_EVENT_SUPPRESS_USE_F 0x0008 +#define LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F 0x0010 +#define LOG_EVENT_ARTIFICIAL_F 0x0020 +#define LOG_EVENT_RELAY_LOG_F 0x0040 +#define LOG_EVENT_IGNORABLE_F 0x0080 +#define LOG_EVENT_NO_FILTER_F 0x0100 +#define LOG_EVENT_MTS_ISOLATE_F 0x0200 + +/** + * How often to call the binlog status function (seconds) + */ #define BLR_STATS_FREQ 60 #define BLR_NSTATS_MINUTES 30 @@ -212,7 +283,7 @@ typedef struct { uint64_t n_fakeevents; /*< Fake events not written to disk */ uint64_t n_artificial; /*< Artificial events not written to disk */ int n_badcrc; /*< No. of bad CRC's from master */ - uint64_t events[0x24]; /*< Per event counters */ + uint64_t events[MAX_EVENT_TYPE_END + 1]; /*< Per event counters */ uint64_t lastsample; int minno; int minavgs[BLR_NSTATS_MINUTES]; @@ -327,7 +398,7 @@ static char *blrm_states[] = { "Unconnected", "Connecting", "Authenticated", "Ti "binlog checksum rerieval", "GTID Mode retrieval", "Master UUID retrieval", "Set Slave UUID", "Set Names latin1", "Set Names utf8", "select 1", "select version()", "select @@version_comment", "select @@hostname", - "select @@mx_allowed_packet", "Register slave", "Binlog Dump", "Set MariaDB slave capability" }; + "select @@max_allowed_packet", "Register slave", "Binlog Dump", "Set MariaDB slave capability" }; #define BLRS_CREATED 0x0000 #define BLRS_UNREGISTERED 0x0001 @@ -361,62 +432,6 @@ static char *blrs_states[] = { "Created", "Unregistered", "Registered", #define COM_REGISTER_SLAVE 0x15 #define COM_BINLOG_DUMP 0x12 -/** - * Binlog event types - */ -#define START_EVENT_V3 0x01 -#define QUERY_EVENT 0x02 -#define STOP_EVENT 0x03 -#define ROTATE_EVENT 0x04 -#define INTVAR_EVENT 0x05 -#define LOAD_EVENT 0x06 -#define SLAVE_EVENT 0x07 -#define CREATE_FILE_EVENT 0x08 -#define APPEND_BLOCK_EVENT 0x09 -#define EXEC_LOAD_EVENT 0x0A -#define DELETE_FILE_EVENT 0x0B -#define NEW_LOAD_EVENT 0x0C -#define RAND_EVENT 0x0D -#define USER_VAR_EVENT 0x0E -#define FORMAT_DESCRIPTION_EVENT 0x0F -#define XID_EVENT 0x10 -#define BEGIN_LOAD_QUERY_EVENT 0x11 -#define EXECUTE_LOAD_QUERY_EVENT 0x12 -#define TABLE_MAP_EVENT 0x13 -#define WRITE_ROWS_EVENTv0 0x14 -#define UPDATE_ROWS_EVENTv0 0x15 -#define DELETE_ROWS_EVENTv0 0x16 -#define WRITE_ROWS_EVENTv1 0x17 -#define UPDATE_ROWS_EVENTv1 0x18 -#define DELETE_ROWS_EVENTv1 0x19 -#define INCIDENT_EVENT 0x1A -#define HEARTBEAT_EVENT 0x1B -#define IGNORABLE_EVENT 0x1C -#define ROWS_QUERY_EVENT 0x1D -#define WRITE_ROWS_EVENTv2 0x1E -#define UPDATE_ROWS_EVENTv2 0x1F -#define DELETE_ROWS_EVENTv2 0x20 -#define GTID_EVENT 0x21 -#define ANONYMOUS_GTID_EVENT 0x22 -#define PREVIOUS_GTIDS_EVENT 0x23 - -#define MAX_EVENT_TYPE 0x23 -#define MAX_EVENT_TYPE_MARIADB10 0xa3 - -/** - * Binlog event flags - */ -#define LOG_EVENT_BINLOG_IN_USE_F 0x0001 -#define LOG_EVENT_FORCED_ROTATE_F 0x0002 -#define LOG_EVENT_THREAD_SPECIFIC_F 0x0004 -#define LOG_EVENT_SUPPRESS_USE_F 0x0008 -#define LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F 0x0010 -#define LOG_EVENT_ARTIFICIAL_F 0x0020 -#define LOG_EVENT_RELAY_LOG_F 0x0040 -#define LOG_EVENT_IGNORABLE_F 0x0080 -#define LOG_EVENT_NO_FILTER_F 0x0100 -#define LOG_EVENT_MTS_ISOLATE_F 0x0200 - /** * Macros to extract common fields */ diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 477ca4cf0..3a5e8f52b 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -1080,7 +1080,7 @@ gw_backend_hangup(DCB *dcb) len = sizeof(error); if (getsockopt(dcb->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) == 0) { - if (error != 0) + if (error != 0 && ses_state != SESSION_STATE_STOPPING) { strerror_r(error, buf, 100); LOGIF(LE, (skygw_log_write_flush( @@ -1094,9 +1094,12 @@ gw_backend_hangup(DCB *dcb) goto retblock; } #if defined(SS_DEBUG) - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Backend hangup error handling."))); + if(ses_state != SESSION_STATE_STOPPING) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Backend hangup error handling."))); + } #endif router->handleError(router_instance, diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index c3e463139..bab5971a8 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -1092,7 +1092,8 @@ int gw_read_client_event( case MYSQL_IDLE: { uint8_t* payload = NULL; - + session_state_t ses_state; + session = dcb->session; ss_dassert(session!= NULL); @@ -1100,93 +1101,106 @@ int gw_read_client_event( { CHK_SESSION(session); } + spinlock_acquire(&session->ses_lock); + ses_state = session->state; + spinlock_release(&session->ses_lock); /* Now, we are assuming in the first buffer there is * the information form mysql command */ payload = GWBUF_DATA(read_buffer); - /** Route COM_QUIT to backend */ - if (MYSQL_IS_COM_QUIT(payload)) - { + if(ses_state == SESSION_STATE_ROUTER_READY) + { + /** Route COM_QUIT to backend */ + if (MYSQL_IS_COM_QUIT(payload)) + { /** - * Sends COM_QUIT packets since buffer is already - * created. A BREF_CLOSED flag is set so dcb_close won't - * send redundant COM_QUIT. - */ + * Sends COM_QUIT packets since buffer is already + * created. A BREF_CLOSED flag is set so dcb_close won't + * send redundant COM_QUIT. + */ SESSION_ROUTE_QUERY(session, read_buffer); /** - * Close router session which causes closing of backends. - */ + * Close router session which causes closing of backends. + */ dcb_close(dcb); - } - else - { + } + else + { /** Reset error handler when routing of the new query begins */ router->handleError(NULL, NULL, NULL, dcb, ERRACT_RESET, NULL); if (stmt_input) { - /** - * Feed each statement completely and separately - * to router. - */ - rc = route_by_statement(session, &read_buffer); - - if (read_buffer != NULL) - { - /** add incomplete mysql packet to read queue */ - dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer); - } + /** + * Feed each statement completely and separately + * to router. + */ + rc = route_by_statement(session, &read_buffer); + + if (read_buffer != NULL) + { + /** add incomplete mysql packet to read queue */ + dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer); + } } else { - /** Feed whole packet to router */ - rc = SESSION_ROUTE_QUERY(session, read_buffer); + /** Feed whole packet to router */ + rc = SESSION_ROUTE_QUERY(session, read_buffer); } - + /** Routing succeed */ if (rc) { - rc = 0; /**< here '0' means success */ + rc = 0; /**< here '0' means success */ } else { - bool succp; - GWBUF* errbuf; - /** - * Create error to be sent to client if session - * can't be continued. - */ - errbuf = mysql_create_custom_error( - 1, - 0, - "Routing failed. Session is closed."); - /** - * Ensure that there are enough backends - * available. - */ - router->handleError( - router_instance, - session->router_session, - errbuf, - dcb, - ERRACT_NEW_CONNECTION, - &succp); - gwbuf_free(errbuf); - /** - * If there are not enough backends close - * session - */ - if (!succp) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Routing the query failed. " - "Session will be closed."))); + bool succp; + GWBUF* errbuf; + /** + * Create error to be sent to client if session + * can't be continued. + */ + errbuf = mysql_create_custom_error( + 1, + 0, + "Routing failed. Session is closed."); + /** + * Ensure that there are enough backends + * available. + */ + router->handleError( + router_instance, + session->router_session, + errbuf, + dcb, + ERRACT_NEW_CONNECTION, + &succp); + gwbuf_free(errbuf); + /** + * If there are not enough backends close + * session + */ + if (!succp) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Routing the query failed. " + "Session will be closed."))); - dcb_close(dcb); - } + dcb_close(dcb); + } } - } + } + } + else + { + skygw_log_write_flush(LT,"Session received a query in state %s", + STRSESSIONSTATE(ses_state)); + while((read_buffer = GWBUF_CONSUME_ALL(read_buffer)) != NULL); + goto return_rc; + } goto return_rc; } /* MYSQL_IDLE */ break; diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index 8dce5ea58..7eac9e739 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -36,6 +36,7 @@ * 17/02/2015 Massimiliano Pinto Addition of slave port and username in diagnostics * 18/02/2015 Massimiliano Pinto Addition of dcb_close in closeSession * 07/05/2015 Massimiliano Pinto Addition of MariaDB 10 compatibility support + * 12/06/2015 Massimiliano Pinto Addition of MariaDB 10 events in diagnostics() * * @endverbatim @@ -682,6 +683,15 @@ static char *event_names[] = { "Anonymous GTID Event", "Previous GTIDS Event" }; +/* New MariaDB event numbers starts from 0xa0 */ +static char *event_names_mariadb10[] = { + "Annotate Rows Event", + /* New MariaDB 10.x event numbers */ + "Binlog Checkpoint Event", + "GTID Event", + "GTID List Event" +}; + /** * Display an entry from the spinlock statistics data * @@ -798,11 +808,28 @@ struct tm tm; buf); dcb_printf(dcb, "\t (%d seconds ago)\n", time(0) - router_inst->stats.lastReply); - dcb_printf(dcb, "\tLast event from master: 0x%x, %s", + + if (!router_inst->mariadb10_compat) { + dcb_printf(dcb, "\tLast event from master: 0x%x, %s", router_inst->lastEventReceived, (router_inst->lastEventReceived >= 0 && - router_inst->lastEventReceived < 0x24) ? + router_inst->lastEventReceived <= MAX_EVENT_TYPE) ? event_names[router_inst->lastEventReceived] : "unknown"); + } else { + char *ptr = NULL; + if (router_inst->lastEventReceived >= 0 && router_inst->lastEventReceived <= MAX_EVENT_TYPE) { + ptr = event_names[router_inst->lastEventReceived]; + } else { + /* Check MariaDB 10 new events */ + if (router_inst->lastEventReceived >= MARIADB_NEW_EVENTS_BEGIN && router_inst->lastEventReceived <= MAX_EVENT_TYPE_MARIADB10) { + ptr = event_names_mariadb10[(router_inst->lastEventReceived - MARIADB_NEW_EVENTS_BEGIN)]; + } + } + + dcb_printf(dcb, "\tLast event from master: 0x%x, %s", + router_inst->lastEventReceived, (ptr != NULL) ? ptr : "unknown"); + } + if (router_inst->lastEventTimestamp) { localtime_r(&router_inst->lastEventTimestamp, &tm); @@ -815,11 +842,17 @@ struct tm tm; if (router_inst->reconnect_pending) dcb_printf(dcb, "\tRouter pending reconnect to master\n"); dcb_printf(dcb, "\tEvents received:\n"); - for (i = 0; i < 0x24; i++) + for (i = 0; i <= MAX_EVENT_TYPE; i++) { dcb_printf(dcb, "\t\t%-38s %u\n", event_names[i], router_inst->stats.events[i]); } + if (router_inst->mariadb10_compat) { + /* Display MariaDB 10 new events */ + for (i = MARIADB_NEW_EVENTS_BEGIN; i <= MAX_EVENT_TYPE_MARIADB10; i++) + dcb_printf(dcb, "\t\tMariaDB 10 %-38s %u\n", event_names_mariadb10[(i - MARIADB_NEW_EVENTS_BEGIN)], router_inst->stats.events[i]); + } + #if SPINLOCK_PROFILE dcb_printf(dcb, "\tSpinlock statistics (instlock):\n"); spinlock_stats(&instlock, spin_reporter, dcb); diff --git a/server/modules/routing/binlog/blr_master.c b/server/modules/routing/binlog/blr_master.c index 3a0519108..86bee0b6b 100644 --- a/server/modules/routing/binlog/blr_master.c +++ b/server/modules/routing/binlog/blr_master.c @@ -917,6 +917,7 @@ static REP_HEADER phdr; phdr = hdr; if (hdr.ok == 0) { + int event_limit; /* * First check that the checksum we calculate matches the * checksum in the packet we received. @@ -957,8 +958,11 @@ static REP_HEADER phdr; #ifdef SHOW_EVENTS printf("blr: event type 0x%02x, flags 0x%04x, event size %d", hdr.event_type, hdr.flags, hdr.event_size); #endif - if (hdr.event_type >= 0 && hdr.event_type < 0x24) + event_limit = router->mariadb10_compat ? MAX_EVENT_TYPE_MARIADB10 : MAX_EVENT_TYPE; + + if (hdr.event_type >= 0 && hdr.event_type <= event_limit) router->stats.events[hdr.event_type]++; + if (hdr.event_type == FORMAT_DESCRIPTION_EVENT && hdr.next_pos == 0) { // Fake format description message diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index b4b080c16..48c78b2e2 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -723,16 +723,10 @@ routeQuery(ROUTER *instance, void *router_session, GWBUF *queue) SERVER_IS_DOWN(router_cli_ses->backend->server)) { LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, + LOGFILE_TRACE|LOGFILE_ERROR, "Error : Failed to route MySQL command %d to backend " - "server.", - mysql_command))); - skygw_log_write( - LOGFILE_ERROR, - "Error : Failed to route MySQL command %d to backend " - "server %s.", - mysql_command, - router_cli_ses->backend->server->unique_name); + "server.%s", + mysql_command,rses_is_closed ? " Session is closed." : ""))); rc = 0; goto return_rc; diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 3c329f646..b35a674c4 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -3915,7 +3915,7 @@ static GWBUF* sescmd_cursor_clone_querybuf( } ss_dassert(scur->scmd_cur_cmd != NULL); - buf = gwbuf_clone(scur->scmd_cur_cmd->my_sescmd_buf); + buf = gwbuf_clone_all(scur->scmd_cur_cmd->my_sescmd_buf); CHK_GWBUF(buf); return buf; @@ -4011,7 +4011,7 @@ static bool execute_sescmd_in_backend( bool succp; int rc = 0; sescmd_cursor_t* scur; - + GWBUF* buf; if(backend_ref == NULL) { skygw_log_write(LE,"Error: NULL parameter passed to execute_sescmd_in_backend. (%s:%d)",__FILE__,__LINE__); @@ -4048,27 +4048,9 @@ static bool execute_sescmd_in_backend( /** Cursor is left active when function returns. */ sescmd_cursor_set_active(scur, true); } -#if defined(SS_DEBUG) - LOGIF(LT, tracelog_routed_query(scur->scmd_cur_rses, - "execute_sescmd_in_backend", - backend_ref, - sescmd_cursor_clone_querybuf(scur))); - { - GWBUF* tmpbuf = sescmd_cursor_clone_querybuf(scur); - uint8_t* ptr = GWBUF_DATA(tmpbuf); - unsigned char cmd = MYSQL_GET_COMMAND(ptr); - - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [execute_sescmd_in_backend] Just before write, fd " - "%d : cmd %s.", - pthread_self(), - dcb->fd, - STRPACKETTYPE(cmd)))); - gwbuf_free(tmpbuf); - } -#endif /*< SS_DEBUG */ + buf = sescmd_cursor_clone_querybuf(scur); + switch (scur->scmd_cur_cmd->my_sescmd_packet_type) { case MYSQL_COM_CHANGE_USER: /** This makes it possible to handle replies correctly */ @@ -4077,7 +4059,7 @@ static bool execute_sescmd_in_backend( dcb, NULL, dcb->session, - sescmd_cursor_clone_querybuf(scur)); + buf); break; case MYSQL_COM_INIT_DB: @@ -4103,10 +4085,11 @@ static bool execute_sescmd_in_backend( * Mark session command buffer, it triggers writing * MySQL command to protocol */ + gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD); rc = dcb->func.write( dcb, - sescmd_cursor_clone_querybuf(scur)); + buf); break; } @@ -4116,6 +4099,7 @@ static bool execute_sescmd_in_backend( } else { + while((buf = GWBUF_CONSUME_ALL(buf)) != NULL); succp = false; } return_succp: diff --git a/server/modules/routing/schemarouter/shardrouter.c b/server/modules/routing/schemarouter/shardrouter.c index 94ab35974..c4148a237 100644 --- a/server/modules/routing/schemarouter/shardrouter.c +++ b/server/modules/routing/schemarouter/shardrouter.c @@ -1701,7 +1701,7 @@ routeQuery(ROUTER* instance, querybuf))) { extract_database(querybuf,db); - snprintf(errbuf,"Unknown database: %s",db); + snprintf(errbuf,25+MYSQL_DATABASE_MAXLEN,"Unknown database: %s",db); create_error_reply(errbuf,router_cli_ses->replydcb); LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR,