Merge branch 'release-1.2'

Conflicts:
	Documentation/Documentation-Contents.md
This commit is contained in:
Markus Makela 2015-07-15 16:34:27 +03:00
commit 4bb776f4e5
157 changed files with 7804 additions and 3134 deletions

View File

@ -6,38 +6,57 @@ endif()
message(STATUS "CMake version: ${CMAKE_VERSION}")
include(macros.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/macros.cmake)
enable_testing()
# Packaging builds install to /usr and other builds to /usr/local
if(PACKAGE)
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "Prefix prepended to install directories.")
endif()
# Set default values for cache entries and set the MaxScale version
set_variables()
set_maxscale_version()
set(CMAKE_INSTALL_PREFIX "/usr/local/mariadb-maxscale" CACHE PATH "Prefix prepended to install directories.")
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
project(MaxScale)
#Disabled for now pending evaluation
# Set the installation layout
include(${CMAKE_SOURCE_DIR}/cmake/install_layout.cmake)
#Do the platform check
include(cmake/CheckPlatform.cmake)
check_deps()
check_dirs()
find_package(OpenSSL)
find_package(Valgrind)
find_package(MySQLClient)
find_package(MySQL)
find_package(Pandoc)
find_package(TCMalloc)
find_package(Jemalloc)
find_package(CURL)
# You can find the variables set by this in the FindCURL.cmake file
# which is a default module in CMake.
find_package(CURL)
if(NOT CURL_FOUND)
message(FATAL_ERROR "Failed to locate dependency: libcurl")
endif()
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/lib:${CMAKE_INSTALL_PREFIX}/modules)
if(NOT OPENSSL_FOUND)
message(FATAL_ERROR "Failed to locate dependency: OpenSSL")
else()
if(OPENSSL_VERSION VERSION_LESS 1 AND NOT FORCE_OPENSSL100)
add_definitions("-DOPENSSL_0_9")
else()
add_definitions("-DOPENSSL_1_0")
endif()
endif()
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/${MAXSCALE_LIBDIR})
# Make sure the release notes for this release are present if it is a stable one
if(${MAXSCALE_VERSION} MATCHES "-stable")
@ -49,10 +68,12 @@ if(${MAXSCALE_VERSION} MATCHES "-stable")
endif()
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/server/include)
configure_file(${CMAKE_SOURCE_DIR}/server/include/version.h.in ${CMAKE_BINARY_DIR}/server/include/version.h)
configure_file(${CMAKE_SOURCE_DIR}/server/test/maxscale_test.h.in ${CMAKE_BINARY_DIR}/server/include/maxscale_test.h)
configure_file(${CMAKE_SOURCE_DIR}/etc/postinst.in ${CMAKE_BINARY_DIR}/postinst)
configure_file(${CMAKE_SOURCE_DIR}/etc/postrm.in ${CMAKE_BINARY_DIR}/postrm)
configure_file(${CMAKE_SOURCE_DIR}/server/include/version.h.in ${CMAKE_BINARY_DIR}/server/include/version.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/server/include/gwdirs.h.in ${CMAKE_BINARY_DIR}/server/include/gwdirs.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/server/test/maxscale_test.h.in ${CMAKE_BINARY_DIR}/server/include/maxscale_test.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/etc/postinst.in ${CMAKE_BINARY_DIR}/postinst @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/etc/postrm.in ${CMAKE_BINARY_DIR}/postrm @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/server/test/maxscale_test.cnf ${CMAKE_BINARY_DIR}/maxscale.cnf @ONLY)
set(FLAGS "-Wall -Wno-unused-variable -Wno-unused-function -fPIC" CACHE STRING "Compilation flags")
set(DEBUG_FLAGS "-ggdb -pthread -pipe -Wformat -fstack-protector --param=ssp-buffer-size=4" CACHE STRING "Debug compilation flags")
@ -70,7 +91,7 @@ if(CMAKE_VERSION VERSION_GREATER 2.6)
endif()
IF(DEFINED OLEVEL )
IF(DEFINED OLEVEL)
if((OLEVEL GREATER -1) AND (OLEVEL LESS 4) )
set(FLAGS "${FLAGS} -O${OLEVEL}" CACHE STRING "Compilation flags" FORCE)
message(STATUS "Optimization level at: ${OLEVEL}")
@ -93,7 +114,13 @@ if(PROFILE)
set(FLAGS "${FLAGS} -pg " CACHE STRING "Compilation flags" FORCE)
endif()
set(CMAKE_C_FLAGS "${FLAGS}")
if(USE_C99)
message(STATUS "Using C99 standard")
set(CMAKE_C_FLAGS "-std=c99 -D_GNU_SOURCE=1 ${FLAGS}")
else()
set(CMAKE_C_FLAGS "${FLAGS}")
endif()
set(CMAKE_C_FLAGS_DEBUG "${DEBUG_FLAGS} -DSS_DEBUG -DLOG_ASSERT")
set(CMAKE_C_FLAGS_RELEASE "")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-ggdb")
@ -128,7 +155,7 @@ if(NOT WITHOUT_MAXADMIN)
add_subdirectory(client)
endif()
# Generate text versions of some documents
execute_process(COMMAND perl ${CMAKE_SOURCE_DIR}/Documentation/format.pl
${CMAKE_SOURCE_DIR}/Documentation/Changelog.md
${CMAKE_BINARY_DIR}/Changelog.txt)
@ -138,23 +165,29 @@ ${CMAKE_SOURCE_DIR}/Documentation/Release-Notes/MaxScale-1.1-Release-Notes.md
execute_process(COMMAND perl ${CMAKE_SOURCE_DIR}/Documentation/format.pl
${CMAKE_SOURCE_DIR}/Documentation/Upgrading-To-MaxScale-1.1.0.md
${CMAKE_BINARY_DIR}/UpgradingToMaxScale110.txt)
install(FILES ${CMAKE_BINARY_DIR}/Changelog.txt DESTINATION .)
install(FILES ${CMAKE_BINARY_DIR}/ReleaseNotes.txt DESTINATION .)
install(FILES ${CMAKE_BINARY_DIR}/UpgradingToMaxScale110.txt DESTINATION .)
message(STATUS "Installing MaxScale to: ${CMAKE_INSTALL_PREFIX}/")
install(FILES server/MaxScale_template.cnf DESTINATION etc)
install(FILES server/MaxScale_BinlogServer_template.cnf DESTINATION etc)
install(FILES ${ERRMSG} DESTINATION mysql)
install(FILES ${CMAKE_SOURCE_DIR}/COPYRIGHT DESTINATION .)
install(FILES ${CMAKE_SOURCE_DIR}/README DESTINATION .)
install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION .)
install(DIRECTORY DESTINATION log)
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)
install(FILES ${CMAKE_SOURCE_DIR}/COPYRIGHT DESTINATION ${MAXSCALE_SHAREDIR})
install(FILES ${CMAKE_SOURCE_DIR}/README DESTINATION ${MAXSCALE_SHAREDIR})
install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ${MAXSCALE_SHAREDIR})
install(FILES etc/lsyncd_example.conf DESTINATION ${MAXSCALE_SHAREDIR})
install(FILES Documentation/maxscale.1 DESTINATION ${CMAKE_INSTALL_DATADIR}/man/man1)
# Install startup scripts and ldconfig files
if(WITH_SCRIPTS)
configure_file(${CMAKE_SOURCE_DIR}/maxscale.conf.in ${CMAKE_BINARY_DIR}/maxscale.conf @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/etc/maxscale.service.in ${CMAKE_BINARY_DIR}/maxscale.service @ONLY)
if(DEB_BASED)
configure_file(${CMAKE_SOURCE_DIR}/etc/ubuntu/init.d/maxscale.in ${CMAKE_BINARY_DIR}/maxscale @ONLY)
else()
@ -163,88 +196,89 @@ if(WITH_SCRIPTS)
if(PACKAGE)
message(STATUS "maxscale.conf will unpack to: /etc/ld.so.conf.d")
message(STATUS "startup scripts will unpack to to: /etc/init.d")
message(STATUS "systemd service files will unpack to to: /usr/lib/systemd/system")
install(FILES ${CMAKE_BINARY_DIR}/maxscale DESTINATION ${MAXSCALE_SHAREDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(FILES ${CMAKE_BINARY_DIR}/maxscale.conf DESTINATION ${MAXSCALE_SHAREDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(FILES ${CMAKE_BINARY_DIR}/maxscale.service DESTINATION ${MAXSCALE_SHAREDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
else()
install(FILES ${CMAKE_BINARY_DIR}/maxscale DESTINATION /etc/init.d
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(FILES ${CMAKE_BINARY_DIR}/maxscale.conf DESTINATION /etc/ld.so.conf.d
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(FILES ${CMAKE_BINARY_DIR}/maxscale.service DESTINATION /usr/lib/systemd/system
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
message(STATUS "Installing maxscale.conf to: /etc/ld.so.conf.d")
message(STATUS "Installing startup scripts to: /etc/init.d")
message(STATUS "Installing systemd service files to: /usr/lib/systemd/system")
endif()
endif()
# Only do packaging if configured
if(PACKAGE)
install(FILES ${CMAKE_BINARY_DIR}/maxscale DESTINATION .
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)
install(FILES ${CMAKE_BINARY_DIR}/maxscale.conf DESTINATION .
install(FILES ${CMAKE_BINARY_DIR}/maxscale.conf DESTINATION ${MAXSCALE_SHAREDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(FILES ${CMAKE_BINARY_DIR}/postinst DESTINATION .
install(FILES ${CMAKE_BINARY_DIR}/postinst DESTINATION ${MAXSCALE_SHAREDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(FILES ${CMAKE_BINARY_DIR}/postrm DESTINATION .
install(FILES ${CMAKE_BINARY_DIR}/postrm DESTINATION ${MAXSCALE_SHAREDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
if(${CMAKE_VERSION} VERSION_LESS 2.8.12)
message(WARNING "CMake version is ${CMAKE_VERSION}. Building of packages requires version 2.8.12 or greater.")
else()
# See if we are on a RPM-capable or DEB-capable system
find_program(RPMBUILD rpmbuild)
find_program(DEBBUILD dpkg-buildpackage)
set(CPACK_GENERATOR "TGZ")
if(NOT ( ${RPMBUILD} STREQUAL "RPMBUILD-NOTFOUND" ) )
message(STATUS "Generating RPM packages")
set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM")
endif()
if(NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" ) )
set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB")
execute_process(COMMAND dpgk --print-architecture OUTPUT_VARIABLE DEB_ARCHITECTURE)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${DEB_ARCHITECTURE})
set (CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
message(STATUS "Generating DEB packages for ${DEB_ARCHITECTURE}")
endif()
# Generic CPack configuration variables
set(CPACK_STRIP_FILES FALSE)
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_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)
set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_BINARY_DIR}/postinst;{CMAKE_BINARY_DIR}/postrm")
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)
set(CPACK_RPM_PACKAGE_NAME "maxscale")
set(CPACK_RPM_PACKAGE_VENDOR "MariaDB Corporation Ab")
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/etc /etc/ld.so.conf.d /etc/init.d /etc/rc.d/init.d")
set(CPACK_RPM_SPEC_MORE_DEFINE "%define ignore \#")
set(CPACK_RPM_USER_FILELIST "%ignore /etc/init.d")
set(CPACK_RPM_USER_FILELIST "%ignore /etc/ld.so.conf.d")
set(CPACK_RPM_USER_FILELIST "%ignore /etc")
# See if we are on a RPM-capable or DEB-capable system
find_program(RPMBUILD rpmbuild)
find_program(DEBBUILD dpkg-buildpackage)
set(CPACK_GENERATOR "TGZ")
if(NOT ( ${RPMBUILD} STREQUAL "RPMBUILD-NOTFOUND" ) )
include(cmake/package_rpm.cmake)
message(STATUS "Generating RPM packages")
endif()
if(NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" ) )
include(cmake/package_deb.cmake)
message(STATUS "Generating DEB packages for ${DEB_ARCHITECTURE}")
endif()
include(CPack)
endif()
endif()
add_custom_target(buildtests
COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N ${CMAKE_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N ${CMAKE_SOURCE_DIR}
COMMAND make
COMMENT "Building test suite..." VERBATIM
)
add_custom_target(testall
COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N ${CMAKE_SOURCE_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} -E copy_if_different ${CMAKE_SOURCE_DIR}/server/test/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/testall.cmake
COMMENT "Running full test suite..." VERBATIM)
add_custom_target(testcore
COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N ${CMAKE_SOURCE_DIR}
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 make install
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/server/test/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf
COMMAND ctest -R Internal
COMMENT "Running core test suite..." VERBATIM)
@ -274,7 +308,7 @@ endif()
# Testall target with Valgrind
if(VALGRIND_FOUND)
add_custom_target(testall-valgrind
COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N ${CMAKE_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N ${CMAKE_SOURCE_DIR}
COMMAND make install
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/server/test/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf
COMMAND /bin/sh -c "valgrind --track-fds=yes --leak-check=full --show-leak-kinds=all --log-file=${CMAKE_BINARY_DIR}/valgrind.log ${CMAKE_BINARY_DIR}/bin/maxscale -c ${CMAKE_BINARY_DIR} &>/dev/null"

View File

@ -1,37 +1,25 @@
Installation and startup
Untar the binary distribution in the desired location,
e.g. /usr/local/mariadb
e.g. /usr/local/mariadb-maxscale
Alternatively build from the source code using the instructions
in the README file and execute make install.
in the [Building MaxScale from Source Code](../Getting-Started/Building-MaxScale-from-Source-Code.md) document.
Simply set the environment variable MAXSCALE_HOME to point to the
MaxScale directory, found inside the path into which the files have been copied,
e.g. MAXSCALE_HOME=/usr/local/mariadb-maxscale
Also you will need to optionally set LD_LIBRARY_PATH to include the 'lib' folder,
found inside the path into which the files have been copied,
e.g. LD_LIBRARY_PATH=/usr/local/mariadb-maxscale/lib
Because we need the libmysqld library for parsing we must create a
valid my.cnf file to enable the library to be used. Copy the my.cnf
to $MAXSCALE_HOME/mysql/my.cnf.
To start MaxScale execute the command 'maxscale' from the bin folder,
e.g. /usr/local/mariadb-maxscale/bin/maxscale
You can start MaxScale using `service maxscale start` or `systemctl start maxscale` if you installed the init.d scripts
or by manually starting the process from the bin folder of the installation directory.
Configuration
You need to edit the file MaxScale.cnf in $MAXSCALE_HOME/etc, you should
define the set of server definitions you require, with the addresses
and ports of those servers. Also define the listening ports for your
various services.
You need to create or edit the maxscale.cnf file in the /etc folder.
Define the services you wish to provide, the set of server definitions
you require, with the addresses and ports of those servers and also
define the listening ports for your various services.
In order to view the internal activity of the gateway you can telnet to
In order to view the internal activity of MaxScale you can either use
the maxadmin client interface with the cli routing module or telnet to
the port defined for the telnet listener. Initially you may login with
the user name of "admin" and the password "mariadb". Once connected type
help for an overview of the commands and help <command> for the more
detailed help on commands. Use the add user command to add a new user,
this will also remove the admin/mariadb user.
this will also remove the admin/mariadb user. For a detailed guide about using the MaxAdmin interface, take a look at the [MaxAdmin](../Reference/MaxAdmin.md) guide.

View File

@ -5,7 +5,7 @@
## About MaxScale
- [About MaxScale](About/About-MaxScale.md)
- [Release Notes 1.1](Release-Notes/MaxScale-1.1-Release-Notes.md)
- [MaxScale 1.2.0 Release Notes](Release-Notes/MaxScale-1.2.0-Release-Notes.md)
- [Changelog](Changelog.md)
- [Limitations](About/Limitations.md)
- [COPYRIGHT](About/COPYRIGHT.md)
@ -13,20 +13,23 @@
## Getting Started
- [Getting Started with MaxScale](Getting-Started/Getting-Started-With-MaxScale.md)
- [MariaDB MaxScale Installation Guide](Getting-Started/MariaDB-MaxScale-Installation-Guide.md)
- [Building MaxScale from Source Code](Getting-Started/Building-MaxScale-from-Source-Code.md)
- [Configuration Guide](Getting-Started/Configuration-Guide.md)
## 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
- [MaxAdmin](Reference/MaxAdmin.md)
- [MaxScale HA with Corosync-Pacemaker](Reference/MaxScale-HA-with-Corosync-Pacemaker.md)
- [MaxScale HA with Lsyncd](Reference/MaxScale-HA-with-lsyncd.md)
- [How Errors are Handled in MaxScale](Reference/How-errors-are-handled-in-MaxScale.md)
- [Debug and Diagnostic Support](Reference/Debug-And-Diagnostic-Support.md)
- [Routing Hints](Reference/Hint-Syntax.md)
## Tutorials
@ -41,30 +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)
- [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)
## Utilities
- [RabbitMQ Consumer Client](filters/RabbitMQ-Consumer-Client.md)
## Routers
- [Simple Schema Sharding Router](routers/SchemaRouter.md)
- [RabbitMQ Consumer Client](Filters/RabbitMQ-Consumer-Client.md)
## Design Documents
@ -81,4 +89,7 @@ Here are detailed documents about the filters MaxScale offers. They contain conf
- [MaxScale 1.0 Release Notes](Release-Notes/MaxScale-1.0-Release-Notes.md)
- [MaxScale 1.0.1 Release Notes](Release-Notes/MaxScale-1.0.1-Release-Notes.md)
- [MaxScale 1.0.3 Release Notes](Release-Notes/MaxScale-1.0.3-Release-Notes.md)
- [MaxScale 1.1.0 Release Notes](Release-Notes/MaxScale-1.1-Release-Notes.md)
- [MaxScale 1.1.1 Release Notes](Release-Notes/MaxScale-1.1.1-Release-Notes.md)
- [MaxScale 1.2.0 Release Notes](Release-Notes/MaxScale-1.2.0-Release-Notes.md)

View File

@ -5,7 +5,7 @@ The database firewall filter is used to block queries that match a set of rules.
## Configuration
The database firewall filter only requires minimal configuration in the MaxScale.cnf file. The actual rules of the database firewall filter are located in a separate text file. The following is an example of a database firewall filter configuration in MaxScale.cnf.
The database firewall filter only requires minimal configuration in the maxscale.cnf file. The actual rules of the database firewall filter are located in a separate text file. The following is an example of a database firewall filter configuration in maxscale.cnf.
```
[DatabaseFirewall]

View File

@ -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
```

View File

@ -6,7 +6,7 @@ The Query Log All (QLA) filter is a filter module for MaxScale that is
## Configuration
The configuration block for the QLA filter requires the minimal filter options in it's section within the MaxScale.cnf file, stored in $MAXSCALE_HOME/etc/MaxScale.cnf.
The configuration block for the QLA filter requires the minimal filter options in it's section within the maxscale.cnf file, stored in /etc/maxscale.cnf.
```
[MyLogFilter]
type=filter

View File

@ -5,9 +5,9 @@ This filter is designed to extract queries and transform them into a canonical f
## Configuration
The configuration block for the **mqfilter** filter requires the minimal filter options in it’s section within the MaxScale.cnf file, stored in $MAXSCALE_HOME/etc/MaxScale.cnf. Although the filter will start, it will use the default values which only work with a freshly installed RabbitMQ server and use its default values. This setup is mostly intended for testing the filter.
The configuration block for the **mqfilter** filter requires the minimal filter options in it’s section within the maxscale.cnf file, stored in /etc/maxscale.cnf. Although the filter will start, it will use the default values which only work with a freshly installed RabbitMQ server and use its default values. This setup is mostly intended for testing the filter.
The following is an example of a mqfilter configuration in the MaxScale.cnf file used for actual logging of queries to a RabbitMQ broker on a different host.
The following is an example of a mqfilter configuration in the maxscale.cnf file used for actual logging of queries to a RabbitMQ broker on a different host.
```
[RabbitMQ]

View File

@ -6,7 +6,7 @@ The regex filter is a filter module for MaxScale that is able to rewrite query c
# Configuration
The configuration block for the Regex filter requires the minimal filter options in it’s section within the MaxScale.cnf file, stored in $MAXSCALE_HOME/etc/MaxScale.cnf.
The configuration block for the Regex filter requires the minimal filter options in it’s section within the maxscale.cnf file, stored in /etc/maxscale.cnf.
```
[MyRegexFilter]

View File

@ -6,7 +6,7 @@ The tee filter is a filter module for MaxScale is a "plumbing" fitting in the Ma
# Configuration
The configuration block for the TEE filter requires the minimal filter parameters in it’s section within the MaxScale.cnf file, stored in $MAXSCALE_HOME/etc/MaxScale.cnf, that defines the filter to load and the service to send the duplicates to. Currently the tee filter does not support multi-statements.
The configuration block for the TEE filter requires the minimal filter parameters in it’s section within the maxscale.cnf file, stored in /etc/maxscale.cnf, that defines the filter to load and the service to send the duplicates to. Currently the tee filter does not support multi-statements.
```
[DataMartFilter]

View File

@ -6,7 +6,7 @@ The top filter is a filter module for MaxScale that monitors every SQL statement
# Configuration
The configuration block for the TOP filter requires the minimal filter options in it’s section within the MaxScale.cnf file, stored in $MAXSCALE_HOME/etc/MaxScale.cnf.
The configuration block for the TOP filter requires the minimal filter options in it’s section within the maxscale.cnf file, stored in /etc/maxscale.cnf.
```
[MyLogFilter]

View File

@ -4,7 +4,7 @@ You will need a number of tools and libraries in order to achieve this.
* cmake version 2.8.12 or later
* gcc recommended version 4.4.7 or later
* gcc recommended version 4.4.7 or later (MariaDB 10 libraries require gcc 4.7 or newer)
* libaio
@ -22,13 +22,13 @@ 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
openssl-devel libaio libaio-devel librabbitmq-devel
openssl-devel libaio libaio-devel librabbitmq-devel libcurl-devel pcre-devel
```
In addition, if you wish to to build an RPM package include:
@ -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,24 +51,18 @@ 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.
```
build-essential libssl-dev libaio-dev ncurses-dev bison
cmake perl libtool librabbitmq-dev
cmake perl libtool librabbitmq-dev libcurl-dev libpcre3-dev
```
If you want to build a DEB package, you will also need:
@ -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.

View File

@ -27,16 +27,16 @@ connection failover| When a connection currently being used between MaxScale and
The MaxScale configuration is read from a file which can be located in a number of placing, MaxScale will search for the configuration file in a number of locations.
1. If the environment variable `MAXSCALE_HOME` is set then MaxScale will look for a configuration file called `MaxScale.cnf` in the directory `$MAXSCALE_HOME/etc`.
1. Location given with the --configdir=<path> command line argument
2. If `MAXSCALE_HOME` is not set or the configuration file is not in the location above MaxScale will look for a file in `/etc/MaxScale.cnf`.
Alternatively MaxScale can be started with the `-c` flag and the path of the MaxScale home directory tree.
2. MaxScale will look for a configuration file called `maxscale.cnf` in the directory `/etc/maxscale.cnf`
An explicit path to a configuration file can be passed by using the `-f` option to MaxScale.
The configuration file itself is based on the ".ini" file format and consists of various sections that are used to build the configuration, these sections define services, servers, listeners, monitors and global settings.
Please see the section about [Protocol Modules](#protocol-modules) for more details about MaxScale and the default directories where modules will be searched for.
### Global Settings
The global settings, in a section named `[MaxScale]`, allow various parameters that affect MaxScale as a whole to be tuned. Currently the only setting that is supported is the number of threads to use to handle the network traffic. MaxScale will also accept the section name of `[gateway]` for global settings. This is for backward compatibility with versions prior to the naming of MaxScale.
@ -101,6 +101,54 @@ log_debug=1
To disable the log use the value 0 and to enable it use the value 1.
#### `logdir`
Set the directory where the logfiles are stored. The folder needs to be both readable and writable by the user running MaxScale.
```
logdir=/tmp/
```
#### `datadir`
Set the directory where the data files used by MaxScale are stored. Modules can write to this directory and for example the binlogrouter uses this folder as the default location for storing binary logs.
```
datadir=/home/user/maxscale_data/
```
#### `libdir`
Set the directory where MaxScale looks for modules. The library directory is the only directory that MaxScale uses when it searches for modules. If you have custom modules for MaxScale, make sure you have them in this folder.
```
libdir=/home/user/lib64/
```
#### `cachedir`
Configure the directory MaxScale uses to store cached data. An example of cached data is the authentication data fetched from the backend servers. MaxScale stores this in case a connection to the backend server is not possible.
```
cachedir=/tmp/maxscale_cache/
```
#### `piddir`
Configure the directory for the PID file for MaxScale. This file contains the Process ID for the running MaxScale process.
```
piddir=/tmp/maxscale_cache/
```
#### `language`
Set the folder where the errmsg.sys file is located in. MaxScale will look for the errmsg.sys file installed with MaxScale from this folder.
```
language=/home/user/lang/
```
### Service
A service represents the database service that MaxScale offers to the clients. In general a service consists of a set of backend database servers and a routing algorithm that determines how MaxScale decides to send statements or route connections to those backend servers.
@ -193,7 +241,7 @@ Query OK, 0 rows affected (0.00 sec)
#### `passwd`
The passwd parameter provides the password information for the above user and may be either a plain text password or it may be an encrypted password. See the section on encrypting passwords for use in the MaxScale.cnf file. This user must be capable of connecting to the backend database and executing these SQL statements to load database names and grants from the backends:
The passwd parameter provides the password information for the above user and may be either a plain text password or it may be an encrypted password. See the section on encrypting passwords for use in the maxscale.cnf file. This user must be capable of connecting to the backend database and executing these SQL statements to load database names and grants from the backends:
* `SELECT user, host, password,Select_priv FROM mysql.user`.
* `SELECT user, host, db FROM mysql.db`
@ -278,6 +326,62 @@ Example:
connection_timeout=300
```
### Service and SSL
This section describes configuration parameters for services that control the SSL/TLS encryption method and the various certificate files involved in it. To enable SSL, you must configure the `ssl` parameter with either `enabled` or `required` and provide the three files for `ssl_cert`, `ssl_key` and `ssl_ca_cert`. After this, MySQL connections to this service can be encrypted with SSL.
#### `ssl`
This enables SSL connections to the service. If this parameter is set to either `required` or `enabled` and the three certificate files can be found (these are explained afterwards), then client connections will be encrypted with SSL. If the parameter is `enabled` then both SSL and non-SSL connections can connect to this service. If the parameter is set to `required` then only SSL connections can be used for this service and non-SSL connections will get an error when they try to connect to the service.
#### `ssl_key`
The SSL private key the service should use. This will be the private key that is used as the server side private key during a client-server SSL handshake. This is a required parameter for SSL enabled services.
#### `ssl_cert`
The SSL certificate the service should use. This will be the public certificate that is used as the server side certificate during a client-server SSL handshake. This is a required parameter for SSL enabled services.
#### `ssl_ca_cert`
This is the Certificate Authority file. It will be used to verify that both the client and the server certificates are valid. This is a required parameter for SSL enabled services.
### `ssl_version`
This parameter controls the level of encryption used. Accepted values are:
* SSLv3
* TLSv10
* TLSv11
* TLSv12
* MAX
### `ssl_cert_verification_depth`
The maximum length of the certificate authority chain that will be accepted. Accepted values are positive integers.
```
# Example
ssl_cert_verification_depth=10
```
Example SSL enabled service configuration:
```
[ReadWriteSplitService]
type=service
router=readwritesplit
servers=server1,server2,server3
user=myuser
passwd=mypasswd
ssl=required
ssl_cert=/home/markus/certs/server-cert.pem
ssl_key=/home/markus/certs/server-key.pem
ssl_ca_cert=/home/markus/certs/ca.pem
ssl_version=TLSv12
```
This configuration requires all connections to be encrypted with SSL. It also specifies that TLSv1.2 should be used as the encryption method. The paths to the server certificate files and the Certificate Authority file are also provided.
### Server
Server sections are used to define the backend database servers that can be formed into a service. A server may be a member of one or more services within MaxScale. Servers are identified by a server name which is the section name in the configuration file. Servers have a type parameter of server, plus address port and protocol parameters.
@ -318,7 +422,7 @@ The monitor has a username and password that is used to connect to all servers f
monitorpw=mymonitorpasswd
```
The monpasswd parameter may be either a plain text password or it may be an encrypted password. See the section on encrypting passwords for use in the MaxScale.cnf file.
The monpasswd parameter may be either a plain text password or it may be an encrypted password. See the section on encrypting passwords for use in the maxscale.cnf file.
### Listener
@ -467,7 +571,7 @@ Individual servers may define override values for the user and password the moni
#### `passwd`
The password parameter may be either a plain text password or it may be an encrypted password. See the section on encrypting passwords for use in the `MaxScale.cnf` file.
The password parameter may be either a plain text password or it may be an encrypted password. See the section on encrypting passwords for use in the `maxscale.cnf` file.
#### `monitor_interval`
@ -540,7 +644,7 @@ Default value is `2`. Write Timeout is the timeout in seconds for each attempt t
## Protocol Modules
The protocols supported by MaxScale are implemented as external modules that are loaded dynamically into the MaxScale core. These modules reside in the directory `$MAXSCALE_HOME/modules`, if the environment variable `$MAXSCALE_HOME` is not set it defaults to `/usr/local/mariadb-maxscale`. It may also be set by passing the `-c` option on the MaxScale command line.
The protocols supported by MaxScale are implemented as external modules that are loaded dynamically into the MaxScale core. These modules reside in the directory `/usr/lib64/maxscale`. The location can be overridden with the `libdir=PATH` parameter under the `[maxscale]` section. It may also be set by passing the `-B PATH` or `--libdir=PATH` option on the MaxScale command line.
### MySQLClient
@ -1024,7 +1128,7 @@ MariaDB [mysql]> grant REPLICATION CLIENT on *.* to 'maxscalemon'@'maxscalehost'
Query OK, 0 rows affected (0.00 sec)
```
MySQL monitor fetches the `@@server_id` variable and other informations from `SHOW SLAVE STATUS` in order to compute the replication topology tree that may include intermediate master servers, called relay servers.
MySQL monitor fetches the `@@server_id` variable and other information from `SHOW SLAVE STATUS` in order to compute the replication topology tree that may include intermediate master servers, called relay servers.
The *Master* server used by router modules is the so called "root master": a server that has the `SERVER_MASTER` status bit set and it's at the lowest level of the replication depth.
@ -1036,7 +1140,7 @@ Please note, those two options are not enabled by default.
### galeramon
The Galeramon monitor is a simple router designed for use with MySQL Galera cluster. To execute the galeramon monitor an entry as shown below should be added to the MaxScale configuration file.
The Galeramon monitor is a simple monitor designed for use with MySQL Galera cluster. To execute the galeramon monitor an entry as shown below should be added to the MaxScale configuration file.
```
[Galera Monitor]
@ -1259,7 +1363,7 @@ before being sent to the server. Note that the text in the match string is case-
The **tee** filter is a filter module for MaxScale that acts as a "plumbing" fitting in the MaxScale filter toolkit. It can be used in a filter pipeline of a service to make a copy of requests from the client and dispatch a copy of the request to another service within MaxScale.
The configuration block for the **tee** filter requires the minimal filter parameters in its section within the `MaxScale.cnf` file that defines the filter to load and the service to send the duplicates to.
The configuration block for the **tee** filter requires the minimal filter parameters in its section within the `maxscale.cnf` file that defines the filter to load and the service to send the duplicates to.
```
[ArchiveFilter]
@ -1274,7 +1378,7 @@ In addition parameters may be added to define patterns to match against to eithe
The top filter is a filter module for MaxScale that monitors every SQL statement that passes through the filter. It measures the duration of that statement, the time between the statement being sent and the first result being returned. The top N times are kept, along with the SQL text itself and a list sorted on the execution times of the query is written to a file upon closure of the client session.
The configuration block for the **top** filter requires the minimal filter options in its section within the `MaxScale.cnf` file, stored in `$MAXSCALE_HOME/etc/MaxScale.cnf`.
The configuration block for the **top** filter requires the minimal filter options in its section within the `maxscale.cnf` file, stored in `/etc/maxscale.cnf`.
```
[MyLogFilter]
@ -1286,31 +1390,6 @@ count=10
In addition parameters may be added to define patterns to match against to either include or exclude particular SQL statements to be duplicated. You may also define that the filter is only active for connections from a particular source or when a particular user is connected.
## Encrypting Passwords
Passwords stored in the MaxScale.cnf file may optionally be encrypted for added security. This is done by creation of an encryption key on installation of MaxScale. Encryption keys may be created manually by executing the maxkeys utility with the argument of the filename to store the key.
maxkeys $MAXSCALE_HOME/etc/.secrets
Changing the encryption key for MaxScale will invalidate any currently encrypted keys stored in the MaxScale.cnf file.
### Creating Encrypted Passwords
Encrypted passwords are created by executing the maxpasswd command with the password you require to encrypt as an argument. The environment variable `MAXSCALE_HOME` must be set, or MaxScale must be installed in the default location before maxpasswd can be executed.
maxpasswd MaxScalePw001
61DD955512C39A4A8BC4BB1E5F116705
The output of the maxpasswd command is a hexadecimal string, this should be inserted into the MaxScale.cnf file in place of the ordinary, plain text, password. MaxScale will determine this as an encrypted password and automatically decrypt it before sending it the database server.
```
[Split Service]
type=service
router=readwritesplit
servers=server1,server2,server3,server4
user=maxscale
password=61DD955512C39A4A8BC4BB1E5F116705
```
## Reloading Configuration
@ -1382,7 +1461,7 @@ and short notations
## Error Reporting
MaxScale is designed to be executed as a service, therefore all error reports, including configuration errors, are written to the MaxScale error log file. MaxScale will log to a set of files in the directory `$MAXSCALE_HOME/log`, the only exception to this is if the log directory is not writable, in which case a message is sent to the standard error descriptor.
MaxScale is designed to be executed as a service, therefore all error reports, including configuration errors, are written to the MaxScale error log file. By default, MaxScale will log to a set of files in the directory `/var/log/maxscale`, the only exception to this is if the log directory is not writable, in which case a message is sent to the standard error descriptor.
### Troubleshooting

View File

@ -1,4 +1,4 @@
# Getting Started With MariaDB MaxScale
# MariaDB MaxScale Installation Guide
## First Steps With MaxScale
@ -8,23 +8,31 @@ In this introduction to MaxScale the aim is to take the reader from the point of
The simplest way to install MaxScale is to use one of the binary packages that are available for download from the MariaDB website.
* Simply go to [www.mariadb.com](http://www.mariadb.com)
* Simply go to [http://www.mariadb.com/my_portal/download](http://www.mariadb.com/my_portal/download)
* Select the Downloads option from the Resources menu
* Sign in to MariaDB.com
* Find and click on the button "Download MariaDB MaxScale Binaries"
* Follow the instructions at the top of the page.
* Find the section on that page entitled MariaDB MaxScale
![image alt text](images/getting_started.png)
* Select your operating system from the drop down box
If you want to install only MaxScale, futher down you will find the product specific download pages. Click on the MariaDB MaxScale link and follow the distribution specific instructions.
* Instructions that are specific for your operating system will then appear
![image alt text](images/getting_started2.png)
![image alt text](images/image_1.png)
After you have installed MaxScale, you can start it.
* Follow these instructions to install MaxScale on your machine
```
systemctl start maxscale.service
```
Upon successful completion of the installation process you have a version of MaxScale that is missing only a configuration file before it can be started.
If your system does not support systemd you can start MaxScale using the installed init.d script.
```
service maxscale start
```
An example configuration file is installed into the `/etc/` folder. This file should be changed according to your needs.
## Building MaxScale From Source Code
@ -34,6 +42,8 @@ Alternatively you may download the MaxScale source and build your own binaries.
The first step in configuring your MaxScale is to determine what it is you want to achieve with your MaxScale and what environment it will run in. The later is probably the easiest starting point for choosing which configuration route you wish to take. There are two distinct database environments which the first GA release of MaxScale supports; MySQL Master/Slave Replication clusters and Galera Cluster.
For more details, refer to the [Configuration Guide](Configuration-Guide.md).
### Master/Slave Replication Clusters
There are two major configuration options available to use MaxScale with a MySQL Replication cluster; connection routing with separate read and write connections, or read/write splitting with a single connection. A separate tutorial is available for each of these configurations that describes how to build the configuration file for MaxScale that will work with your environment.
@ -54,21 +64,51 @@ It is also possible to use the Read/Write Splitter with Galera. Although it is n
As well as the four major configuration choices outlined above there are also other configurations sub-options that may be mixed with those to provide a variety of different configuration and functionality. The MaxScale filter concept allows the basic configurations to be built upon in a large variety of ways. A separate filter tutorial is available that discusses the concept and gives some examples of ways to use filters.
## Encrypting Passwords
Passwords stored in the maxscale.cnf file may optionally be encrypted for added security. This is done by creation of an encryption key on installation of MaxScale. Encryption keys may be created manually by executing the maxkeys utility with the argument of the filename to store the key. The default location MaxScale stores the keys is `/var/lib/maxscale`.
```
# Usage: maxkeys [PATH]
maxkeys /var/lib/maxscale/
```
Changing the encryption key for MaxScale will invalidate any currently encrypted keys stored in the maxscale.cnf file.
### Creating Encrypted Passwords
Encrypted passwords are created by executing the maxpasswd command with the location of the .secrets file and the password you require to encrypt as an argument.
```
# Usage: maxpasswd PATH PASSWORD
maxpasswd /var/lib/maxscale/ MaxScalePw001
61DD955512C39A4A8BC4BB1E5F116705
```
The output of the maxpasswd command is a hexadecimal string, this should be inserted into the maxscale.cnf file in place of the ordinary, plain text, password. MaxScale will determine this as an encrypted password and automatically decrypt it before sending it the database server.
```
[Split Service]
type=service
router=readwritesplit
servers=server1,server2,server3,server4
user=maxscale
password=61DD955512C39A4A8BC4BB1E5F116705
```
## Running MaxScale
MaxScale consists of a core executable and a number of modules that implement
the different protocols and routing algorithms. These modules are built as
shared objects that are loaded on demand. In order for MaxScale to find these
modules it will search using a predescribed search path. The rules are:
modules it will search using a configurable search path. The priority of these paths are:
1. Look in the current directory for the module
2. Look in $MAXSCALE_HOME/modules
3. Look in /usr/local/mariadb-maxscale/modules
Configuration is read by default from the file $MAXSCALE_HOME/etc/MaxScale.cnf, /etc/MaxScale.cnf. An example file is included in in the installation and can be found in the etc/ folder within the MaxScale installation. The default value of MAXSCALE_HOME can be overridden by using the -c flag on the command line. This should be immediately followed by the path to the MaxScale home directory. The -f flag can be used on the command line to set the name and the location of the configuration file. Without path expression the file is read from \$MAXSCALE_HOME/etc directory.
1. Look in the directory defined with --libdir=PATH during startup
2. Look in the directory defined with libdir=PATH in the configuration file under the [maxscale] section
3. Look in default directory in /usr/lib64/maxscale
Configuration is read by default from the file /etc/maxscale.cnf. An example file is included in in the installation and can be found in the /usr/share/maxscale folder within the MaxScale installation. The -f flag can be used on the command line to set the name and the location of the configuration file. The -C flag can be used to set the directory where the configuration file is searched for. Without the -f or -C flags, the file is read from the /etc directory.
## Administration Of MaxScale
There are various administration tasks that may be done with MaxScale, a client command, maxadmin, is available that will interact with a running MaxScale and allow the status of MaxScale to be monitored and give some control of the MaxScale functionality. There is a separate reference guide for the maxadmin utility and also a short administration tutorial that covers the common administration tasks that need to be done with MaxScale.
There are various administration tasks that may be done with MaxScale, a client command, maxadmin, is available that will interact with a running MaxScale and allow the status of MaxScale to be monitored and give some control of the MaxScale functionality. There is [a separate reference guide](../Reference/MaxAdmin.md) for the maxadmin utility and also [a short administration tutorial](../Tutorials/Administration-Tutorial.md) that covers the common administration tasks that need to be done with MaxScale.

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -0,0 +1,120 @@
# Galera Monitor
## Overview
The Galera Monitor is a monitoring module for MaxScale that monitors a Galera cluster. It detects whether nodes are a part of the cluster and if they are in sync with the rest of the cluster. It can also assign master and slave roles inside MaxScale, allowing Galera clusters to be used with modules designed for traditional master-slave clusters.
## Configuration
A minimal configuration for a monitor requires a set of servers for monitoring and a username and a password to connect to these servers. The user requires the REPLICATION CLIENT privilege to successfully monitor the state of the servers.
```
[Galera Monitor]
type=monitor
module=galeramon
servers=server1,server2,server3
user=myuser
passwd=mypwd
```
## Optional parameters for all monitors
Here are optional parameters that are common for all the monitors.
### `monitor_interval`
This is the time the monitor waits between each cycle of monitoring. The default value of 10000 milliseconds (10 seconds) should be lowered if you want a faster response to changes in the server states. The value is defined in milliseconds and the smallest possible value is 100 milliseconds.
```
monitor_interval=2500
```
### `backend_connect_timeout`
This parameter controls the timeout for connecting to a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 3 seconds.
```
backend_connect_timeout=6
```
### `backend_write_timeout`
This parameter controls the timeout for writing to a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 2 seconds.
```
backend_write_timeout=4
```
### `backend_read_timeout`
This parameter controls the timeout for reading from a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 1 seconds.
```
backend_read_timeout=2
```
## Galera Monitor optional parameters
These are optional parameters specific to the Galera Monitor.
### `disable_master_failback`
If a node marked as master inside MaxScale happens to fail and the master status is assigned to another node MaxScale will normally return the master status to the original node after it comes back up. With this option enabled, if the master status is assigned to a new node it will not be reassigned to the original node for as long as the new master node is running.
```
disable_master_failback=true
```
### `available_when_donor`
This option only has an effect if there is a single Galera node being backed up an XtraBackup instance. This causes the initial node to go into Donor state which would normally prevent if from being marked as a valid server inside MaxScale. If this option is enabled, a single node in Donor state where the method is XtraBackup will be kept in Synced state.
```
available_when_donor=true
```
### `disable_master_role_setting`
This disables the assignment of master and slave roles to the Galera cluster nodes. If this option is enabled, Synced is the only status assigned by this monitor.
```
disable_master_role_setting=true
```
### `script`
This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path.
```
script=/home/user/script.sh
```
### `events`
A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names.
```
events=master_down,slave_down
```
## Script events
Here is a table of all possible event types and their descriptions.
Event Name|Description
----------|----------
master_down|A Master server has gone down
master_up|A Master server has come up
slave_down|A Slave server has gone down
slave_up|A Slave server has come up
server_down|A server with no assigned role has gone down
server_up|A server with no assigned role has come up
synced_down|A synced Galera node has come up
synced_up|A synced Galera node has gone down
lost_master|A server lost Master status
lost_slave|A server lost Slave status
lost_synced|A Galera node lost synced status
new_master|A new Master was detected
new_slave|A new Slave was detected
new_synced|A new synced Galera node was detected

View File

@ -0,0 +1,107 @@
# Multi-Master Monitor
## Overview
The Multi-Master Monitor is a monitoring module for MaxScale that monitors Master-Master replication. It assigns master and slave roles inside MaxScale based on whether the read_only parameter on a server is set to off or on.
## Configuration
A minimal configuration for a monitor requires a set of servers for monitoring and a username and a password to connect to these servers. The user requires the REPLICATION CLIENT privilege to successfully monitor the state of the servers.
```
[Multi-Master Monitor]
type=monitor
module=mmmon
servers=server1,server2,server3
user=myuser
passwd=mypwd
```
## Optional parameters for all monitors
Here are optional parameters that are common for all the monitors.
### `monitor_interval`
This is the time the monitor waits between each cycle of monitoring. The default value of 10000 milliseconds (10 seconds) should be lowered if you want a faster response to changes in the server states. The value is defined in milliseconds and the smallest possible value is 100 milliseconds.
```
monitor_interval=2500
```
### `backend_connect_timeout`
This parameter controls the timeout for connecting to a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 3 seconds.
```
backend_connect_timeout=6
```
### `backend_write_timeout`
This parameter controls the timeout for writing to a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 2 seconds.
```
backend_write_timeout=4
```
### `backend_read_timeout`
This parameter controls the timeout for reading from a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 1 seconds.
```
backend_read_timeout=2
```
## Multi-Master Monitor optional parameters
These are optional parameters specific to the Multi-Master Monitor.
### `detect_stale_master`
Allow previous master to be available even in case of stopped or misconfigured replication. This allows services that depend on master and slave roles to continue functioning as long as the master server is available.
This is a situation which can happen if all slave servers are unreachable or the replication breaks for some reason.
```
detect_stale_master=true
```
### `script`
This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path.
```
script=/home/user/script.sh
```
This script will be called with the following command line arguments.
```
<name of the script> --event=<event type> --initiator=<server whose state changed> --nodelist=<list of all servers>
```
### `events`
A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names.
```
events=master_down,slave_down
```
## Script events
Here is a table of all possible event types and their descriptions.
Event Name|Description
----------|----------
master_down|A Master server has gone down
master_up|A Master server has come up
slave_down|A Slave server has gone down
slave_up|A Slave server has come up
server_down|A server with no assigned role has gone down
server_up|A server with no assigned role has come up
lost_master|A server lost Master status
lost_slave|A server lost Slave status
new_master|A new Master was detected
new_slave|A new Slave was detected

View File

@ -0,0 +1,155 @@
# MySQL Monitor
## Overview
The MySQL Monitor is a monitoring module for MaxScale that monitors a Master-Slave replication cluster. It assigns master and slave roles inside MaxScale according to the actual replication tree in the cluster.
## Configuration
A minimal configuration for a monitor requires a set of servers for monitoring and a username and a password to connect to these servers. The user requires the REPLICATION CLIENT privilege to successfully monitor the state of the servers.
```
[MySQL Monitor]
type=monitor
module=mysqlmon
servers=server1,server2,server3
user=myuser
passwd=mypwd
```
## Optional parameters for all monitors
Here are optional parameters that are common for all the monitors.
### `monitor_interval`
This is the time the monitor waits between each cycle of monitoring. The default value of 10000 milliseconds (10 seconds) should be lowered if you want a faster response to changes in the server states. The value is defined in milliseconds and the smallest possible value is 100 milliseconds.
```
monitor_interval=2500
```
### `backend_connect_timeout`
This parameter controls the timeout for connecting to a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 3 seconds.
```
backend_connect_timeout=6
```
### `backend_write_timeout`
This parameter controls the timeout for writing to a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 2 seconds.
```
backend_write_timeout=4
```
### `backend_read_timeout`
This parameter controls the timeout for reading from a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 1 seconds.
```
backend_read_timeout=2
```
## MySQL Monitor optional parameters
These are optional parameters specific to the MySQL Monitor.
### `detect_replication_lag`
Detect replication lag between the master and the slaves. This allows the routers to route read queries to only slaves that are up to date.
```
detect_replication_lag=true
```
### `detect_stale_master`
Allow previous master to be available even in case of stopped or misconfigured
replication. This allows services that depend on master and slave roles to continue functioning as long as the master server is available.
This is a situation which can happen if all slave servers are unreachable or the replication breaks for some reason.
```
detect_stale_master=true
```
### `script`
This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path.
```
script=/home/user/script.sh
```
This script will be called with the following command line arguments.
```
<name of the script> --event=<event type> --initiator=<server whose state changed> --nodelist=<list of all servers>
```
### `events`
A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names.
```
events=master_down,slave_down
```
### `mysql51_replication`
Enable support for MySQL 5.1 replication monitoring. This is needed if a MySQL server older than 5.5 is used as a slave in replication.
```
mysql51_replication=true
```
## Script events
Here is a table of all possible event types and their descriptions.
Event Name|Description
----------|----------
master_down|A Master server has gone down
master_up|A Master server has come up
slave_down|A Slave server has gone down
slave_up|A Slave server has come up
server_down|A server with no assigned role has gone down
server_up|A server with no assigned role has come up
lost_master|A server lost Master status
lost_slave|A server lost Slave status
new_master|A new Master was detected
new_slave|A new Slave was detected
## Example 1 - Monitor script
Here is an example shell script which sends an email to an admin when a server goes down.
```
#!/usr/bin/env bash
#This script assumes that the local mail server is configured properly
#The second argument is the event type
event=${$2/.*=/}
server=${$3/.*=/}
message="A server has gone down at `date`."
echo $message|mail -s "The event was $event for server $server." admin@my.org
```
Here is a monitor configuration that only triggers the script when a master or a slave server goes down.
```
[Database Monitor]
type=monitor
module=mysqlmon
servers=server1,server2
script=mail_to_admin.sh
events=master_down,slave_down
```
When a master or a slave server goes down, the script is executed, a mail is sent and the administrator will be immediately notified of any possible problems.
This is just a simple example showing what you can do with MaxScale and monitor scripts.

View File

@ -0,0 +1,102 @@
# NDB Cluster Monitor
## Overview
The MySQL Cluster Monitor is a monitoring module for MaxScale that monitors a MySQL Cluster. It assigns a NDB status for the server if it is a part of a MySQL Cluster.
## Configuration
A minimal configuration for a monitor requires a set of servers for monitoring and a username and a password to connect to these servers. The user requires the REPLICATION CLIENT privilege to successfully monitor the state of the servers.
```
[MySQL Cluster Monitor]
type=monitor
module=ndbclustermon
servers=server1,server2,server3
user=myuser
passwd=mypwd
```
## Optional parameters for all monitors
Here are optional parameters that are common for all the monitors.
### `monitor_interval`
This is the time the monitor waits between each cycle of monitoring. The default value of 10000 milliseconds (10 seconds) should be lowered if you want a faster response to changes in the server states. The value is defined in milliseconds and the smallest possible value is 100 milliseconds.
```
monitor_interval=2500
```
### `backend_connect_timeout`
This parameter controls the timeout for connecting to a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 3 seconds.
```
backend_connect_timeout=6
```
### `backend_write_timeout`
This parameter controls the timeout for writing to a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 2 seconds.
```
backend_write_timeout=4
```
### `backend_read_timeout`
This parameter controls the timeout for reading from a monitored server. It is in seconds and the minimum value is 1 second. The default value for this parameter is 1 seconds.
```
backend_read_timeout=2
```
## MySQL Cluster Monitor optional parameters
These are optional parameters specific to the MySQL Cluster Monitor.
### `script`
This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path.
```
script=/home/user/script.sh
```
This script will be called with the following command line arguments.
```
<name of the script> --event=<event type> --initiator=<server whose state changed> --nodelist=<list of all servers>
```
### `events`
A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names.
```
events=master_down,slave_down
```
## Script events
Here is a table of all possible event types and their descriptions that the MySQL Cluster monitor can be called with.
Event Name|Description
----------|----------
master_down|A Master server has gone down
master_up|A Master server has come up
slave_down|A Slave server has gone down
slave_up|A Slave server has come up
server_down|A server with no assigned role has gone down
server_up|A server with no assigned role has come up
ndb_down|A MySQL Cluster node has gone down
ndb_up|A MySQL Cluster node has come up
lost_master|A server lost Master status
lost_slave|A server lost Slave status
lost_ndb|A MySQL Cluster node lost node membership
new_master|A new Master was detected
new_slave|A new Slave was detected
new_ndb|A new MySQL Cluster node was found

View File

@ -1679,7 +1679,7 @@ Loaded 34 users.
## Reload config
The reload config command can be used to force MaxScale to re-read the MaxScale.cnf and update itself to the latest configuration defined in that configuration file. It is also possible to force the reading of the configuration file by sending a HangUp signal (SIGHUP) to the maxscale process.
The reload config command can be used to force MaxScale to re-read the maxscale.cnf and update itself to the latest configuration defined in that configuration file. It is also possible to force the reading of the configuration file by sending a HangUp signal (SIGHUP) to the maxscale process.
**MaxScale>** reload config
@ -1711,7 +1711,7 @@ User admin already exists.
**MaxScale>**** **
If you should forget or lose the the account details you may simply remove the passwd file in $MAXSCALE_HOME/etc and the system will revert to the default behavior with admin/mariadb as the account.
If you should forget or lose the the account details you may simply remove the passwd file in /var/cache/maxscale and the system will revert to the default behavior with admin/mariadb as the account.
## Enable/disable log
@ -1745,7 +1745,7 @@ MaxScale generates output of its behavior to four distinct logs, error, messages
## Log contents
By default all log files are located in : $MAXSCALE_HOME/log and named as :
By default all log files are located in : /var/log/maxscale and named as :
skygw_errW.log, skygw_msgX.log, skygw_traceY.log and skygw_debugZ.log
@ -1789,7 +1789,7 @@ MariaDB Corporation MaxScale /home/jdoe/bin/develop/log/skygw_msg1.log Tue Dec
2014-12-09 14:47:05 Log directory : /home/jdoe/bin/develop/log
2014-12-09 14:47:05 Configuration file : /home/jdoe/bin/develop/etc/MaxScale.cnf
2014-12-09 14:47:05 Configuration file : /home/jdoe/bin/develop/etc/maxscale.cnf
2014-12-09 14:47:05 Initialise CLI router module V1.0.0.
@ -1837,7 +1837,7 @@ MariaDB Corporation MaxScale /home/jdoe/bin/develop/log/skygw_msg1.log Tue Dec
### Trace log
Trace log includes information about available servers and their states, client sessions, queries being executed, routing decisions and other routing related data. Trace log can be found from the same directory with other logs but it is physically stored elsewhere, to OSs shared memory to reduce the latency caused by logging. The location of physical file is : /dev/shm/<pid>/skygw_traceX.log where ‘X’ is the same sequence number as in the file name in the $MAXSCALE_HOME/log directory.
Trace log includes information about available servers and their states, client sessions, queries being executed, routing decisions and other routing related data. Trace log can be found from the same directory with other logs but it is physically stored elsewhere, to OSs shared memory to reduce the latency caused by logging. The location of physical file is : /dev/shm/<pid>/skygw_traceX.log where ‘X’ is the same sequence number as in the file name in the /var/log/maxscale directory.
Individual trace log entry looks similar to those in other logs but there is some difference too. Some log entries include a number within square brackets to specify which client session they belong to. For example:
@ -1923,11 +1923,11 @@ In the log, session’s life cycle is covered by annotating its beginning and th
The log files are located in
$MAXSCALE_HOME/log
/var/log/maxscale
by default. If, however, trace and debug logs are enabled, only a soft link is created there. MaxScale process creates a directory under
/dev/shm/<pid>
/dev/shm/maxscale.<pid>
where it stores the physical trace and debug log files. Link and physical files share the same name. These logs consume the main memory of the host they run on so it is important to archive or remove them periodically to avoid unnecessary main-memory consumption.

View File

@ -1,42 +1,97 @@
# Hint Syntax
Use either ’-- ’ (notice the whitespace) or ’#’ after the semicolon or ’/* .. */’ before
the semicolon.
## Enabling routing hints
The MySQL manual doesn’t specify if comment blocks, i.e. ’/* .. */’, should contain a w
hitespace character before or after the tags.
To enable routing hints for a service, the hintfilter module needs to be configured and the filter needs to be applied to the service.
All hints must start with the ’maxscale tag’:
-- maxscale <hint>
The hints right now have two types, ones that route to a server and others that contain
Here is an example service which has the hint filter configured and applied.
```
[Read Service]
type=service
router=readconnroute
router_options=master
servers=server1
user=maxuser
passwd=maxpwd
filter=Hint
[Hint]
type=filter
module=hintfilter
```
## Comments and comment types
The client connection will need to have comments enabled. For example the `mysql` command line client has comments disabled by default.
For comment types, use either `-- ` (notice the whitespace) or `#` after the semicolon or `/* .. */` before the semicolon. All comment types work with routing hints.
The MySQL manual doesn`t specify if comment blocks, i.e. `/* .. */`, should contain a w
hitespace character before or after the tags, so adding whitespace at both the start and the end is advised.
## Hint body
All hints must start with the `maxscale` tag.
```
-- maxscale <hint body>
```
The hints have two types, ones that route to a server and others that contain
name-value pairs.
Routing queries to a server:
###Routing destination hints
These hints will instruct the router to route a query to a certain type of a server.
```
-- maxscale route to [master | slave | server <server name>]
```
The name of the server is the same as in MaxScale.cnf
A `master` value in a routing hint will route the query to a master server. This can be used to direct read queries to a master server for a up-to-date result with no replication lag. A `slave` value will route the query to a slave server. A `server` value will route the query to a named server. The value of <server name> needs to be the same as the server section name in maxscale.cnf.
Creating a name-value pair:
### Name-value hints
These control the behavior and affect the routing decisions made by the router.
```
-- maxscale <param>=<value>
```
Currently the only accepted parameter is
’max_slave_replication_lag’
Currently the only accepted parameter is `max_slave_replication_lag`. This will route the query to a server with lower replication lag then what is defined in the hint value.
## Hint stack
Hints can be either single-use hints, which makes them affect only one query, or named
hints, which can be pushed on and off a stack of active hints.
Defining named hints:
```
-- maxscale <hint name> prepare <hint content>
```
Pushing a hint onto the stack:
```
-- maxscale <hint name> begin
```
Popping the topmost hint off the stack:
```
-- maxscale end
```
You can define and activate a hint in a single command using the following:
```
-- maxscale <hint name> begin <hint content>
```
You can also push anonymous hints onto the stack which are only used as long as they are on the stack:
-- maxscale begin <hint content>
```
-- maxscale begin <hint content>
```

View File

@ -591,7 +591,7 @@ Some monitors provide a replication heartbeat mechanism that monitors the delay
MaxScale> enable heartbeat "MySQL Monitor"
MaxScale>
Please note that changes made via this interface will not persist across restarts of MaxScale. To make a permanent change edit the MaxScale.cnf file.
Please note that changes made via this interface will not persist across restarts of MaxScale. To make a permanent change edit the maxscale.cnf file.
Enabling the replication heartbeat mechanism will add the display of heartbeat information in the show server output
@ -786,11 +786,11 @@ Two commands are provided to change the logging levels within MaxScale, disable
MaxScale> disable log debug
MaxScale>
Please note that changes made via this interface will not persist across restarts of MaxScale. To make a permanent change edit the MaxScale.cnf file.
Please note that changes made via this interface will not persist across restarts of MaxScale. To make a permanent change edit the maxscale.cnf file.
## Reloading The Configuration
A command, reload config, is available that will cause MaxScale to reload the MaxScale.cnf configuration file.
A command, reload config, is available that will cause MaxScale to reload the maxscale.cnf configuration file.
## Shutting Down MaxScale
@ -798,7 +798,7 @@ The MaxScale server may be shutdown using the shutdown maxscale command.
# Configuring MaxScale to Accept MaxAdmin Connections
In order to allow the use of the MaxAdmin client interface the service must be added to the MaxScale.cnf file of the Maxscale server. The CLI service itself must be added and a listener for the maxscaled protocol.
In order to allow the use of the MaxAdmin client interface the service must be added to the maxscale.cnf file of the Maxscale server. The CLI service itself must be added and a listener for the maxscaled protocol.
The default entries required are shown below.

View File

@ -0,0 +1,184 @@
# MaxScale HA with Lsyncd
***This guide was written for lsyncd 2.1.5.***
This document guides you in setting up multiple MaxScale instances and synchronizing the configuration files with lsyncd. Lsyncd is a rsync wrapper which can synchronize files across the network. The lsyncd daemon uses a configuration file to control the files to synchronize and the remote targets where these files are synchronized to.
Copying the configuration file and running the lsyncd daemon on all the hosts keeps all the configuration files in sync. Modifications in the configuration file on one of the hosts will be copied on the other hosts. This allows adinistrators to easily provide a highly available, disaster resistant MaxScale installation with up-to-date configuration files on all the hosts.
### Requirements
You will need:
* Access to the remote hosts.
* MaxScale installed on all systems
* Configured maxscale.cnf file in /etc
* SSH daemon and clients installed on all hosts
The installation and configuration of MaxScale is covered in other documents.
## Creating SSH keys
For lsyncd to work, we will need to either use an existing set of SSH keys or to create a new set of keys. The creation and copying of keys needs to be repeated on all of the hosts.
If you already have a SSH key generated, you can skip this next step and go to the Copying Keys part.
### Generating keys
To generate a new set of SSH keys, we will use `ssh-keygen`.
```
[root@localhost ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
f4:99:0a:cc:d4:ac:ea:ed:ff:0d:bb:e5:87:3e:38:df root@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
| |
| o |
| . + |
| + o . o |
| = S + |
| . . . |
| . . .... |
| . . o*o.. |
| ..o...+==oE |
+-----------------+
```
The keys will be generated in the .ssh folder and will automatically be used by ssh.
### Copying keys
To copy the SSH keys to the remote host we will use `ssh-copy-id`.
Use the username and host of the remote server you wish to synchronize MaxScale's configuration files to. For example, if the server's address is 192.168.122.100 and the user we use for synchronization us `user` we can use the following command.
```
ssh-copy-id user@192.168.122.100
```
Repeat the last command with the usernames and addresses of all the remote hosts you want to synchronize the configuration files to.
## Installing lsyncd
You will need to install lsyncd on all of the hosts for changes in the configuration file on one of the nodes to be synchronized to the other nodes.
You can install lsyncd with either a package manager or by building from source code. This guide demonstrates installation using a package manager and those looking to build lsyncd from source should refer to its documentation: https://github.com/axkibe/lsyncd/wiki/Manual-to-Lsyncd-2.1.x
Installing with Yum:
```
yum install lsyncd
```
Installing with Apt:
```
apt-get install lsyncd
```
## Creating the Lsyncd configuration file
Lsyncd uses a configuration file to determine where to read files from and where to synchronize them if changes in them occur. Lsyncd is written in Lua and the configuration file is also valid Lua code.
Here is an example configuration file with descriptions on the meaning of the values in it.
```
-- Lsyncd will log to these two files.
settings{
logfile = "/var/log/maxscale/maxscale-ha.log",
statusFile = "/var/log/maxscale/maxscale-ha-status.log"
}
-- Copy and paste the sync section and change the host value to add new remote targets.
sync{
default.rsyncssh,
-- This is where the maxscale.cnf file is copied from.
source="/etc",
-- This is the user and host where the maxscale.cnf is copied to.
-- Change this to the user and destination host where you want maxscale.cnf to be synchronized to.
host="user@192.168.122.100",
-- This is where the maxscale.cnf is copied to on the remote host.
targetdir="/etc",
-- This is an optional section which defines a custom SSH port. Uncomment to enable.
-- ssh={port=2222},
-- These are values passed to rsync. Only change these if you know what you are doing.
rsync={
compress=true,
_extra = {[[--filter=+ *maxscale.cnf]],
[[--filter=- **]]
}
}
}
```
The most important part is the `sync` section which defines a target for synchronization. The `default.rsyncssh` tells lsyncd to synchronize files using SSH.
The `source` parameter tells lsyncd where to read the files from. This should be the location of the maxscale.cnf file. The `host` parameter defines the host where the files should be synchronized to and the user account lsyncd should use when synchronizing the files. The `targetdir` parameter defines the local directory on the remote target where the files should be synchronized to. This value should be the location on the remote host where the maxscale.cnf file is searched from. By default, this is the `/etc` folder.
The optional `ssh` parameter and its sub-parameter `port`define a custom port for the SSH connection. Most users do not need this parameterer. The `rsycn` parameter contains an arra of options that are passed to the rsycn executable. These should not be changed unless you specifically know what you are doing. For more information on the options passed to rsync read the rsync(1) manpage.
You can add multiple remote targets by defining multiple `sync` sections. Here is an example with two sync sections defining different hosts that have MaxScale installed and whose configuration files should be kep in sync.
```
settings{
logfile = "/var/log/maxscale/maxscale-ha.log",
statusFile = "/var/log/maxscale/maxscale-ha-status.log"
}
sync{
default.rsyncssh,
source="/etc",
host="maxuser@192.168.0.50",
targetdir="/etc",
rsync={
compress=true,
_extra = {[[--filter=+ *maxscale.cnf]],
[[--filter=- **]]
}
}
}
sync{
default.rsyncssh,
source="/etc",
host="syncuser@192.168.122.105",
targetdir="/etc",
rsync={
compress=true,
_extra = {[[--filter=+ *maxscale.cnf]],
[[--filter=- **]]
}
}
}
```
## Starting Lsyncd
Starting lsyncd can be done from the command line or through a init script. To start syncd from the command like, execute the `lsyncd` command and pass the configuration file as the only parameter.
By default lsyncd will search for the configuration file in `/etc/lsyncd.conf`. By placing the configuration file we created in the `/etc` folder, we can start lsyncd with the following command.
```
service lsyncd start
```
Here is an example which start lsyncd and reads the configuration options from the `lsyncd.cnf` file.
```
lsyncd lsyncd.cnf
```
For more information on the lsyncd executable and its options, please see the --help output of lsyncd or the lsyncd(1) manpage.

View File

@ -0,0 +1,15 @@
# MaxScale and SSL
MaxScale supports client side SSL connections. Enabling is done on a per service basis and each service has its own set of certificates.
## SSL Options
Here are the options which relate to SSL and certificates.
Parameter|Values |Description
---------|-----------|--------
ssl | disabled, enabled, required |`disable` disables SSL, `enabled` enables SSL for client connections but still allows non-SSL connections and `required` requires SSL from all client connections. With the `required` option, client connections that do not use SSL will be rejected.
ssl_cert | path to file |Path to server certificate
ssl_key | path to file |Path to server private key
ssl_ca_cert | path to file |Path to Certificate Authority file
ssl_version|SSLV3,TLSV10,TLSV11,TLSV12,MAX| The SSL method level, defaults to highest available encryption level which is TLSv1.2
ssl_cert_verify_depth|integer|Certificate authority certificate verification depth, default is 100.

View File

@ -1,4 +1,4 @@
MaxScale Release Notes
# MariaDB MaxScale 0.5 Alpha Release Notes
0.5 Alpha

View File

@ -1,4 +1,4 @@
MaxScale Release Notes
# MariaDB MaxScale 0.6 Alpha Release Notes
0.6 Alpha

View File

@ -1,4 +1,4 @@
MaxScale Release Notes
# MariaDB MaxScale 0.7 Alpha Release Notes
0.7 Alpha

View File

@ -1,4 +1,4 @@
MaxScale Release Notes
# MariaDB MaxScale 1.0 Beta Release Notes
1.0 Beta

View File

@ -1,4 +1,4 @@
MaxScale Release Notes
# MariaDB MaxScale 1.0.1 Beta Release Notes
1.0.1 Beta
@ -107,11 +107,11 @@ A number of bug fixes have been applied between the 1.0 beta release and this re
</tr>
<tr>
<td>479</td>
<td>Undefined filter reference in MaxScale.cnf causes a crash</td>
<td>Undefined filter reference in maxscale.cnf causes a crash</td>
</tr>
<tr>
<td>410</td>
<td>MaxScale.cnf server option is not parsed for spaces</td>
<td>maxscale.cnf server option is not parsed for spaces</td>
</tr>
<tr>
<td>417</td>

View File

@ -1,4 +1,4 @@
MaxScale Release Notes
# MariaDB MaxScale 1.0.3 Release Notes
1.0.3 GA

View File

@ -1,4 +1,4 @@
# MaxScale Release Notes
# MariaDB MaxScale 1.0.4 Release Notes
1.0.4 GA

View File

@ -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.

View File

@ -1,4 +1,4 @@
# MaxScale Release Notes
# MariaDB MaxScale 1.1 Release Notes
## 1.1 GA

View File

@ -1,6 +1,6 @@
# MaxScale Release Notes
# MariaDB MaxScale 1.1.1 Release Notes
## 1.1 GA
## 1.1.1 GA
MaxScale 1.1 is the current stable (GA) release of MaxScale. Version 1.1.1 is mainly a bug fix release introducing fixes, but also introduces some improvements to existing functionality.

View File

@ -0,0 +1,99 @@
# MariaDB MaxScale 1.2 Release Notes
## 1.2 GA
This document details the changes in version 1.2 since the release of the 1.1.1 GA Release of the MaxScale product.
###***PLEASE NOTICE: MaxScale installation directories have changed in this version***
The 1.2 version of MaxScale differs from previos versions in its installation layout. Please take great care when upgrading MaxScale from previous versions to version 1.2. An automatic upgrade will not work due to the severe changes in the installation layout.
## New Features
### Non-root MaxScale
You can now run MaxScale as any user. The standard installation of a MaxScale package now creates the maxscale user and the maxscale group.
### FHS-compliant installation
The 1.2 version of MaxScale now complies to the Filesystem Hierarchy Standard. This means that MAXSCALE_HOME is no longer necessary and directories can be moved to different locations.
A quick list of changes in installation directories and file names:
* Binaries go into `/usr/bin`
* Configuration files to `/etc` and the configuration file is now lower case: `maxscale.cnf`
* Logs to `/var/log/maxscale`
* The module and library directory have been combined into a single directory in `/usr/lib64/maxscale`. If you have custom modules please make sure they are located there.
* Data directory is `/var/lib/maxscale`. This is the default location for MaxScale-specific data.
* PID file can be found at `/var/run/maxscale`
### Client side SSL encryption
MaxScale now supports SSL/TLS encrypted connections to MaxScale.
### 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.
* [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

View File

@ -0,0 +1,104 @@
# Readconnroute
This document provides anoverview of the **readconnroute** router module and its intended use case scenarios. It also displays all router configuration parameters with their descriptions.
## Overview
The readconnroute router provides simple and lightweight load balancing across a set of servers. The router can also be configured to balance connections based on a weighting parameter defined in the server's section.
## Configuration
Readconnroute router-specific settings are specified in the configuration file of MaxScale in its specific section. The section can be freely named but the name is used later as a reference from listener section.
The configuration consists of mandatory and optional parameters.
## Mandatory parameters
**`type`** specifies the type of service. For readconnroute module the type is `router`:
type=router
**`router`** specifies the router module to be used. For readconnroute the value is `readconnroute`:
router=readconnroute
**`servers`** provides a list of servers, which the router will connect to:
servers=server1,server2,server3
**NOTE: Each server on the list must have its own section in the configuration file where it is defined.**
**`user`** is the username the router session uses for accessing backends in order to load the content of the `mysql.user` table (and `mysql.db` and database names as well) and optionally for creating, and using `maxscale_schema.replication_heartbeat` table.
**`passwd`** specifies corresponding password for the user. Syntax for user and passwd is:
```
user=<username>
passwd=<password>
```
## Optional parameters
The **`weightby`** parameter defines the name of the value which is used to calculate the weights of the servers. Here is an example server configuration with the `serv_weight` parameter used as the weighting parameter.
```
[server1]
type=server
address=127.0.0.1
port=3000
protocol=MySQLBackend
serv_weight=3
[server2]
type=server
address=127.0.0.1
port=3001
protocol=MySQLBackend
serv_weight=1
[Read Service]
type=service
router=readconnroute
servers=server1,server2
weightby=serv_weight
```
With this configuration and a heavy query load, the server *server1* will get most of the connections and about a third of the remaining queries are routed to the second server. With server weights, you can assing secondary servers that are only used when the primary server is under heavy load.
Without the weightby parameter, each connection counts as a single connection. With a weighting parameter, a single connection received its weight from the server's own weighting parameter divided by the sum of all weighting parameters in all the configured servers.
If we use the previous configuration as an example, the sum of the `serv_weight` parameter is 4. Server1 would receive a weight of `3/4=75%` and server2 would get `1/4=25%`. This means that server1 would get 75% of the connections and server2 would get 25% of the connections.
**`router_options`** can contain a list of valid server roles. These roles are used as the valid types of servers the router will form connections to when new sessions are created.
```
router_options=slave
```
Here is a list of all possible values for the `router_options`.
Role|Description
------|---------
master|A server assigned as a master by one of MaxScale monitors. Depending on the monitor implementation, this could be a master server of a Master-Slave replication cluster or a Write-Master of a Galera cluster.
slave|A server assigned as a slave of a master.
synced| A Galera cluster node which is in a synced state with the cluster.
ndb|A MySQL Replication Cluster node
running|A server that is up and running. All servers that MaxScale can connect to are labeled as running.
If no `router_options` parameter is configured in the service definition, the router will use the default value of `running`. This means that it will load balance connections across all running servers defined in the `servers` parameter of the service.
## Examples
The most common use for the readconnroute is to provide either a read or write port for an application. This provides a more lightweight routing solution than the more complex readwritesplit router but requires the application to be able to use distinct write and read ports.
To configure a read-only service that tolerates master failures, we first need to add a new section in to the configuration file.
```
[Read Service]
type=service
router=readconnroute
servers=slave1,slave2,slave3
router_options=slave
```
Here the `router_options`designates slaves as the only valid server type. With this configuration, the queries are load balanced across the slave servers.
For more complex examples of the readconnroute router, take a look at the examples in the [Tutorials](../Tutorials) folder.

View File

@ -4,7 +4,9 @@ This document provides a short overview of the **readwritesplit** router module
## Overview
The **readwritesplit** router is designed to be used with a Master-Slave replication cluster. It automatically detects changes in the master server and will use the current master server of the cluster. With a Galera cluster, one can achieve a resilient setup and easy master failover by using one of the Galera nodes as a Write-Master node, where are write queries are routed, and spreading the read load over all the nodes.
The **readwritesplit** router is designed to increase the read-only processing capability of a cluster while maintaining consistency. This is achieved by splitting the query load into read and write queries. Read queries, which do not modify data, are spread across multiple nodes while all write queries will be sent to a single node.
The router is designed to be used with a traditional Master-Slave replication cluster. It automatically detects changes in the master server and will use the current master server of the cluster. With a Galera cluster, one can achieve a resilient setup and easy master failover by using one of the Galera nodes as a Write-Master node, where all write queries are routed, and spreading the read load over all the nodes.
## Configuration
@ -18,9 +20,9 @@ The configuration consists of mandatory and optional parameters.
type=router
**`service`** specifies the router module to be used. For **readwritesplit** the value is `readwritesplit`:
**`router`** specifies the router module to be used. For **readwritesplit** the value is `readwritesplit`:
service=readwritesplit
router=readwritesplit
**`servers`** provides a list of servers, which must include one master and available slaves:
@ -91,6 +93,17 @@ disable_sescmd_history=true
disable_slave_recovery=true
```
**`master_accept_reads`** allows the master server to be used for reads. This is a useful option to enable if you are using a small number of servers and wish to use the master for reads as well.
```
# Use the master for reads
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:

View File

@ -15,54 +15,33 @@ The purpose of this tutorial is to introduce the MaxScale Administrator to a few
### Starting MaxScale
There are several ways to start MaxScale, the most convenient mechanism is probably using the Linux service interface. When a MaxScale package is installed the package manager will also installed a script in /etc/init.d which may be used to start and stop MaxScale either directly or via the service interface.
```
$ service maxscale start
```
or
```
$ /etc/init.d/maxscale start
It is also possible to start MaxScale by executing the maxscale command itself, in this case you must ensure that the environment is correctly setup or command line options are passed. The major elements to consider are the correct setting of the MAXSCALE\_HOME directory and to ensure that LD\_LIBRARY\_PATH. The LD\_LIBRARY\_PATH should include the lib directory that was installed as part of the MaxScale installation, the MAXSCALE\_HOME should point to /usr/local/mariadb-maxscale if a default installation has been created or to the directory this was relocated to. Running the executable $MAXSCALE\_HOME/bin/maxscale will result in MaxScale running as a daemon process, unattached to the terminal in which it was started and using configuration files that it finds in the $MAXSCALE\_HOME directory.
```
It is also possible to start MaxScale by executing the maxscale command itself. Running the executable /usr/bin/maxscale will result in MaxScale running as a daemon process, unattached to the terminal in which it was started and using configuration files that it finds in the /etc directory.
Options may be passed to the MaxScale binary that alter this default behavior, this options are documented in the table below.
<table>
<tr>
<td>Switch</td>
<td>Long Option</td>
<td>Description</td>
</tr>
<tr>
<td>-d</td>
<td>--nodaemon</td>
<td>Run MaxScale attached to the terminal rather than as a daemon process. This is useful for debugging purposes.</td>
</tr>
<tr>
<td>-c</td>
<td>--homedir=</td>
<td>Ignore the environment variable MAXSCALE_HOME and use the supplied argument instead.</td>
</tr>
<tr>
<td>-f</td>
<td>--config=</td>
<td>Use the filename passed as an argument instead of looking in $MAXSCALE_HOME/etc/MaxScale.cnf</td>
</tr>
<tr>
<td>-l<file>|<shm>|<stdout></td>
<td>--log=</td>
<td>Control where logs are written for the debug and trace level log messages. the default is to write these to a shared memory device, however using the -lfile or --log=file option will forced these to be written to regular files. Using -lstdout or --log=stdout will use the standard output for all enabled logs.</td>
</tr>
<tr>
<td>-v</td>
<td>--version</td>
<td>Print version information for MaxScale</td>
</tr>
<tr>
<td>-?</td>
<td>--help</td>
<td>Print usage information for MaxScale</td>
</tr>
</table>
Switch|Long Option|Description
------|-----------|-----------
`-d`|`--nodaemon`|enable running in terminal process (default:disabled)
`-f FILE`|`--config=FILE`|relative or absolute pathname of MaxScale configuration file (default:/etc/maxscale.cnf)
`-l[file shm]`|`--log=[file shm]`|log to file or shared memory (default: shm)
`-L PATH`|`--logdir=PATH`|path to log file directory (default: /var/log/maxscale)
`-D PATH`|`--datadir=PATH`|path to data directory, stored embedded mysql tables (default: /var/cache/maxscale)
`-C PATH`|`--configdir=PATH`|path to configuration file directory (default: /etc/)
`-B PATH`|`--libdir=PATH`|path to module directory (default: /usr/lib64/maxscale)
`-A PATH`|`--cachedir=PATH`|path to cache directory (default: /var/cache/maxscale)
`P PATH`|`--piddir=PATH`|PID file directory
`-U USER`|`--user=USER`|run MaxScale as another user. The user ID and group ID of this user are used to run MaxScale.
`-s [yes no]`|`--syslog=[yes no]`|log messages to syslog (default:yes)
`-S [yes no]`|`--maxscalelog=[yes no]`|log messages to MaxScale log (default: yes)
`-v`|`--version`|print version info and exit
`-?`|`--help`|show this help
<a name="stopping"></a>
### Stopping MaxScale
@ -70,26 +49,27 @@ Options may be passed to the MaxScale binary that alter this default behavior, t
There are numerous ways in which MaxScale can be stopped; using the service interface, killing the process or by use of the maxadmin utility.
Stopping MaxScale with the service interface is simply a case of using the service stop command or calling the init.d script with the stop argument.
```
$ service maxscale stop
```
or
```
$ /etc/init.d/maxscale stop
MaxScale will also stop gracefully if it received a hangup signal, to find the process id of the MaxScale server use the ps command or read the contents of the maxscale.pid file located in the same directory as the logs.
$ kill -HUP `cat $MAXSCALE_HOME/log/maxscale.pid`
```
MaxScale will also stop gracefully if it received a terminate signal, to find the process id of the MaxScale server use the ps command or read the contents of the maxscale.pid file located in the /var/run/maxscale directory.
```
$ kill `cat /var/run/maxscale/maxscale.pid`
```
In order to shutdown MaxScale using the maxadmin command you may either connect with maxadmin in interactive mode or pass the "shutdown maxscale" command you wish to execute as an argument to maxadmin.
```
$ maxadmin -pmariadb shutdown maxscale
```
<a name="checking"></a>
### Checking The Status Of The MaxScale Services
It is possible to use the maxadmin command to obtain statistics regarding the services that are configured within your MaxScale configuration file. The maxadmin command "list services" will give very basic information regarding the services that are define. This command may be either run in interactive mode or passed on the maxadmin command line.
```
$ maxadmin -pmariadb
MaxScale> list services
@ -110,6 +90,7 @@ It is possible to use the maxadmin command to obtain statistics regarding the se
--------------------------+----------------------+--------+---------------
MaxScale>
```
It should be noted that network listeners count as a user of the service, therefore there will always be one user per network port in which the service listens. More detail can be obtained by use of the "show service" command which is passed a service name.
@ -117,7 +98,7 @@ It should be noted that network listeners count as a user of the service, theref
### What Clients Are Connected To MaxScale
To determine what client are currently connected to MaxScale you can use the "list clients" command within maxadmin. This will give you IP address and the ID’s of the DCB and session for that connection. As with any maxadmin command this can be passed on the command line or typed interactively in maxadmin.
```
$ maxadmin -pmariadb list clients
Client Connections
@ -133,28 +114,27 @@ To determine what client are currently connected to MaxScale you can use the "li
-----------------+------------------+----------------------+------------
$
```
<a name="rotating"></a>
### Rotating Log Files
MaxScale write log data into four log files with varying degrees of detail. With the exception of the error log, which can not be disabled, these log files may be enabled and disabled via the maxadmin interface or in the configuration file. The default behavior of MaxScale is to grow the log files indefinitely, the administrator must take action to prevent this.
It is possible to rotate either a single log file or all the log files with a single command. When the logfile is rotated, the current log file is closed and a new log file, with an increased sequence number in its name, is created. Log file rotation is achieved by use of the "flush log" or “flush logs” command in maxadmin.
```
$ maxadmin -pmariadb flush logs
```
Flushes all of the logs, whereas an individual log may be flushed with the "flush log" command.
```
$ maxadmin -pmariadb
MaxScale> flush log error
MaxScale> flush log trace
MaxScale>
```
This may be integrated into the Linux logrotate mechanism by adding a configuration file to the /etc/logrotate.d directory. If we assume we want to rotate the log files once per month and wish to keep 5 log files worth of history, the configuration file would look like the following.
<table>
<tr>
<td>/usr/local/mariadb-maxscale/log/*.log {
```
/var/log/maxscale/*.log {
monthly
rotate 5
missingok
@ -163,30 +143,26 @@ sharedscripts
postrotate
\# run if maxscale is running
if test -n "`ps acx|grep maxscale`"; then
/usr/local/mariadb-maxscale/bin/maxadmin -pmariadb flush logs
/usr/bin/maxadmin -pmariadb flush logs
fi
endscript
}</td>
</tr>
</table>
}
```
One disadvantage with this is that the password used for the maxadmin command has to be embedded in the log rotate configuration file. MaxScale will also rotate all of its log files if it receives the USR1 signal. Using this the logrotate configuration script can be rewritten as
<table>
<tr>
<td>/usr/local/mariadb-maxscale/log/*.log {
```
/var/log/maxscale/*.log {
monthly
rotate 5
missingok
nocompress
sharedscripts
postrotate
kill -USR1 `cat /usr/local/mariadb-maxscale/log/maxscale.pid`
kill -USR1 `cat /var/run/maxscale/maxscale.pid`
endscript
}</td>
</tr>
</table>
}
```
<a name="outofuse"></a>
### Taking A Database Server Out Of Use
@ -194,16 +170,16 @@ endscript
MaxScale supports the concept of maintenance mode for servers within a cluster, this allows for planned, temporary removal of a database from the cluster within the need to change the MaxScale configuration.
To achieve the removal of a database server you can use the set server command in the maxadmin utility to set the maintenance mode flag for the server. This may be done interactively within maxadmin or by passing the command on the command line.
```
MaxScale> set server dbserver3 maintenance
MaxScale>
```
This will cause MaxScale to stop routing any new requests to the server, however if there are currently requests executing on the server these will not be interrupted.
To bring the server back into service use the "clear server" command to clear the maintenance mode bit for that server.
```
MaxScale> clear server dbserver3 maintenance
MaxScale>
```
Note that maintenance mode is not persistent, if MaxScale restarts when a node is in maintenance mode a new instance of MaxScale will not honour this mode. If multiple MaxScale instances are configured to use the node them maintenance mode must be set within each MaxScale instance. However if multiple services within one MaxScale instance are using the server then you only need set the maintenance mode once on the server for all services to take note of the mode change.

View File

@ -60,7 +60,7 @@ If you wish to use two different usernames for the two different roles of monito
### Creating Your MaxScale Configuration
MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory $MAXSCALE_HOME/etc, if you have installed in the default location then this file is available in /usr/local/mariadb-maxscale/etc/MaxScale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within this directory that may be use as a basis for your configuration.
MaxScale configuration is held in an ini file that is located in the file maxscale.cnf in the directory /etc, if you have installed in the default location then this file is available in /etc/maxscale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within the /usr/share/maxscale directory that may be use as a basis for your configuration.
A global, maxscale, section is included within every MaxScale configuration file; this is used to set the values of various MaxScale wide parameters, perhaps the most important of these is the number of threads that MaxScale will use to execute the code that forwards requests and handles responses for clients.
@ -89,7 +89,7 @@ In order to instruct the router to which servers it should route we must add rou
The final step in the service section is to add the username and password that will be used to populate the user data from the database cluster. There are two options for representing the password, either plain text or encrypted passwords may be used. In order to use encrypted passwords a set of keys must be generated that will be used by the encryption and decryption process. To generate the keys use the maxkeys command and pass the name of the secrets file in which the keys are stored.
% maxkeys /usr/local/mariadb-maxscale/etc/.secrets
% maxkeys /var/lib/maxscale/.secrets
%
Once the keys have been created the maxpasswd command can be used to generate the encrypted password.
@ -178,7 +178,7 @@ or
% service maxscale start
Check the error log in /usr/local/mariadb-maxscale/log to see if any errors are detected in the configuration file and to confirm MaxScale has been started. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured.
Check the error log in /var/log/maxscale to see if any errors are detected in the configuration file and to confirm MaxScale has been started. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured.
% maxadmin -pmariadb list services

View File

@ -62,7 +62,7 @@ If you wish to use two different usernames for the two different roles of monito
### Creating Your MaxScale Configuration
MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory $MAXSCALE_HOME/etc, if you have installed in the default location then this file is available in /usr/local/mariadb-maxscale/etc/MaxScale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within this directory that may be use as a basis for your configuration.
MaxScale configuration is held in an ini file that is located in the file maxscale.cnf in the directory /etc, if you have installed in the default location then this file is available in /etc/maxscale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within the /usr/share/maxscale directory that may be use as a basis for your configuration.
A global, maxscale, section is included within every MaxScale configuration file; this is used to set the values of various MaxScale wide parameters, perhaps the most important of these is the number of threads that MaxScale will use to execute the code that forwards requests and handles responses for clients.
@ -83,7 +83,7 @@ The router for we need to use for this configuration is the readwritesplit modul
The final step in the service sections is to add the username and password that will be used to populate the user data from the database cluster. There are two options for representing the password, either plain text or encrypted passwords may be used. In order to use encrypted passwords a set of keys must be generated that will be used by the encryption and decryption process. To generate the keys use the maxkeys command and pass the name of the secrets file in which the keys are stored.
% maxkeys /usr/local/mariadb-maxscale/etc/.secrets
% maxkeys /var/lib/maxscale/.secrets
%
Once the keys have been created the maxpasswd command can be used to generate the encrypted password.
@ -183,7 +183,7 @@ or
% service maxscale start
Check the error log in /usr/local/mariadb-maxscale/log to see if any errors are detected in the configuration file and to confirm MaxScale has been started. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured.
Check the error log in /var/log/maxscale to see if any errors are detected in the configuration file and to confirm MaxScale has been started. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured.
% maxadmin -pmariadb list services

View File

@ -5,54 +5,65 @@ The plugin is capable of returning data in one of two ways, either as MySQL resu
# Configuration
The plugin is configured in the MaxScale.cnf plugin in much the same way as any other router service is configured, there needs to be a service section in the configuration file and also listeners defined for that service. The service does not however require any backend servers to be associated with it, or any monitors.
The plugin is configured in the maxscale.cnf plugin in much the same way as any other router service is configured, there needs to be a service section in the configuration file and also listeners defined for that service. The service does not however require any backend servers to be associated with it, or any monitors.
The service entry needs to define the service name, the type as service and the router module to load.
The specified user, with the password (plain or encrypted via maxpassword utility) is allowed to connect via MySQL protocol.
Currently the user can connect to maxinfo from any remote IP and to localhost as well.
```
[MaxInfo]
type=service
router=maxinfo
user=monitor
passwd=EBD2F49C3B375812A8CDEBA632ED8BBC
```
The listener section defines the protocol, port and other information needed to create a listener for the service. To listen on a port using the MySQL protocol a section as shown below should be added to the configuration file.
```
[MaxInfo Listener]
type=listener
service=MaxInfo
protocol=MySQLClient
port=9003
```
To listen with the HTTP protocol and hence return JSON documents a section as should below is required.
```
[MaxInfo JSON Listener]
type=listener
service=MaxInfo
protocol=HTTPD
port=8003
```
If both the MySQL and JSON responses are required then a single service can be configured with both types of listener.
As with any other listeners within MaxScale the listeners can be bound to a particular interface by use of the address= parameter. This allows the access to the maxinfo data to be limited to the localhost by adding an address=localhost parameter in the configuration file.
```
[MaxInfo Listener]
type=listener
service=MaxInfo
protocol=MySQLClient
address=localhost
port=9003
```
# MySQL Interface to maxinfo
The maxinfo supports a small subset of SQL statements in addition to the MySQL status and ping requests. These may be used for simple monitoring of MaxScale.
```
% mysqladmin -hmaxscale.mariadb.com -P9003 -umonitor -pxyz ping
mysqld is alive
% mysqladmin -hmaxscale.mariadb.com -P9003 -umonitor -pxyz status
Uptime: 72 Threads: 1 Sessions: 11
%
```
The SQL command used to interact with maxinfo is the show command, a variety of show commands are available and will be described in the following sections.
@ -60,6 +71,7 @@ The SQL command used to interact with maxinfo is the show command, a variety of
The show variables command will display a set of name and value pairs for a number of MaxScale system variables.
```
mysql> show variables;
+--------------------+-------------------------+
| Variable_name | Value |
@ -77,9 +89,11 @@ The show variables command will display a set of name and value pairs for a numb
9 rows in set (0.02 sec)
mysql>
```
The show variables command can also accept a limited like clause. This like clause must either be a literal string to match, a pattern starting with a %, a pattern ending with a % or a string with a % at both the start and the end.
```
mysql> show variables like 'version';
+---------------+----------------+
| Variable_name | Value |
@ -116,11 +130,13 @@ The show variables command can also accept a limited like clause. This like clau
3 rows in set (0.02 sec)
mysql>
```
## Show status
The show status command displays a set of status counters, as with show variables the show status command can be passed a simplified like clause to limit the values returned.
```
mysql> show status;
+---------------------------+-------+
| Variable_name | Value |
@ -151,11 +167,13 @@ The show status command displays a set of status counters, as with show variable
22 rows in set (0.02 sec)
mysql>
```
## Show services
The show services command will return a set of basic statistics regarding each of the configured services within MaxScale.
```
mysql> show services;
+----------------+----------------+--------------+----------------+
| Service Name | Router Module | No. Sessions | Total Sessions |
@ -172,6 +190,7 @@ The show services command will return a set of basic statistics regarding each o
8 rows in set (0.02 sec)
mysql>
```
The show services command does not accept a like clause and will ignore any like clause that is given.
@ -179,6 +198,7 @@ The show services command does not accept a like clause and will ignore any like
The show listeners command will return a set of status information for every listener defined within the MaxScale configuration file.
```
mysql> show listeners;
+----------------+-----------------+-----------+------+---------+
| Service Name | Protocol Module | Address | Port | State |
@ -196,6 +216,7 @@ The show listeners command will return a set of status information for every lis
9 rows in set (0.02 sec)
mysql>
```
The show listeners command will ignore any like clause passed to it.
@ -203,6 +224,7 @@ The show listeners command will ignore any like clause passed to it.
The show sessions command returns information on every active session within MaxScale. It will ignore any like clause passed to it.
```
mysql> show sessions;
+-----------+---------------+----------------+---------------------------+
| Session | Client | Service | State |
@ -222,11 +244,13 @@ The show sessions command returns information on every active session within Max
11 rows in set (0.02 sec)
mysql>
```
## Show clients
The show clients command reports a row for every client application connected to MaxScale. Like clauses are not available of the show clients command.
```
mysql> show clients;
+-----------+---------------+---------+---------------------------+
| Session | Client | Service | State |
@ -237,11 +261,13 @@ The show clients command reports a row for every client application connected to
2 rows in set (0.02 sec)
mysql>
```
## Show servers
The show servers command returns data for each backend server configured within the MaxScale configuration file. This data includes the current number of connections MaxScale has to that server and the state of that server as monitored by MaxScale.
```
mysql> show servers;
+---------+-----------+------+-------------+---------+
| Server | Address | Port | Connections | Status |
@ -254,11 +280,13 @@ The show servers command returns data for each backend server configured within
4 rows in set (0.02 sec)
mysql>
```
## Show modules
The show modules command reports the information on the modules currently loaded into MaxScale. This includes the name type and version of each module. It also includes the API version the module has been written against and the current release status of the module.
```
mysql> show modules;
+----------------+-------------+---------+-------------+----------------+
| Module Name | Module Type | Version | API Version | Status |
@ -277,12 +305,13 @@ The show modules command reports the information on the modules currently loaded
10 rows in set (0.02 sec)
mysql>
```
## Show monitors
The show monitors command reports each monitor configured within the system and the state of that monitor.
```
mysql> show monitors;
+---------------+---------+
| Monitor | Status |
@ -292,12 +321,13 @@ The show monitors command reports each monitor configured within the system and
1 row in set (0.02 sec)
mysql>
```
## Show eventTimes
The show eventTimes command returns a table of statistics that reflect the performance of the event queuing and execution portion of the MaxScale core.
```
mysql> show eventTimes;
+---------------+-------------------+---------------------+
| Duration | No. Events Queued | No. Events Executed |
@ -336,6 +366,7 @@ The show eventTimes command returns a table of statistics that reflect the perfo
30 rows in set (0.02 sec)
mysql>
```
Each row represents a time interval, in 100ms increments, with the counts representing the number of events that were in the event queue for the length of time that row represents and the number of events that were executing of the time indicated by the row.
@ -347,6 +378,7 @@ The simplified JSON interface takes the URL of the request made to maxinfo and m
The /variables URL will return the MaxScale variables, these variables can not be filtered via this interface.
```
$ curl http://maxscale.mariadb.com:8003/variables
[ { "Variable_name" : "version", "Value" : "1.0.6-unstable"},
{ "Variable_name" : "version_comment", "Value" : "MariaDB MaxScale"},
@ -358,11 +390,13 @@ The /variables URL will return the MaxScale variables, these variables can not b
{ "Variable_name" : "MAXSCALE_UPTIME", "Value" : 3948},
{ "Variable_name" : "MAXSCALE_SESSIONS", "Value" : 12}]
$
```
## Status
Use of the /status URI will return the status information that would normally be returned by the show status command. No filtering of the status information is available via this interface
```
$ curl http://maxscale.mariadb.com:8003/status
[ { "Variable_name" : "Uptime", "Value" : 3831},
{ "Variable_name" : "Uptime_since_flush_status", "Value" : 3831},
@ -387,11 +421,13 @@ Use of the /status URI will return the status information that would normally be
{ "Variable_name" : "Max_event_queue_time", "Value" : 0},
{ "Variable_name" : "Max_event_execution_time", "Value" : 1}]
$
```
## Services
The /services URI returns the data regarding the services defined within the configuration of MaxScale. Two counters are returned, the current number of sessions attached to this service and the total number connected since the service started.
```
$ curl http://maxscale.mariadb.com:8003/services
[ { "Service Name" : "Test Service", "Router Module" : "readconnroute", "No. Sessions" : 1, "Total Sessions" : 1},
{ "Service Name" : "Split Service", "Router Module" : "readwritesplit", "No. Sessions" : 1, "Total Sessions" : 1},
@ -402,11 +438,13 @@ The /services URI returns the data regarding the services defined within the con
{ "Service Name" : "CLI", "Router Module" : "cli", "No. Sessions" : 1, "Total Sessions" : 1},
{ "Service Name" : "MaxInfo", "Router Module" : "maxinfo", "No. Sessions" : 5, "Total Sessions" : 20}]
$
```
## Listeners
The /listeners URI will return a JSON array with one entry per listener, each entry is a JSON object that describes the configuration and state of that listener.
```
$ curl http://maxscale.mariadb.com:8003/listeners
[ { "Service Name" : "Test Service", "Protocol Module" : "MySQLClient", "Address" : "*", "Port" : 4006, "State" : "Running"},
{ "Service Name" : "Split Service", "Protocol Module" : "MySQLClient", "Address" : "*", "Port" : 4007, "State" : "Running"},
@ -418,11 +456,13 @@ The /listeners URI will return a JSON array with one entry per listener, each en
{ "Service Name" : "MaxInfo", "Protocol Module" : "MySQLClient", "Address" : "*", "Port" : 9003, "State" : "Running"},
{ "Service Name" : "MaxInfo", "Protocol Module" : "HTTPD", "Address" : "*", "Port" : 8003, "State" : "Running"}]
$
```
## Modules
The /modules URI returns data for each plugin that has been loaded into MaxScale. The plugin name, type and version are returned as is the version of the plugin API that the plugin was built against and the release status of the plugin.
```
$ curl http://maxscale.mariadb.com:8003/modules
[ { "Module Name" : "HTTPD", "Module Type" : "Protocol", "Version" : "V1.0.1", "API Version" : "1.0.0", "Status" : "In Development"},
{ "Module Name" : "maxscaled", "Module Type" : "Protocol", "Version" : "V1.0.0", "API Version" : "1.0.0", "Status" : "GA"},
@ -435,11 +475,13 @@ The /modules URI returns data for each plugin that has been loaded into MaxScale
{ "Module Name" : "cli", "Module Type" : "Router", "Version" : "V1.0.0", "API Version" : "1.0.0", "Status" : "GA"},
{ "Module Name" : "maxinfo", "Module Type" : "Router", "Version" : "V1.0.0", "API Version" : "1.0.0", "Status" : "Alpha"}]
$
```
## Sessions
The /sessions URI returns a JSON array with an object for each active session within MaxScale.
```
$ curl http://maxscale.mariadb.com:8003/sessions
[ { "Session" : "0x1a8e9a0", "Client" : "80.176.79.245", "Service" : "MaxInfo", "State" : "Session ready for routing"},
{ "Session" : "0x1a8e6d0", "Client" : "80.240.130.35", "Service" : "MaxInfo", "State" : "Session ready for routing"},
@ -453,32 +495,38 @@ The /sessions URI returns a JSON array with an object for each active session wi
{ "Session" : "0x1a5c530", "Client" : , "Service" : "Split Service", "State" : "Listener Session"},
{ "Session" : "0x19ac1c0", "Client" : , "Service" : "Test Service", "State" : "Listener Session"}]
$
```
## Clients
The /clients URI is a limited version of the /sessions, in this case it only returns an entry for a session that represents a client connection.
```
$ curl http://maxscale.mariadb.com:8003/clients
[ { "Session" : "0x1a90be0", "Client" : "80.176.79.245", "Service" : "MaxInfo", "State" : "Session ready for routing"},
{ "Session" : "0x1a8e9a0", "Client" : "127.0.0.1", "Service" : "MaxInfo", "State" : "Session ready for routing"},
{ "Session" : "0x1a8e6d0", "Client" : "80.240.130.35", "Service" : "MaxInfo", "State" : "Session ready for routing"}]
$
```
## Servers
The /servers URI is used to retrieve information for each of the servers defined within the MaxScale configuration. This information includes the connection count and the current status as monitored by MaxScale. The connection count is only those connections made by MaxScale to those servers.
```
$ curl http://maxscale.mariadb.com:8003/servers
[ { "Server" : "server1", "Address" : "127.0.0.1", "Port" : 3306, "Connections" : 0, "Status" : "Running"},
{ "Server" : "server2", "Address" : "127.0.0.1", "Port" : 3307, "Connections" : 0, "Status" : "Down"},
{ "Server" : "server3", "Address" : "127.0.0.1", "Port" : 3308, "Connections" : 0, "Status" : "Down"},
{ "Server" : "server4", "Address" : "127.0.0.1", "Port" : 3309, "Connections" : 0, "Status" : "Down"}]
$
```
## Event Times
The /event/times URI returns an array of statistics that reflect the performance of the event queuing and execution portion of the MaxScale core. Each element is an object that represents a time bucket, in 100ms increments, with the counts representing the number of events that were in the event queue for the length of time that row represents and the number of events that were executing of the time indicated by the object.
```
$ curl http://maxscale.mariadb.com:8003/event/times
[ { "Duration" : "< 100ms", "No. Events Queued" : 64, "No. Events Executed" : 63},
{ "Duration" : " 100 - 200ms", "No. Events Queued" : 0, "No. Events Executed" : 0},
@ -510,3 +558,4 @@ The /event/times URI returns an array of statistics that reflect the performance
{ "Duration" : "2700 - 2800ms", "No. Events Queued" : 0, "No. Events Executed" : 0},
{ "Duration" : "2800 - 2900ms", "No. Events Queued" : 0, "No. Events Executed" : 0},
{ "Duration" : "> 3000ms", "No. Events Queued" : 0, "No. Events Executed" : 0}]
```

View File

@ -207,7 +207,7 @@ The SQL node is referenced here as [mysqld(API)], which reflects the fact that t
## Configuring MaxScale for connection load balancing of SQL nodes
Add these sections in MaxScale.cnf config file:
Add these sections in maxscale.cnf config file:
[Cluster Service]
type=service
@ -249,7 +249,7 @@ Add these sections in MaxScale.cnf config file:
Assuming MaxScale is installed in server1, start it
[root@server1 ~]# cd /usr/local/mariadb-maxscale/bin
[root@server1 ~]# cd /usr/bin
[root@server1 bin]# ./maxscale -c ../

View File

@ -36,6 +36,7 @@ The first user required must be able to select data from the table mysql.user, t
2. Create the user, substituting the username, password and host on which maxscale runs within your environment
```
MariaDB [(none)]> create user '*username*'@'*maxscalehost*' identified by '*password*';
**Query OK, 0 rows affected (0.00 sec)**
@ -45,9 +46,11 @@ MariaDB [(none)]> create user '*username*'@'*maxscalehost*' identified by '*pass
MariaDB [(none)]> grant SELECT on mysql.user to '*username*'@'*maxscalehost*';
**Query OK, 0 rows affected (0.03 sec)**
```
Additionally, GRANT SELECT on the mysql.db table and SHOW DATABASES privileges are required in order to load databases name and grants suitable for database name authorization.
```
MariaDB [(none)]> GRANT SELECT ON mysql.db TO 'username'@'maxscalehost';
**Query OK, 0 rows affected (0.00 sec)**
@ -55,9 +58,11 @@ MariaDB [(none)]> GRANT SELECT ON mysql.db TO 'username'@'maxscalehost';
MariaDB [(none)]> GRANT SHOW DATABASES ON *.* TO 'username'@'maxscalehost';
**Query OK, 0 rows affected (0.00 sec)**
```
The second user is used to monitored the state of the cluster. This user, which may be the same username as the first, requires permissions to access the various sources of monitoring data. In order to monitor a replication cluster this user must be granted the roles REPLICATION SLAVE and REPLICATION CLIENT
```
MariaDB [(none)]> grant REPLICATION SLAVE on *.* to '*username*'@'*maxscalehost*';
**Query OK, 0 rows affected (0.00 sec)**
@ -65,220 +70,174 @@ MariaDB [(none)]> grant REPLICATION SLAVE on *.* to '*username*'@'*maxscalehost*
MariaDB [(none)]> grant REPLICATION CLIENT on *.* to '*username*'@'*maxscalehost*';
**Query OK, 0 rows affected (0.00 sec)**
```
If you wish to use two different usernames for the two different roles of monitoring and collecting user information then create a different username using the first two steps from above.
## Creating Your MaxScale Configuration
MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory $MAXSCALE_HOME/etc, if you have installed in the default location then this file is available in /usr/local/mariadb/maxscle/etc/MaxScale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within this directory that may be use as a basis for your configuration.
MaxScale configuration is held in an ini file that is located in the file maxscale.cnf in the directory /etc. This is not created as part of the installation process and must be manually created. A template file does exist in the `/usr/share/maxscale` folder that can be use as a basis for your configuration.
A global, maxscale, section is included within every MaxScale configuration file; this is used to set the values of various MaxScale wide parameters, perhaps the most important of these is the number of threads that MaxScale will use to execute the code that forwards requests and handles responses for clients.
```
[maxscale]
threads=4
```
Since we are using MySQL Replication and connection routing we want two different ports to which the client application can connect; one that will be directed to the current master within the replication cluster and another that will load balance between the slaves. To achieve this within MaxScale we need to define two services in the ini file; one for the read/write operations that should be executed on the master server and another for connections to one of the slaves. Create a section for each in your MaxScale.ini file and set the type to service, the section names are the names of the services themselves and should be meaningful to the administrator. Names may contain whitespace.
```
[Write Service]
type=service
[Read Service]
type=service
```
The router for these two sections is identical, the readconnroute module, also the services should be provided with the list of servers that will be part of the cluster. The server names given here are actually the names of server sections in the configuration file and not the physical hostnames or addresses of the servers.
```
[Write Service]
type=service
router=readconnroute
servers=dbserv1, dbserv2, dbserv3
[Read Service]
type=service
router=readconnroute
servers=dbserv1, dbserv2, dbserv3
```
In order to instruct the router to which servers it should route we must add router options to the service. The router options are compared to the status that the monitor collects from the servers and used to restrict the eligible set of servers to which that service may route. In our case we use the two options master and slave for our two services.
```
[Write Service]
type=service
router=readconnroute
router_options=master
servers=dbserv1, dbserv2, dbserv3
[Read Service]
type=service
router=readconnroute
router_options=slave
servers=dbserv1, dbserv2, dbserv3
```
The final step in the service sections is to add the username and password that will be used to populate the user data from the database cluster. There are two options for representing the password, either plain text or encrypted passwords may be used. In order to use encrypted passwords a set of keys must be generated that will be used by the encryption and decryption process. To generate the keys use the maxkeys command and pass the name of the secrets file in which the keys are stored.
% maxkeys /usr/local/mariadb-maxscale/etc/.secrets
%
```
maxkeys /var/lib/maxscale/.secrets
```
Once the keys have been created the maxpasswd command can be used to generate the encrypted password.
% maxpasswd plainpassword
```
maxpasswd plainpassword
96F99AA1315BDC3604B006F427DD9484
%
```
The username and password, either encrypted or plain text, are stored in the service section using the user and passwd parameters.
```
[Write Service]
type=service
router=readconnroute
router_options=master
servers=dbserv1, dbserv2, dbserv3
user=maxscale
passwd=96F99AA1315BDC3604B006F427DD9484
[Read Service]
type=service
router=readconnroute
router_options=slave
servers=dbserv1, dbserv2, dbserv3
user=maxscale
passwd=96F99AA1315BDC3604B006F427DD9484
```
This completes the definitions required by the services, however listening ports must be associated with the services in order to allow network connections. This is done by creating a series of listener sections. These sections again are named for the convenience of the administrator and should be of type listener with an entry labeled service which contains the name of the service to associate the listener with. Each service may have multiple listeners.
```
[Write Listener]
type=listener
service=Write Service
[Read Listener]
type=listener
service=Read Service
```
A listener must also define the protocol module it will use for the incoming network protocol, currently this should be the MySQLClient protocol for all database listeners. The listener may then supply a network port to listen on and/or a socket within the file system.
```
[Write Listener]
type=listener
service=Write Service
protocol=MySQLClient
port=4306
socket=/tmp/ClusterMaster
[Read Listener]
type=listener
service=Read Service
protocol=MySQLClient
port=4307
```
An address parameter may be given if the listener is required to bind to a particular network address when using hosts with multiple network addresses. The default behavior is to listen on all network interfaces.
The next stage is the configuration is to define the server information. This defines how to connect to each of the servers within the cluster, again a section is created for each server, with the type set to server, the network address and port to connect to and the protocol to use to connect to the server. Currently the protocol for all database connections in MySQLBackend.
```
[dbserv1]
type=server
address=192.168.2.1
port=3306
protocol=MySQLBackend
[dbserv2]
type=server
address=192.168.2.2
port=3306
protocol=MySQLBackend
[dbserv3]
type=server
address=192.168.2.3
port=3306
protocol=MySQLBackend
```
In order for MaxScale to monitor the servers using the correct monitoring mechanisms a section should be provided that defines the monitor to use and the servers to monitor. Once again a section is created with a symbolic name for the monitor, with the type set to monitor. Parameters are added for the module to use, the list of servers to monitor and the username and password to use when connecting to the the servers with the monitor.
```
[Replication Monitor]
type=monitor
module=mysqlmon
servers=dbserv1, dbserv2, dbserv3
user=maxscale
passwd=96F99AA1315BDC3604B006F427DD9484
```
As with the password definition in the server either plain text or encrypted passwords may be used.
The final stage in the configuration is to add the option service which is used by the maxadmin command to connect to MaxScale for monitoring and administration purposes. This creates a service section and a listener section.
```
[CLI]
type=service
router=cli
[CLI Listener]
type=listener
service=CLI
protocol=maxscaled
address=localhost
port=6603
```
In the case of the example above it should be noted that an address parameter has been given to the listener, this limits connections to maxadmin commands that are executed on the same machine that hosts MaxScale.
@ -286,14 +245,19 @@ In the case of the example above it should be noted that an address parameter ha
Upon completion of the configuration process MaxScale is ready to be started for the first time. This may either be done manually by running the maxscale command or via the service interface.
% maxscale
```
maxscale
```
or
% service maxscale start
```
service maxscale start
```
Check the error log in /usr/local/mariadb-maxscale/log to see if any errors are detected in the configuration file and to confirm MaxScale has been started. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured.
Check the error log in /var/log/lomaxscale/ to see if any errors are detected in the configuration file and to confirm MaxScale has been started. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured.
```
% maxadmin -pmariadb list services
Services.
@ -349,6 +313,7 @@ CLI | maxscaled | localhost | 6603 | Running
---------------------+--------------------+-----------------+-------+--------
%
```
MaxScale is now ready to start accepting client connections and routing them to the master or slaves within your cluster. Other configuration options are available that can alter the criteria used for routing, these include monitoring the replication lag within the cluster and routing only to slaves that are within a predetermined delay from the current master or using weights to obtain unequal balancing operations. These options may be found in the MaxScale Configuration Guide. More detail on the use of maxadmin can be found in the document "MaxAdmin - The MaxScale Administration & Monitoring Client Application".
MaxScale is now ready to start accepting client connections and routing them to the master or slaves within your cluster. Other configuration options are available that can alter the criteria used for routing, these include monitoring the replication lag within the cluster and routing only to slaves that are within a predetermined delay from the current master or using weights to obtain unequal balancing operations. These options may be found in the MaxScale Configuration Guide. More detail on the use of maxadmin can be found in the document [MaxAdmin - The MaxScale Administration & Monitoring Client Application](Administration-Tutorial.md).

View File

@ -70,7 +70,7 @@ If you wish to use two different usernames for the two different roles of monito
## Creating Your MaxScale Configuration
MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory $MAXSCALE_HOME/etc, if you have installed in the default location then this file is available in /usr/local/mariadb-maxscale/etc/MaxScale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within this directory that may be use as a basis for your configuration.
MaxScale configuration is held in an ini file that is located in the file maxscale.cnf in the directory /etc, if you have installed in the default location then this file is available in /etc/maxscale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within the /usr/share/maxscale directory that may be use as a basis for your configuration.
A global, maxscale, section is included within every MaxScale configuration file; this is used to set the values of various MaxScale wide parameters, perhaps the most important of these is the number of threads that MaxScale will use to execute the code that forwards requests and handles responses for clients.
@ -96,7 +96,7 @@ servers=dbserv1, dbserv2, dbserv3
The final step in the service sections is to add the username and password that will be used to populate the user data from the database cluster. There are two options for representing the password, either plain text or encrypted passwords may be used. In order to use encrypted passwords a set of keys must be generated that will be used by the encryption and decryption process. To generate the keys use the maxkeys command and pass the name of the secrets file in which the keys are stored.
% maxkeys /usr/local/mariadb-maxscale/etc/.secrets
% maxkeys /var/lib/maxscale/.secrets
%
@ -226,7 +226,7 @@ or
% service maxscale start
Check the error log in /usr/local/mariadb-maxscale/log to see if any errors are detected in the configuration file and to confirm MaxScale has been started. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured.
Check the error log in /var/log/maxscale to see if any errors are detected in the configuration file and to confirm MaxScale has been started. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured.
% maxadmin -pmariadb list services

View File

@ -44,7 +44,7 @@ In order to use these scripts on your Nagios Server, you need to copy them from
MaxScale must be configured with 'maxscaled' protocol for the administration interface:
Example of MaxScale.cnf file:
Example of maxscale.cnf file:
[AdminInterface]
type=service
@ -73,9 +73,9 @@ and add (just after localhost.cfg or commnads.cfg)
- modify server IP address in server1.cfg, pointing to MaxScale server
- maxadmin executable must be in the nagios server
- default MaxScale AdminInterface port is 6603
- default maxadmin executable path is /usr/local/mariadb-maxscale/bin/maxadmin
- default maxadmin executable path is /usr/bin/maxadmin
It can be changed by -m option
- maxadmin executable could be copied from an existing maxscale installation (default location is /usr/local/mariadb-maxscale/bin/maxadmin)
- maxadmin executable could be copied from an existing maxscale installation (default location is /usr/bin/maxadmin)
This example shows configuration that needs to be done on Nagios server in order to communicate to MaxScale server that is running on host server1.
In this example we are using the check_maxscale_resource as the check command

View File

@ -193,7 +193,7 @@ This generates RPM or DEB packages based on your system. These packages can then
## Step 5 - Configure new applications
The new filter needs to be configured in MaxScale.cnf.
The new filter needs to be configured in maxscale.cnf.
[Test Service]
type=service

View File

@ -28,7 +28,7 @@ Using MaxScale as a replication proxy is much the same as using MaxScale as a pr
## Service Configuration
As with any MaxScale configuration a good starting point is with the service definition with the MaxScale.cnf file. The service requires a name which is the section name in the ini file, a type parameter with a value of service and the name of the router plugin that should be loaded. In the case of replication proxies this router name is binlogrouter.
As with any MaxScale configuration a good starting point is with the service definition with the maxscale.cnf file. The service requires a name which is the section name in the ini file, a type parameter with a value of service and the name of the router plugin that should be loaded. In the case of replication proxies this router name is binlogrouter.
[Replication]
@ -84,7 +84,7 @@ This optional parameter allows for the administrator to define the number of the
### binlogdir
This parameter allows the location that MaxScale uses to store binlog files to be set. If this parameter is not set to a directory name then MaxScale will store the binlog files in the directory $MAXSCALE_HOME/<Service Name>.
This parameter allows the location that MaxScale uses to store binlog files to be set. If this parameter is not set to a directory name then MaxScale will store the binlog files in the directory /var/cache/maxscale/<Service Name>.
### heartbeat

View File

@ -32,7 +32,7 @@ Upon successful completion of the installation command you will have MaxScale in
### Creating Your MaxScale Configuration
The first step in the creation of your MaxScale.cnf file is to define the global maxscale section. This section configures the number of threads MaxScale uses. A good rule of thumb is to use at most as may threads as you have CPUs. MaxScale uses few threads for internal operations so one or two threads less than the maximum should be enough.
The first step in the creation of your maxscale.cnf file is to define the global maxscale section. This section configures the number of threads MaxScale uses. A good rule of thumb is to use at most as may threads as you have CPUs. MaxScale uses few threads for internal operations so one or two threads less than the maximum should be enough.
```
[maxscale]
@ -92,7 +92,7 @@ After this we have a fully working configuration and we can move on to starting
Upon completion of the configuration process MaxScale is ready to be started . This may either be done manually by running the maxscale command or via the service interface. The service scripts are located in the `/etc/init.d/` folder and are accessible through both the `service` and `systemctl` commands.
After starting MaxScale check the error log in /usr/local/mariadb-maxscale/log to see if any errors are detected in the configuration file. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured.
After starting MaxScale check the error log in /var/log/maxscale to see if any errors are detected in the configuration file. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured.
MaxScale is now ready to start accepting client connections and routing them. Queries are routed to the right servers based on the database they target and switching between the shards is seamless since MaxScale keeps the session state intact between servers.

View File

@ -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.

69
Documentation/maxscale.1 Normal file
View File

@ -0,0 +1,69 @@
.TH maxscale 1
.SH NAME
maxscale - The intelligent proxy
.SH SYNOPSIS
.B maxscale
[\fIOPTIONS...\fR]
.SH DESCRIPTION
The MariaDB Corporation MaxScale is an intelligent proxy that allows forwarding of
database statements to one or more database servers using complex rules,
a semantic understanding of the database statements and the roles of
the various servers within the backend cluster of databases.
MaxScale is designed to provide load balancing and high availability
functionality transparently to the applications. In addition it provides
a highly scalable and flexible architecture, with plugin components to
support different protocols and routing decisions.
.SH OPTIONS
.TP
.BR "-d, --nodaemon"
Run MaxScale in the terminal process
.TP
.BR -f " \fIFILE\fB, --config=\fIFILE\fR"
Relative or absolute pathname of MaxScale configuration file to load.
.TP
.BR -l "[\fIfile|shm\fB], --log=[\fIfile|shm\fB]"
Log trace and debug logs to file or shared memory. The debug and trace logs are disabled by default and if enabled, will log to shared memory.
.TP
.BR -L " \fIPATH\fB, --logdir=\fIPATH\fB"
Path to log file directory.
.TP
.BR -D " \fIPATH\fB, --datadir=\fIPATH\fB"
Path to data directory. This is where the embedded mysql tables are stored in addition to other MaxScale specific data.
.TP
.BR -C " \fIPATH\fB, --configdir=\fIPATH\fB"
Path to configuration file directory. MaxScale will look for the \fImaxscale.cnf\fR file from this folder.
.TP
.BR -B " \fIPATH\fB, --libdir=\fIPATH\fB"
Path to module directory. Modules are only searched from this folder.
.TP
.BR -A " \fIPATH\fB, --cachedir=\fIPATH\fB"
Path to cache directory. This is where MaxScale stores cached authentication data.
.TP
.BR -P " \fIPATH\fB, --piddir=\fIPATH\fB"
Location of MaxScale's PID file.
.TP
.BR -U " \fIUSER\fB, --user=\fIUSER\fB"
Run MaxScale as another user. The user ID and group ID of this user are used to run MaxScale.
.TP
.BR -s " [\fIyes\fB|\fIno\fB], --syslog=[\fIyes\fB|\fIno\fB]"
Log messages to syslog.
.TP
.BR -S " [\fIyes\fB|\fIno\fB], \fB--maxscalelog=[\fIyes\fB|\fIno\fB]"
Log messages to MaxScale's own log files.
.TP
.BR "-v, --version"
Print version information and exit.
.TP
.BR "-?, --help"
Show the help information for MaxScale and exit.
.SH EXAMPLES
Tutorials on GitHub:
.UR https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Documentation-Contents.md#tutorials
.UE
.SH SEE ALSO
The MaxScale documentation on GitHub:
.UR https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Documentation-Contents.md
.UE

View File

@ -7,4 +7,4 @@ if(HIST)
else()
message(STATUS "Could not find editline library. MaxAdmin will be built without it.")
endif()
install(TARGETS maxadmin DESTINATION bin)
install(TARGETS maxadmin DESTINATION ${MAXSCALE_BINDIR})

View File

@ -0,0 +1,11 @@
# Set the install layout
include(GNUInstallDirs)
set(MAXSCALE_LIBDIR ${CMAKE_INSTALL_LIBDIR}/maxscale CACHE PATH "Library installation path")
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")
# 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/)")

View File

@ -9,17 +9,23 @@ macro(set_maxscale_version)
# MaxScale version number
set(MAXSCALE_VERSION_MAJOR "1")
set(MAXSCALE_VERSION_MINOR "1")
set(MAXSCALE_VERSION_PATCH "1")
set(MAXSCALE_VERSION_MINOR "2")
set(MAXSCALE_VERSION_PATCH "0")
set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
# This should be incremented each time a package is rebuilt
set(MAXSCALE_BUILD_NUMBER 2)
set(MAXSCALE_BUILD_NUMBER 1)
endmacro()
macro(set_variables)
# Use C99
set(USE_C99 FALSE 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")
@ -132,29 +138,9 @@ macro(check_deps)
endif()
# set(MAXSCALE_DEPS aio ssl crypt crypto z m dl rt pthread)
# foreach(lib ${MAXSCALE_DEPS})
# find_library(lib${lib} ${lib})
# if((DEFINED lib${lib}) AND (${lib${lib}} MATCHES "NOTFOUND"))
# set(DEPS_ERROR TRUE)
# set(FAILED_DEPS "${FAILED_DEPS} lib${lib}")
# elseif(DEBUG_OUTPUT)
# message(STATUS "Library was found at: ${lib${lib}}")
# endif()
# endforeach()
# if(DEPS_ERROR)
# set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
# message(FATAL_ERROR "Cannot find dependencies: ${FAILED_DEPS}")
# endif()
endmacro()
macro(check_dirs)
# This variable is used to prevent redundant checking of dependencies
set(DEPS_OK TRUE CACHE BOOL "If all the dependencies were found.")
# Find the MySQL headers if they were not defined
if(DEFINED MYSQL_DIR)
@ -168,7 +154,6 @@ macro(check_dirs)
debugmsg("Search returned: ${MYSQL_DIR_LOC}")
if(${MYSQL_DIR_LOC} MATCHES "NOTFOUND")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
message(FATAL_ERROR "Fatal Error: MySQL headers were not found.")
else()
set(MYSQL_DIR ${MYSQL_DIR_LOC} CACHE PATH "Path to MySQL headers" FORCE)
@ -193,7 +178,6 @@ debugmsg("Search returned: ${MYSQL_DIR_LOC}")
else()
find_file(ERRMSG_FILE errmsg.sys PATHS /usr/share /usr/share/mysql /usr/local/share/mysql PATH_SUFFIXES english mysql/english)
if(${ERRMSG_FILE} MATCHES "NOTFOUND")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
message(FATAL_ERROR "Fatal Error: The errmsg.sys file was not found, please define the path to it by using -DERRMSG=<path>")
else()
message(STATUS "Using errmsg.sys found at: ${ERRMSG_FILE}")
@ -202,75 +186,12 @@ debugmsg("Search returned: ${MYSQL_DIR_LOC}")
set(ERRMSG ${ERRMSG_FILE} CACHE FILEPATH "Path to the errmsg.sys file." FORCE)
unset(ERRMSG_FILE)
# Find the embedded mysql library
# if (DEFINED EMBEDDED_LIB)
# if( NOT (IS_DIRECTORY ${EMBEDDED_LIB}) )
# debugmsg("EMBEDDED_LIB is not a directory: ${EMBEDDED_LIB}")
# if(${CMAKE_VERSION} VERSION_LESS 2.8.12 )
# set(COMP_VAR PATH)
# else()
# set(COMP_VAR DIRECTORY)
# endif()
# get_filename_component(EMBEDDED_LIB ${EMBEDDED_LIB} ${COMP_VAR})
# debugmsg("EMBEDDED_LIB directory component: ${EMBEDDED_LIB}")
# endif()
# debugmsg("Searching for the embedded library at: ${EMBEDDED_LIB}")
# endif()
# if(STATIC_EMBEDDED)
# debugmsg("Using the static embedded library...")
# set(OLD_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
# set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
# if (DEFINED EMBEDDED_LIB)
# debugmsg("Searching for libmysqld.a at: ${EMBEDDED_LIB}")
# find_library(EMBEDDED_LIB_STATIC libmysqld.a PATHS ${EMBEDDED_LIB} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH)
# else()
# find_library(EMBEDDED_LIB_STATIC libmysqld.a PATH_SUFFIXES mysql mariadb)
# endif()
# debugmsg("Search returned: ${EMBEDDED_LIB_STATIC}")
# set(EMBEDDED_LIB ${EMBEDDED_LIB_STATIC} CACHE FILEPATH "Path to libmysqld" FORCE)
# set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_SUFFIXES})
# else()
# debugmsg("Using the dynamic embedded library...")
# set(OLD_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
# set(CMAKE_FIND_LIBRARY_SUFFIXES ".so")
# if (DEFINED EMBEDDED_LIB)
# debugmsg("Searching for libmysqld.so at: ${EMBEDDED_LIB}")
# find_library(EMBEDDED_LIB_DYNAMIC mysqld PATHS ${EMBEDDED_LIB} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH)
# else()
# find_library(EMBEDDED_LIB_DYNAMIC mysqld PATH_SUFFIXES mysql mariadb)
# endif()
# debugmsg("Search returned: ${EMBEDDED_LIB_DYNAMIC}")
# set(EMBEDDED_LIB ${EMBEDDED_LIB_DYNAMIC} CACHE FILEPATH "Path to libmysqld" FORCE)
# set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_SUFFIXES})
# endif()
# unset(EMBEDDED_LIB_DYNAMIC)
# unset(EMBEDDED_LIB_STATIC)
# unset(OLD_SUFFIXES)
# # Inform the user about the embedded library
# if( (${EMBEDDED_LIB} MATCHES "NOTFOUND") OR (${EMBEDDED_LIB} MATCHES "NOTFOUND"))
# set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
# message(FATAL_ERROR "Library not found: libmysqld. If your install of MySQL is in a non-default location, please provide the location with -DEMBEDDED_LIB=<path to library>")
# else()
# get_filename_component(EMBEDDED_LIB ${EMBEDDED_LIB} REALPATH)
# message(STATUS "Using embedded library: ${EMBEDDED_LIB}")
# endif()
# Check which init.d script to install
if(WITH_SCRIPTS)
find_file(RPM_FNC functions PATHS /etc/rc.d/init.d)
if(${RPM_FNC} MATCHES "RPM_FNC-NOTFOUND")
find_file(DEB_FNC init-functions PATHS /lib/lsb)
if(${DEB_FNC} MATCHES "DEB_FNC-NOTFOUND")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
message(FATAL_ERROR "Cannot find required init-functions in /lib/lsb/ or /etc/rc.d/init.d/, please confirm that your system files are OK.")
else()
set(DEB_BASED TRUE CACHE BOOL "If init.d script uses /lib/lsb/init-functions instead of /etc/rc.d/init.d/functions.")

6
cmake/package_deb.cmake Normal file
View File

@ -0,0 +1,6 @@
# DEB specific CPack configuration parameters
set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB")
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_BINARY_DIR}/postinst;{CMAKE_BINARY_DIR}/postrm")
execute_process(COMMAND dpgk --print-architecture OUTPUT_VARIABLE DEB_ARCHITECTURE)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${DEB_ARCHITECTURE})
set (CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)

13
cmake/package_rpm.cmake Normal file
View File

@ -0,0 +1,13 @@
# RPM specific CPack configuration parameters
set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM")
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)
set(CPACK_RPM_PACKAGE_NAME "maxscale")
set(CPACK_RPM_PACKAGE_VENDOR "MariaDB Corporation Ab")
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/etc /etc/ld.so.conf.d /etc/init.d /etc/rc.d/init.d")
set(CPACK_RPM_SPEC_MORE_DEFINE "%define ignore \#")
set(CPACK_RPM_USER_FILELIST "%ignore /etc/init.d")
set(CPACK_RPM_USER_FILELIST "%ignore /etc/ld.so.conf.d")
set(CPACK_RPM_USER_FILELIST "%ignore /etc")

View File

@ -1,4 +1,5 @@
execute_process(COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -c ${CMAKE_BINARY_DIR} &>/dev/null 2> /dev/null > /dev/null")
execute_process(COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -f ${CMAKE_BINARY_DIR}/maxscale.cnf --logdir=${CMAKE_BINARY_DIR}/ --datadir=${CMAKE_BINARY_DIR}/ --cachedir=${CMAKE_BINARY_DIR}/ --piddir=${CMAKE_BINARY_DIR}/ &> ${CMAKE_BINARY_DIR}/maxscale.output"
OUTPUT_VARIABLE MAXSCALE_OUT)
execute_process(COMMAND make test RESULT_VARIABLE RVAL)
execute_process(COMMAND killall maxscale)
if(NOT RVAL EQUAL 0)

View File

@ -18,12 +18,11 @@
### END INIT INFO
#############################################
# MaxScale HOME, PIDFILE, LIB
# MaxScale PIDFILE and LIB
#############################################
export MAXSCALE_HOME=@CMAKE_INSTALL_PREFIX@
export MAXSCALE_PIDFILE=$MAXSCALE_HOME/log/maxscale.pid
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MAXSCALE_HOME/lib
export MAXSCALE_PIDFILE=@MAXSCALE_VARDIR@/run/maxscale/maxscale.pid
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@CMAKE_INSTALL_PREFIX@/@MAXSCALE_LIBDIR@/maxscale
###############################
# LSB Exit codes (non-Status)
@ -39,7 +38,7 @@ _RETVAL_STATUS_OK=0
_RETVAL_STATUS_NOT_RUNNING=3
# Sanity checks.
[ -x $MAXSCALE_HOME/bin/maxscale ] || exit $_RETVAL_NOT_INSTALLED
[ -x @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale ] || exit $_RETVAL_NOT_INSTALLED
# Source function library.
. /etc/rc.d/init.d/functions
@ -52,23 +51,23 @@ RETVAL=0
start() {
echo -n $"Starting MaxScale: "
my_check=`status -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale`
my_check=`status -p $MAXSCALE_PIDFILE @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale`
CHECK_RET=$?
[ $CHECK_RET -eq 0 ] && echo -n " found $my_check" && success && CHECK_RET=0
daemon --pidfile $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale >& /dev/null
daemon --pidfile $MAXSCALE_PIDFILE @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale --user=maxscale >& /dev/null
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$servicename
if [ $CHECK_RET -ne 0 ]; then
sleep 2
my_check=`status -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale`
my_check=`status -p $MAXSCALE_PIDFILE @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale`
CHECK_RET=$?
[ $CHECK_RET -eq 0 ] && echo -n $my_check && success || failure
fi
# Return rigth code
# Return right code
if [ $RETVAL -ne 0 ]; then
failure
RETVAL=$_RETVAL_NOT_RUNNING
@ -100,7 +99,7 @@ stop() {
reload() {
echo -n $"Reloading MaxScale: "
killproc -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale -HUP
killproc -p $MAXSCALE_PIDFILE @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale -HUP
RETVAL=$?
echo
}

30
etc/lsyncd_example.conf Normal file
View File

@ -0,0 +1,30 @@
-- Lsyncd will log to these two files.
settings{
logfile = "/var/log/maxscale/maxscale-ha.log",
statusFile = "/var/log/maxscale/maxscale-ha-status.log"
}
-- Copy and paste the sync section and change the host value to add new remote targets.
sync{
default.rsyncssh,
-- This is where the maxscale.cnf file is copied from.
source="/etc",
-- This is the user and host where the maxscale.cnf is copied to.
host="user@127.0.0.1",
-- This is where the maxscale.cnf is copied to on the remote host.
targetdir="/etc",
-- This is an optional section which defines a custom SSH port. Uncomment to enable.
-- ssh={port=2222},
-- These are values passed to rsync. Only change these if you know what you are doing.
rsync={
compress=true,
_extra = {[[--filter=+ *maxscale.cnf]],
[[--filter=- **]]}
}
}

12
etc/maxscale.service.in Normal file
View File

@ -0,0 +1,12 @@
[Unit]
Description=MariaDB MaxScale Database Proxy
After=network.target
[Service]
Type=forking
Restart=on-failure
PIDFile=@MAXSCALE_VARDIR@/run/maxscale/maxscale.pid
ExecStart=@CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale --user=maxscale
[Install]
WantedBy=multi-user.target

View File

@ -1,5 +1,62 @@
#!/bin/sh
cp @CMAKE_INSTALL_PREFIX@/maxscale /etc/init.d/
cp @CMAKE_INSTALL_PREFIX@/maxscale.conf /etc/ld.so.conf.d/
# Create directories
mkdir -p @CMAKE_INSTALL_PREFIX@/@MAXSCALE_LIBDIR@
mkdir -p @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@
mkdir -p @CMAKE_INSTALL_PREFIX@/@MAXSCALE_SHAREDIR@
mkdir -p @CMAKE_INSTALL_PREFIX@/@MAXSCALE_DOCDIR@
# MAXSCALE_VARDIR is an absolute path to /var by default
mkdir -p @MAXSCALE_VARDIR@/log/maxscale
mkdir -p @MAXSCALE_VARDIR@/lib/maxscale
mkdir -p @MAXSCALE_VARDIR@/cache/maxscale
mkdir -p @MAXSCALE_VARDIR@/run/maxscale
# Create MaxScale user
if [ -f "/etc/passwd" -a "$(grep -c 'maxscale' /etc/passwd)" -eq 0 ]
then
useradd -r -s /bin/false maxscale
groupadd maxscale
fi
# Change the owner of the directories to maxscale:maxscale
chown maxscale:maxscale @MAXSCALE_VARDIR@/log/maxscale
chown maxscale:maxscale @MAXSCALE_VARDIR@/lib/maxscale
chown maxscale:maxscale @MAXSCALE_VARDIR@/cache/maxscale
chown maxscale:maxscale @MAXSCALE_VARDIR@/run/maxscale
chmod 0755 @MAXSCALE_VARDIR@/log/maxscale
chmod 0755 @MAXSCALE_VARDIR@/lib/maxscale
chmod 0755 @MAXSCALE_VARDIR@/cache/maxscale
chmod 0755 @MAXSCALE_VARDIR@/run/maxscale
# Copy init.d script and ldconfig file
if [ -f "@CMAKE_INSTALL_PREFIX@/@MAXSCALE_SHAREDIR@/maxscale" ]
then
cp @CMAKE_INSTALL_PREFIX@/@MAXSCALE_SHAREDIR@/maxscale /etc/init.d/
fi
if [ -f "@CMAKE_INSTALL_PREFIX@/@MAXSCALE_SHAREDIR@/maxscale.conf" ]
then
cp @CMAKE_INSTALL_PREFIX@/@MAXSCALE_SHAREDIR@/maxscale.conf /etc/init.d/
fi
if [ -d "/usr/lib/systemd/system" -a -f @CMAKE_INSTALL_PREFIX@/@MAXSCALE_SHAREDIR@/maxscale.service ]
then
cp @CMAKE_INSTALL_PREFIX@/@MAXSCALE_SHAREDIR@/maxscale.service /usr/lib/systemd/system
fi
/sbin/ldconfig
cat <<EOF >& 2
********** Notice: MaxScale 1.2 Changes **************
MaxScale 1.2 has changed the default installation locations
and various files have changed locations. The configuration
file is now read from /etc/maxscale.cnf (note the lower case name)
and MaxScale data is in /var/lib/maxscale/.
The default location of binary log files and the authentication cache changed from
/usr/local/mariadb-maxscale/<Service name> to /var/lib/maxscale/<Service name>.
******************************************************
EOF

View File

@ -3,4 +3,11 @@ if [ "$1" -eq 0 ]
then
rm -f /etc/init.d/maxscale
rm -f /etc/ld.so.conf.d/maxscale.conf
rm -f /usr/lib/systemd/system/maxscale.service
else
# Copy and rename config from old location
if [ -f "/usr/local/mariadb-maxscale/etc/MaxScale.cnf" ]
then
cp "/usr/local/mariadb-maxscale/etc/MaxScale.cnf" "/etc/maxscale.cnf"
fi
fi

View File

@ -21,9 +21,8 @@
# MaxScale HOME, PIDFILE, LIB
#############################################
export MAXSCALE_HOME=@CMAKE_INSTALL_PREFIX@
export MAXSCALE_PIDFILE=$MAXSCALE_HOME/log/maxscale.pid
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MAXSCALE_HOME/lib
export MAXSCALE_PIDFILE=@MAXSCALE_VARDIR@/run/maxscale/maxscale.pid
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@CMAKE_INSTALL_PREFIX@/@MAXSCALE_LIBDIR@/maxscale
###############################
# LSB Exit codes (non-Status)
@ -39,14 +38,14 @@ _RETVAL_STATUS_OK=0
_RETVAL_STATUS_NOT_RUNNING=3
# Sanity checks.
[ -x $MAXSCALE_HOME/bin/maxscale ] || exit $_RETVAL_NOT_INSTALLED
[ -x @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale ] || exit $_RETVAL_NOT_INSTALLED
#################################
# stop/start/status related vars
#################################
NAME=maxscale
DAEMON=$MAXSCALE_HOME/bin/maxscale
DAEMON=@CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale
DAEMON_OPTS= --user=maxscale
# Source function library.
. /lib/lsb/init-functions
@ -58,11 +57,11 @@ RETVAL=0
start() {
log_daemon_msg "Starting MaxScale"
start_daemon -p $MAXSCALE_PIDFILE $DAEMON 2> /dev/null > /dev/null
start_daemon -p "$MAXSCALE_PIDFILE" "$DAEMON" "$DAEMON_OPTS" 2> /dev/null > /dev/null
sleep 2
status_of_proc -p $MAXSCALE_PIDFILE $DAEMON $NAME
status_of_proc -p "$MAXSCALE_PIDFILE" "$DAEMON" $NAME
log_end_msg $?
}
@ -78,13 +77,13 @@ stop() {
reload() {
log_daemon_msg "Reloading MaxScale"
kill -HUP $(cat $MAXSCALE_PIDFILE)
kill -HUP $(cat "$MAXSCALE_PIDFILE")
log_end_msg $?
}
maxscale_wait_stop() {
PIDTMP=$(pidofproc -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale)
PIDTMP=$(pidofproc -p "$MAXSCALE_PIDFILE" "$DAEMON")
kill -TERM "${PIDTMP:-}" 2> /dev/null;
if [ -n "${PIDTMP:-}" ] && kill -0 "${PIDTMP:-}" 2> /dev/null; then
local i=0
@ -116,7 +115,7 @@ case "$1" in
# return 3 on any error
log_daemon_msg "Checking MaxScale"
status_of_proc -p $MAXSCALE_PIDFILE $DAEMON $NAME
status_of_proc -p "$MAXSCALE_PIDFILE" "$DAEMON" $NAME
RETVAL=$?
if [ $RETVAL -ne 0 ]; then

View File

@ -2,8 +2,8 @@ if(LOG_DEBUG)
add_definitions(-DSS_LOG_DEBUG)
endif()
add_library(log_manager SHARED log_manager.cc)
target_link_libraries(log_manager pthread aio stdc++ utils)
install(TARGETS log_manager DESTINATION lib)
target_link_libraries(log_manager pthread aio stdc++)
install(TARGETS log_manager DESTINATION ${MAXSCALE_LIBDIR})
if(BUILD_TESTS)
add_subdirectory(test)
endif()

View File

@ -1413,7 +1413,7 @@ int skygw_log_write_flush(
/**
* Write log string to buffer and add to file write list.
*/
for(i = LOGFILE_FIRST;i<=LOGFILE_LAST;i <<=1)
for (i = LOGFILE_FIRST; i<LOGFILE_LAST ;i <<=1)
{
/**
* If particular log is disabled in general and it is not enabled for
@ -1476,7 +1476,7 @@ int skygw_log_write(
* Write log string to buffer and add to file write list.
*/
for(i = LOGFILE_FIRST;i<=LOGFILE_LAST;i <<=1)
for (i = LOGFILE_FIRST; i<=LOGFILE_LAST; i <<=1)
{
/**
* If particular log is disabled in general and it is not enabled for
@ -1780,7 +1780,6 @@ static bool fnames_conf_init(
case 's':
/** record list of log file ids for later use */
if(do_syslog)
shmem_id_str = optarg;
break;
case 'h':
@ -1812,12 +1811,14 @@ static bool fnames_conf_init(
strdup(get_logpath_default()) : fn->fn_logpath;
/** Set identity string for syslog if it is not set in config.*/
if(do_syslog)
{
syslog_ident_str =
(syslog_ident_str == NULL ?
(argv == NULL ? strdup(program_invocation_short_name) :
strdup(*argv)) :
syslog_ident_str);
}
/* ss_dfprintf(stderr, "\n\n\tCommand line : ");
for (i=0; i<argc; i++) {
ss_dfprintf(stderr, "%s ", argv[i]);

View File

@ -1,5 +1,5 @@
install(FILES nagios/check_maxscale_monitors.pl DESTINATION plugins/nagios)
install(FILES nagios/check_maxscale_resources.pl DESTINATION plugins/nagios)
install(FILES nagios/check_maxscale_threads.pl DESTINATION plugins/nagios)
install(FILES nagios/maxscale_commands.cfg DESTINATION plugins/nagios)
install(FILES nagios/server1.cfg DESTINATION plugins/nagios)
install(FILES nagios/check_maxscale_monitors.pl DESTINATION ${MAXSCALE_SHAREDIR}/plugins/nagios)
install(FILES nagios/check_maxscale_resources.pl DESTINATION ${MAXSCALE_SHAREDIR}/plugins/nagios)
install(FILES nagios/check_maxscale_threads.pl DESTINATION ${MAXSCALE_SHAREDIR}/plugins/nagios)
install(FILES nagios/maxscale_commands.cfg DESTINATION ${MAXSCALE_SHAREDIR}/plugins/nagios)
install(FILES nagios/server1.cfg DESTINATION ${MAXSCALE_SHAREDIR}/plugins/nagios)

View File

@ -1,5 +1,5 @@
add_library(query_classifier SHARED query_classifier.cc)
install(TARGETS query_classifier DESTINATION lib)
install(TARGETS query_classifier COMPONENT lib DESTINATION ${MAXSCALE_LIBDIR})
if(BUILD_TESTS)
add_subdirectory(test)
endif()

View File

@ -1485,7 +1485,8 @@ void parsing_info_done(
void* ptr)
{
parsing_info_t* pi;
THD* thd;
if (ptr)
{
pi = (parsing_info_t *)ptr;
@ -1496,6 +1497,8 @@ void parsing_info_done(
if (mysql->thd != NULL)
{
thd = (THD*)mysql->thd;
thd->end_statement ();
(*mysql->methods->free_embedded_thd)(mysql);
mysql->thd = NULL;
}

View File

@ -1,5 +1,5 @@
if(BUILD_TESTS OR BUILD_TOOLS)
add_library(fullcore STATIC adminusers.c atomic.c config.c buffer.c dbusers.c dcb.c filter.c gwbitmask.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c memlog.c modutil.c monitor.c poll.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c)
add_library(fullcore STATIC adminusers.c atomic.c config.c buffer.c dbusers.c dcb.c filter.c gwbitmask.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c memlog.c modutil.c monitor.c poll.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c gwdirs.c externcmd.c)
if(WITH_JEMALLOC)
target_link_libraries(fullcore ${JEMALLOC_LIBRARIES})
elseif(WITH_TCMALLOC)
@ -12,7 +12,7 @@ add_executable(maxscale atomic.c buffer.c spinlock.c gateway.c
gw_utils.c utils.c dcb.c load_utils.c session.c service.c server.c
poll.c config.c users.c hashtable.c dbusers.c thread.c gwbitmask.c
monitor.c adminusers.c secrets.c filter.c modutil.c hint.c
housekeeper.c memlog.c resultset.c)
housekeeper.c memlog.c resultset.c gwdirs.c externcmd.c)
if(WITH_JEMALLOC)
target_link_libraries(maxscale ${JEMALLOC_LIBRARIES})
@ -21,15 +21,15 @@ elseif(WITH_TCMALLOC)
endif()
target_link_libraries(maxscale ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} ${CURL_LIBRARIES} log_manager utils ssl aio pthread crypt dl crypto inih z rt m stdc++)
install(TARGETS maxscale DESTINATION bin)
install(TARGETS maxscale DESTINATION ${MAXSCALE_BINDIR})
add_executable(maxkeys maxkeys.c secrets.c utils.c)
add_executable(maxkeys maxkeys.c secrets.c utils.c gwdirs.c)
target_link_libraries(maxkeys log_manager utils pthread crypt crypto)
install(TARGETS maxkeys DESTINATION bin)
install(TARGETS maxkeys DESTINATION ${MAXSCALE_BINDIR})
add_executable(maxpasswd maxpasswd.c secrets.c utils.c)
add_executable(maxpasswd maxpasswd.c secrets.c utils.c gwdirs.c)
target_link_libraries(maxpasswd log_manager utils pthread crypt crypto)
install(TARGETS maxpasswd DESTINATION bin)
install(TARGETS maxpasswd DESTINATION ${MAXSCALE_BINDIR})
if(BUILD_TESTS)
add_subdirectory(test)

View File

@ -19,13 +19,16 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define _XOPEN_SOURCE
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700
#endif
#include <unistd.h>
#include <crypt.h>
#include <users.h>
#include <adminusers.h>
#include <skygw_utils.h>
#include <log_manager.h>
#include <gwdirs.h>
/** Defined in log_manager.cc */
extern int lm_enabled_logfiles_bitmask;
@ -119,12 +122,7 @@ char fname[1024], *home;
char uname[80], passwd[80];
initialise();
if ((home = getenv("MAXSCALE_HOME")) != NULL && strlen(home) < 1024){
sprintf(fname, "%s/etc/passwd", home);
}
else{
sprintf(fname, "/usr/local/mariadb-maxscale/etc/passwd");
}
sprintf(fname, "%s/passwd", get_datadir());
if ((fp = fopen(fname, "r")) == NULL)
return NULL;
if ((rval = users_alloc()) == NULL)
@ -155,12 +153,7 @@ FILE *fp;
char fname[1024], *home, *cpasswd;
initialise();
if ((home = getenv("MAXSCALE_HOME")) != NULL && strlen(home) < 1024){
sprintf(fname, "%s/etc/passwd", home);
}
else{
sprintf(fname, "/usr/local/mariadb-maxscale/etc/passwd");
}
sprintf(fname, "%s/passwd", get_datadir());
if (users == NULL)
{
@ -253,15 +246,8 @@ char* admin_remove_user(
/**
* Open passwd file and remove user from the file.
*/
if ((home = getenv("MAXSCALE_HOME")) != NULL &&
strnlen(home,PATH_MAX) < PATH_MAX &&
strnlen(home,PATH_MAX) > 0) {
sprintf(fname, "%s/etc/passwd", home);
sprintf(fname_tmp, "%s/etc/passwd_tmp", home);
} else {
sprintf(fname, "/usr/local/mariadb-maxscale/etc/passwd");
sprintf(fname_tmp, "/usr/local/mariadb-maxscale/etc/passwd_tmp");
}
sprintf(fname, "%s/passwd", get_datadir());
sprintf(fname_tmp, "%s/passwd_tmp", get_datadir());
/**
* Rewrite passwd file from memory.
*/

View File

@ -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;
}

View File

@ -231,7 +231,7 @@ int rval;
strcpy(version_string,tmp);
}
ptr = strstr(tmp, "-embedded");
ptr = strstr(version_string, "-embedded");
if (ptr) {
*ptr = '\0';
}
@ -345,6 +345,8 @@ hashtable_memory_fns(monitorhash,strdup,NULL,free,NULL);
char *weightby;
char *version_string;
char *subservices;
char *ssl,*ssl_cert,*ssl_key,*ssl_ca_cert,*ssl_version;
char* ssl_cert_verify_depth;
bool is_rwsplit = false;
bool is_schemarouter = false;
char *allow_localhost_match_wildcard_host;
@ -353,6 +355,12 @@ hashtable_memory_fns(monitorhash,strdup,NULL,free,NULL);
user = config_get_value(obj->parameters, "user");
auth = config_get_value(obj->parameters, "passwd");
subservices = config_get_value(obj->parameters, "subservices");
ssl = config_get_value(obj->parameters, "ssl");
ssl_cert = config_get_value(obj->parameters, "ssl_cert");
ssl_key = config_get_value(obj->parameters, "ssl_key");
ssl_ca_cert = config_get_value(obj->parameters, "ssl_ca_cert");
ssl_version = config_get_value(obj->parameters, "ssl_version");
ssl_cert_verify_depth = config_get_value(obj->parameters, "ssl_cert_verify_depth");
enable_root_user = config_get_value(
obj->parameters,
"enable_root_user");
@ -417,7 +425,21 @@ hashtable_memory_fns(monitorhash,strdup,NULL,free,NULL);
}
if (version_string) {
/** Add the 5.5.5- string to the start of the version string if
* the version string starts with "10.".
* This mimics MariaDB 10.0 replication which adds 5.5.5- for backwards compatibility. */
if(strncmp(version_string,"10.",3) == 0)
{
((SERVICE *)(obj->element))->version_string = malloc((strlen(version_string) +
strlen("5.5.5-") + 1) * sizeof(char));
strcpy(((SERVICE *)(obj->element))->version_string,"5.5.5-");
strcat(((SERVICE *)(obj->element))->version_string,version_string);
}
else
{
((SERVICE *)(obj->element))->version_string = strdup(version_string);
}
} else {
if (gateway.version_string)
((SERVICE *)(obj->element))->version_string = strdup(gateway.version_string);
@ -429,7 +451,84 @@ hashtable_memory_fns(monitorhash,strdup,NULL,free,NULL);
max_slave_rlag_str =
config_get_value(obj->parameters,
"max_slave_replication_lag");
if(ssl)
{
if(ssl_cert == NULL)
{
error_count++;
skygw_log_write(LE,"Error: Server certificate missing for service '%s'."
"Please provide the path to the server certificate by adding the ssl_cert=<path> parameter",
obj->object);
}
if(ssl_ca_cert == NULL)
{
error_count++;
skygw_log_write(LE,"Error: CA Certificate missing for service '%s'."
"Please provide the path to the certificate authority certificate by adding the ssl_ca_cert=<path> parameter",
obj->object);
}
if(ssl_key == NULL)
{
error_count++;
skygw_log_write(LE,"Error: Server private key missing for service '%s'. "
"Please provide the path to the server certificate key by adding the ssl_key=<path> parameter"
,obj->object);
}
if(access(ssl_ca_cert,F_OK) != 0)
{
skygw_log_write(LE,"Error: Certificate authority file for service '%s' not found: %s",
obj->object,
ssl_ca_cert);
error_count++;
}
if(access(ssl_cert,F_OK) != 0)
{
skygw_log_write(LE,"Error: Server certificate file for service '%s' not found: %s",
obj->object,
ssl_cert);
error_count++;
}
if(access(ssl_key,F_OK) != 0)
{
skygw_log_write(LE,"Error: Server private key file for service '%s' not found: %s",
obj->object,
ssl_key);
error_count++;
}
if(error_count == 0)
{
if(serviceSetSSL(obj->element,ssl) != 0)
{
skygw_log_write(LE,"Error: Unknown parameter for service '%s': %s",obj->object,ssl);
error_count++;
}
else
{
serviceSetCertificates(obj->element,ssl_cert,ssl_key,ssl_ca_cert);
if(ssl_version)
{
if(serviceSetSSLVersion(obj->element,ssl_version) != 0)
{
skygw_log_write(LE,"Error: Unknown parameter value for 'ssl_version' for service '%s': %s",obj->object,ssl_version);
error_count++;
}
}
if(ssl_cert_verify_depth)
{
if(serviceSetSSLVerifyDepth(obj->element,atoi(ssl_cert_verify_depth)) != 0)
{
skygw_log_write(LE,"Error: Invalid parameter value for 'ssl_cert_verify_depth' for service '%s': %s",obj->object,ssl_cert_verify_depth);
error_count++;
}
}
}
}
}
if (enable_root_user)
serviceEnableRootUser(
obj->element,
@ -833,7 +932,7 @@ hashtable_memory_fns(monitorhash,strdup,NULL,free,NULL);
/* if id is not set, do it now */
if (gateway.id == 0) {
setipaddress(&serv_addr.sin_addr, (address == NULL) ? "0.0.0.0" : address);
gateway.id = (unsigned long) (serv_addr.sin_addr.s_addr + port != NULL ? atoi(port) : 0 + getpid());
gateway.id = (unsigned long) (serv_addr.sin_addr.s_addr + (port != NULL ? atoi(port) : 0 + getpid()));
}
if (service && socket && protocol) {
@ -1325,7 +1424,7 @@ int i;
}
else if (strcmp(name, "ms_timestamp") == 0)
{
skygw_set_highp(config_truth_value(value));
skygw_set_highp(config_truth_value((char*)value));
}
else
{
@ -1333,7 +1432,7 @@ int i;
{
if (strcasecmp(name, lognames[i].logname) == 0)
{
if (config_truth_value(value))
if (config_truth_value((char*)value))
skygw_log_enable(lognames[i].logfile);
else
skygw_log_disable(lognames[i].logfile);
@ -1721,6 +1820,9 @@ SERVER *server;
obj->element = server_alloc(address,
protocol,
atoi(port));
server_set_unique_name(obj->element, obj->object);
if (obj->element && monuser && monpw)
{
serverAddMonUser(obj->element,
@ -1908,6 +2010,12 @@ static char *service_params[] =
"version_string",
"filters",
"weightby",
"ssl_cert",
"ssl_ca_cert",
"ssl",
"ssl_key",
"ssl_version",
"ssl_cert_verify_depth",
NULL
};
@ -1929,6 +2037,9 @@ static char *monitor_params[] =
"servers",
"user",
"passwd",
"script",
"events",
"mysql51_replication",
"monitor_interval",
"detect_replication_lag",
"detect_stale_master",

View File

@ -210,7 +210,7 @@ HASHTABLE *oldresources;
oldusers = service->users;
/* digest compare */
if (memcmp(oldusers->cksum, newusers->cksum, SHA_DIGEST_LENGTH) == 0) {
if (oldusers != NULL && memcmp(oldusers->cksum, newusers->cksum, SHA_DIGEST_LENGTH) == 0) {
/* same data, nothing to do */
LOGIF(LD, (skygw_log_write_flush(
LOGFILE_DEBUG,
@ -234,7 +234,7 @@ HASHTABLE *oldresources;
spinlock_release(&service->spin);
if (i) {
if (i && oldusers) {
/* free the old table */
users_free(oldusers);
}
@ -974,7 +974,7 @@ getAllUsers(SERVICE *service, USERS *users)
}
}
if(service->optimize_wildcard && havedb && wildcard_db_grant(dbnm))
if(havedb && wildcard_db_grant(dbnm) && service->optimize_wildcard)
{
rc = add_wildcard_users(users, row[0], row[1], password, row[4], dbnm, service->resources);
skygw_log_write(LOGFILE_DEBUG|LOGFILE_TRACE,"%s: Converted '%s' to %d individual database grants.",service->name,dbnm,rc);
@ -984,9 +984,9 @@ getAllUsers(SERVICE *service, USERS *users)
rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], password, row[4], havedb ? dbnm : NULL);
}
skygw_log_write(LOGFILE_DEBUG,"%s: Adding user:%s host:%s anydb:%s db:%s.",
LOGIF(LD,(skygw_log_write(LOGFILE_DEBUG,"%s: Adding user:%s host:%s anydb:%s db:%s.",
service->name,row[0],row[1],row[4],
havedb ? dbnm : NULL);
havedb ? dbnm : NULL)));
} else {
/* we don't have dbgrants, simply set ANY DB for the user */
rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], password, "Y", NULL);
@ -1033,8 +1033,8 @@ getAllUsers(SERVICE *service, USERS *users)
} else if(rc == -1) {
/** Duplicate user*/
LOGIF(LE,(skygw_log_write(LT|LE,
"Warning: Duplicate MySQL user found for service [%s]: %s@%s%s%s",
LOGIF(LT,(skygw_log_write(LT,
"Duplicate MySQL user found for service [%s]: %s@%s%s%s",
service->name,
row[0],row[1],havedb?" for database: ":"",
havedb ?dbnm:"")));
@ -1118,6 +1118,7 @@ getUsers(SERVICE *service, USERS *users)
MYSQL_DATABASE_MAXLEN;
int dbnames = 0;
int db_grants = 0;
char dbnm[MYSQL_DATABASE_MAXLEN+1];
if (serviceGetUser(service, &service_user, &service_passwd) == 0)
{
@ -1464,16 +1465,40 @@ getUsers(SERVICE *service, USERS *users)
*/
if (db_grants) {
/* we have dbgrants, store them */
bool havedb = false;
/* we have dbgrants, store them */
if(row[5]){
unsigned long *rowlen = mysql_fetch_lengths(result);
memcpy(dbnm,row[5],rowlen[5]);
memset(dbnm + rowlen[5],0,1);
havedb = true;
if(service->strip_db_esc) {
strip_escape_chars(dbnm);
LOGIF(LD, (skygw_log_write(
LOGFILE_DEBUG,
"[%s]: %s -> %s",
service->name,
row[5],
dbnm)));
}
}
if(service->optimize_wildcard && wildcard_db_grant(row[5]))
if(havedb && wildcard_db_grant(row[5]))
{
rc = add_wildcard_users(users, row[0], row[1], password, row[4], row[5], service->resources);
skygw_log_write(LOGFILE_DEBUG|LOGFILE_TRACE,"%s: Converted '%s' to %d individual database grants.",service->name,row[5],rc);
if(service->optimize_wildcard)
{
rc = add_wildcard_users(users, row[0], row[1], password, row[4], dbnm, service->resources);
skygw_log_write(LOGFILE_DEBUG|LOGFILE_TRACE,"%s: Converted '%s' to %d individual database grants.",service->name,row[5],rc);
}
else
{
/** Use ANYDB for wildcard grants */
rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], password, "Y", NULL);
}
}
else
{
rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], password, row[4], row[5]);
rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], password, row[4], havedb ? dbnm : NULL);
}
} else {
@ -1673,6 +1698,41 @@ static int uh_cmpfun( void* v1, void* v2) {
return 0;
}
if(hu2->resource && strlen(hu2->resource) && strchr(hu2->resource,'%') != NULL)
{
regex_t re;
char db[MYSQL_DATABASE_MAXLEN*2 +1];
strcpy(db,hu2->resource);
int len = strlen(db);
char* ptr = strrchr(db,'%');
if(ptr == NULL)
{
return 1;
}
while(ptr)
{
memmove(ptr+1,ptr,(len - (ptr - db)) + 1);
*ptr = '.';
*(ptr + 1) = '*';
len = strlen(db);
ptr = strrchr(db,'%');
}
if((regcomp(&re,db,REG_ICASE|REG_NOSUB)))
{
return 1;
}
if(regexec(&re,hu1->resource,0,NULL,0) == 0)
{
regfree(&re);
return 0;
}
regfree(&re);
}
/* no matches, deny auth */
return 1;
}
@ -1782,18 +1842,6 @@ char *mysql_format_user_entry(void *data)
return mysql_user;
}
/*
* The hash function we use for storing MySQL database names.
*
* @param key The key value
* @return The hash key
*/
int
resource_hash(char *key)
{
return (*key + *(key + 1));
}
/**
* Remove the resources table
*
@ -1817,7 +1865,7 @@ resource_alloc()
{
HASHTABLE *resources;
if ((resources = hashtable_alloc(10, resource_hash, strcmp)) == NULL)
if ((resources = hashtable_alloc(10, simple_str_hash, strcmp)) == NULL)
{
return NULL;
}

File diff suppressed because it is too large Load Diff

169
server/core/externcmd.c Normal file
View File

@ -0,0 +1,169 @@
#include <externcmd.h>
/** Defined in log_manager.cc */
extern int lm_enabled_logfiles_bitmask;
extern size_t log_ses_count[];
extern __thread log_info_t tls_log_info;
/**
* Tokenize a string into arguments suitable for a execvp call.
* @param args Argument string
* @param argv Array of char pointers to be filled with tokenized arguments
* @return 0 on success, -1 on error
*/
int tokenize_arguments(char* args, char** argv)
{
int i = 0;
bool quoted = false;
bool read = false;
bool escaped = false;
char *ptr,*start;
char qc;
start = args;
ptr = start;
while(*ptr != '\0' && i < MAXSCALE_EXTCMD_ARG_MAX)
{
if(escaped)
{
escaped = false;
}
else
{
if(*ptr == '\\')
{
escaped = true;
}
else if(quoted && !escaped && *ptr == qc) /** End of quoted string */
{
*ptr = '\0';
argv[i++] = strdup(start);
read = false;
quoted = false;
}
else if (!quoted)
{
if(isspace(*ptr))
{
*ptr = '\0';
if(read) /** New token */
{
argv[i++] = strdup(start);
read = false;
}
}
else if( *ptr == '\"' || *ptr == '\'')
{
/** New quoted token, strip quotes */
quoted = true;
qc = *ptr;
start = ptr + 1;
}
else if(!read)
{
start = ptr;
read = true;
}
}
}
ptr++;
}
if(read)
argv[i++] = strdup(start);
argv[i] = NULL;
return 0;
}
/**
* Allocate a new external command.
* The name and parameters are copied into the external command structure so
* the original memory can be freed if needed.
* @param command Command to execute with the parameters
* @return Pointer to new external command struct or NULL if an error occurred
*/
EXTERNCMD* externcmd_allocate(char* argstr)
{
EXTERNCMD* cmd;
if(argstr == NULL)
return NULL;
if((cmd = (EXTERNCMD*)malloc(sizeof(EXTERNCMD))) != NULL)
{
if(tokenize_arguments(argstr,cmd->parameters) == -1)
{
free(cmd);
return NULL;
}
if(access(cmd->parameters[0],F_OK) != 0)
{
skygw_log_write(LE,
"Error: Cannot find file: %s",
cmd->parameters[0]);
externcmd_free(cmd);
return NULL;
}
if(access(cmd->parameters[0],X_OK) != 0)
{
skygw_log_write(LE,
"Error: Cannot execute file: %s",
cmd->parameters[0]);
externcmd_free(cmd);
return NULL;
}
}
return cmd;
}
/**
* Free a previously allocated external command.
* @param cmd Command to free
*/
void externcmd_free(EXTERNCMD* cmd)
{
int i;
for(i = 0;cmd->parameters[i] != NULL;i++)
{
free(cmd->parameters[i]);
}
free(cmd);
}
/**
*Execute a command in a separate process.
*@param cmd Command to execute
*@return 0 on success, -1 on error.
*/
int externcmd_execute(EXTERNCMD* cmd)
{
int rval = 0;
pid_t pid;
pid = fork();
if(pid < 0)
{
skygw_log_write(LOGFILE_ERROR,"Error: Failed to execute command '%s', fork failed: [%d] %s",
cmd->parameters[0],errno,strerror(errno));
rval = -1;
}
else if(pid == 0)
{
/** Child process, execute command */
execvp(cmd->parameters[0],cmd->parameters);
_exit(1);
}
else
{
cmd->child = pid;
cmd->n_exec++;
LOGIF(LD,skygw_log_write(LD,"[monitor_exec_cmd] Forked child process %d : %s.",pid,cmd));
}
return rval;
}

File diff suppressed because it is too large Load Diff

29
server/core/gwdirs.c Normal file
View File

@ -0,0 +1,29 @@
#include <gwdirs.h>
/**
* Get the directory with all the modules.
* @return The module directory
*/
char* get_libdir()
{
return libdir?libdir:(char*)default_libdir;
}
/**
* Get the service cache directory
* @return The path to the cache directory
*/
char* get_cachedir()
{
return cachedir?cachedir:(char*)default_cachedir;
}
/**
* Get the service cache directory
* @return The path to the cache directory
*/
char* get_datadir()
{
return maxscaledatadir?maxscaledatadir:(char*)default_datadir;
}

View File

@ -48,6 +48,8 @@
#include <curl/curl.h>
#include <sys/utsname.h>
#include <openssl/sha.h>
#include <gw.h>
#include <gwdirs.h>
/** Defined in log_manager.cc */
extern int lm_enabled_logfiles_bitmask;
@ -104,21 +106,10 @@ WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
return realsize;
}
char* get_maxscale_home(void)
{
char* home = getenv("MAXSCALE_HOME");
if (home == NULL)
{
home = "/usr/local/mariadb-maxscale";
}
return home;
}
/**
* Load the dynamic library related to a gateway module. The routine
* will look for library files in the current directory,
* $MAXSCALE_HOME/modules and /usr/local/mariadb-maxscale/modules.
* the configured folder and /usr/lib64/maxscale.
*
* @param module Name of the module to load
* @param type Type of module, used purely for registration
@ -142,22 +133,17 @@ MODULE_INFO *mod_info = NULL;
*
* Search of the shared object.
*/
snprintf(fname,MAXPATHLEN+1, "./lib%s.so", module);
snprintf(fname, MAXPATHLEN+1,"%s/lib%s.so", get_libdir(), module);
if (access(fname, F_OK) == -1)
{
home = get_maxscale_home ();
snprintf(fname, MAXPATHLEN+1,"%s/modules/lib%s.so", home, module);
if (access(fname, F_OK) == -1)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Unable to find library for "
"module: %s.",
module)));
return NULL;
}
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Unable to find library for "
"module: %s. Module dir: %s",
module, get_libdir())));
return NULL;
}
if ((dlhandle = dlopen(fname, RTLD_NOW|RTLD_LOCAL)) == NULL)

View File

@ -31,19 +31,25 @@
#include <secrets.h>
#include <skygw_utils.h>
#include <log_manager.h>
#include <gwdirs.h>
int main(int argc, char **argv)
{
int arg_count = 6;
int arg_count = 4;
char *home;
char *keyfile;
char** arg_vector;
int rval = 0;
if (argc != 2)
if (argc < 2)
{
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
return 1;
keyfile = "/var/lib/maxscale/";
fprintf(stderr, "Generating .secrets file in /var/lib/maxscale/ ...\n");
}
else
{
keyfile = argv[1];
}
arg_vector = malloc(sizeof(char*)*(arg_count + 1));
if(arg_vector == NULL)
@ -54,26 +60,14 @@ int main(int argc, char **argv)
arg_vector[0] = "logmanager";
arg_vector[1] = "-j";
if ((home = getenv("MAXSCALE_HOME")) != NULL)
{
arg_vector[2] = (char*)malloc((strlen(home) + strlen("/log"))*sizeof(char));
sprintf(arg_vector[2],"%s/log",home);
}
else
{
arg_vector[2] = strdup("/usr/local/mariadb-maxscale/log");
}
arg_vector[3] = "-o";
arg_vector[4] = "-l";
arg_vector[5] = "LOGFILE_ERROR";
arg_vector[6] = NULL;
arg_vector[2] = "/var/log/maxscale/maxkeys";
arg_vector[3] = "-o";
arg_vector[4] = NULL;
skygw_logmanager_init(arg_count,arg_vector);
free(arg_vector[2]);
free(arg_vector);
if (secrets_writeKeys(argv[1]))
if (secrets_writeKeys(keyfile))
{
fprintf(stderr, "Failed to encode the password\n");
rval = 1;

View File

@ -46,9 +46,9 @@ main(int argc, char **argv)
char** arg_vector;
int rval = 0;
if (argc != 2)
if (argc != 3)
{
fprintf(stderr, "Usage: %s <password>\n", argv[0]);
fprintf(stderr, "Usage: %s <file> <password>\n", argv[0]);
return 1;
}
@ -60,18 +60,9 @@ main(int argc, char **argv)
return 1;
}
arg_vector[0] = "logmanager";
arg_vector[1] = "-j";
if ((home = getenv("MAXSCALE_HOME")) != NULL)
{
arg_vector[2] = (char*)malloc((strlen(home) + strlen("/log"))*sizeof(char));
sprintf(arg_vector[2],"%s/log",home);
}
else
{
arg_vector[2] = strdup("/usr/local/mariadb-maxscale/log");
}
arg_vector[0] = strdup("logmanager");
arg_vector[1] = strdup("-j");
arg_vector[2] = strdup("/var/log/maxscale");
arg_vector[3] = "-o";
arg_vector[4] = "-l";
@ -88,9 +79,9 @@ main(int argc, char **argv)
return 1;
}
strncpy(pw,argv[1],80);
strncpy(pw,argv[2],80);
if ((enc = encryptPassword(pw)) != NULL){
if ((enc = encryptPassword(argv[1],pw)) != NULL){
printf("%s\n", enc);
}else{
fprintf(stderr, "Failed to encode the password\n");

View File

@ -841,4 +841,4 @@ int modutil_count_statements(GWBUF* buffer)
}
return num;
}
}

View File

@ -28,6 +28,7 @@
* and monitor id
* 30/10/14 Massimiliano Pinto Addition of disable_master_failback parameter
* 07/11/14 Massimiliano Pinto Addition of monitor network timeouts
* 08/05/15 Markus Makela Moved common monitor variables to MONITOR struct
*
* @endverbatim
*/
@ -65,8 +66,6 @@ MONITOR *mon;
{
return NULL;
}
mon->state = MONITOR_STATE_ALLOC;
mon->name = strdup(name);
if ((mon->module = load_module(module, MODULE_MONITOR)) == NULL)
{
@ -74,13 +73,21 @@ MONITOR *mon;
LOGFILE_ERROR,
"Error : Unable to load monitor module '%s'.",
name)));
free(mon->name);
free(mon);
return NULL;
}
mon->state = MONITOR_STATE_ALLOC;
mon->name = strdup(name);
mon->handle = NULL;
mon->databases = NULL;
mon->password = NULL;
mon->user = NULL;
mon->password = NULL;
mon->read_timeout = DEFAULT_READ_TIMEOUT;
mon->write_timeout = DEFAULT_WRITE_TIMEOUT;
mon->connect_timeout = DEFAULT_CONNECT_TIMEOUT;
mon->interval = MONITOR_INTERVAL;
spinlock_init(&mon->lock);
spinlock_acquire(&monLock);
mon->next = allMonitors;
allMonitors = mon;
@ -100,7 +107,7 @@ monitor_free(MONITOR *mon)
{
MONITOR *ptr;
mon->module->stopMonitor(mon->handle);
mon->module->stopMonitor(mon);
mon->state = MONITOR_STATE_FREED;
spinlock_acquire(&monLock);
if (allMonitors == mon)
@ -127,8 +134,10 @@ MONITOR *ptr;
void
monitorStart(MONITOR *monitor, void* params)
{
monitor->handle = (*monitor->module->startMonitor)(monitor->handle,params);
spinlock_acquire(&monitor->lock);
monitor->handle = (*monitor->module->startMonitor)(monitor,params);
monitor->state = MONITOR_STATE_RUNNING;
spinlock_release(&monitor->lock);
}
/**
@ -142,7 +151,7 @@ monitorStop(MONITOR *monitor)
if(monitor->state != MONITOR_STATE_STOPPED)
{
monitor->state = MONITOR_STATE_STOPPING;
monitor->module->stopMonitor(monitor->handle);
monitor->module->stopMonitor(monitor);
monitor->state = MONITOR_STATE_STOPPED;
}
}
@ -175,7 +184,32 @@ MONITOR *ptr;
void
monitorAddServer(MONITOR *mon, SERVER *server)
{
mon->module->registerServer(mon->handle, server);
MONITOR_SERVERS *ptr, *db;
if ((db = (MONITOR_SERVERS *)malloc(sizeof(MONITOR_SERVERS))) == NULL)
return;
db->server = server;
db->con = NULL;
db->next = NULL;
db->mon_err_count = 0;
db->log_version_err = true;
/** Server status is uninitialized */
db->mon_prev_status = -1;
/* pending status is updated by get_replication_tree */
db->pending_status = 0;
spinlock_acquire(&mon->lock);
if (mon->databases == NULL)
mon->databases = db;
else
{
ptr = mon->databases;
while (ptr->next != NULL)
ptr = ptr->next;
ptr->next = db;
}
spinlock_release(&mon->lock);
}
/**
@ -189,7 +223,8 @@ monitorAddServer(MONITOR *mon, SERVER *server)
void
monitorAddUser(MONITOR *mon, char *user, char *passwd)
{
mon->module->defaultUser(mon->handle, user, passwd);
mon->user = strdup(user);
mon->password = strdup(passwd);
}
/**
@ -209,7 +244,7 @@ MONITOR *ptr;
dcb_printf(dcb, "Monitor: %p\n", ptr);
dcb_printf(dcb, "\tName: %s\n", ptr->name);
if (ptr->module->diagnostics)
ptr->module->diagnostics(dcb, ptr->handle);
ptr->module->diagnostics(dcb, ptr);
ptr = ptr->next;
}
spinlock_release(&monLock);
@ -227,7 +262,7 @@ monitorShow(DCB *dcb, MONITOR *monitor)
dcb_printf(dcb, "Monitor: %p\n", monitor);
dcb_printf(dcb, "\tName: %s\n", monitor->name);
if (monitor->module->diagnostics)
monitor->module->diagnostics(dcb, monitor->handle);
monitor->module->diagnostics(dcb, monitor);
}
/**
@ -288,10 +323,7 @@ MONITOR *ptr;
void
monitorSetInterval (MONITOR *mon, unsigned long interval)
{
if (mon->module->setInterval != NULL) {
mon->interval = interval;
mon->module->setInterval(mon->handle, interval);
}
mon->interval = interval;
}
/**
@ -303,9 +335,55 @@ monitorSetInterval (MONITOR *mon, unsigned long interval)
*/
void
monitorSetNetworkTimeout(MONITOR *mon, int type, int value) {
if (mon->module->setNetworkTimeout != NULL) {
mon->module->setNetworkTimeout(mon->handle, type, value);
int max_timeout = (int)(mon->interval/1000);
int new_timeout = max_timeout -1;
if (new_timeout <= 0)
new_timeout = DEFAULT_CONNECT_TIMEOUT;
switch(type) {
case MONITOR_CONNECT_TIMEOUT:
if (value < max_timeout) {
memcpy(&mon->connect_timeout, &value, sizeof(int));
} else {
memcpy(&mon->connect_timeout, &new_timeout, sizeof(int));
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"warning : Monitor Connect Timeout %i is greater than monitor interval ~%i seconds"
", lowering to %i seconds", value, max_timeout, new_timeout)));
}
break;
case MONITOR_READ_TIMEOUT:
if (value < max_timeout) {
memcpy(&mon->read_timeout, &value, sizeof(int));
} else {
memcpy(&mon->read_timeout, &new_timeout, sizeof(int));
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"warning : Monitor Read Timeout %i is greater than monitor interval ~%i seconds"
", lowering to %i seconds", value, max_timeout, new_timeout)));
}
break;
case MONITOR_WRITE_TIMEOUT:
if (value < max_timeout) {
memcpy(&mon->write_timeout, &value, sizeof(int));
} else {
memcpy(&mon->write_timeout, &new_timeout, sizeof(int));
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"warning : Monitor Write Timeout %i is greater than monitor interval ~%i seconds"
", lowering to %i seconds", value, max_timeout, new_timeout)));
}
break;
default:
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Monitor setNetworkTimeout received an unsupported action type %i", type)));
break;
}
}
/**

View File

@ -330,7 +330,8 @@ poll_remove_dcb(DCB *dcb)
CHK_DCB(dcb);
/*< It is possible that dcb has already been removed from the set */
if (dcb->state != DCB_STATE_POLLING)
if (dcb->state != DCB_STATE_POLLING &&
dcb->state != DCB_STATE_LISTENING)
{
if (dcb->state == DCB_STATE_NOPOLLING ||
dcb->state == DCB_STATE_ZOMBIE)

View File

@ -22,6 +22,7 @@
#include <log_manager.h>
#include <ctype.h>
#include <mysql_client_server_protocol.h>
#include <gwdirs.h>
/** Defined in log_manager.cc */
extern int lm_enabled_logfiles_bitmask;
@ -52,31 +53,26 @@ int i;
}
/**
* secrets_readKeys
*
* This routine reads data from a binary file and extracts the AES encryption key
* and the AES Init Vector
*
* This routine reads data from a binary file named ".secrets" and extracts the AES encryption key
* and the AES Init Vector.
* If the path parameter is not null the custom path is interpreted as a folder
* containing the .secrets file. Otherwise the default location is used.
* @return The keys structure or NULL on error
*/
static MAXKEYS *
secrets_readKeys()
secrets_readKeys(char* path)
{
char secret_file[255];
char secret_file[PATH_MAX+1];
char *home;
MAXKEYS *keys;
struct stat secret_stats;
int fd;
int len;
static int reported = 0;
home = getenv("MAXSCALE_HOME");
if (home == NULL) {
home = "/usr/local/mariadb-maxscale";
}
snprintf(secret_file, 255, "%s/etc/.secrets", home);
if(path != NULL)
snprintf(secret_file, PATH_MAX, "%s/.secrets", path);
else
snprintf(secret_file, PATH_MAX, "%s/.secrets", get_datadir());
/* Try to access secrets file */
if (access(secret_file, R_OK) == -1)
{
@ -225,11 +221,20 @@ static int reported = 0;
* @param secret_file The file with secret keys
* @return 0 on success and 1 on failure
*/
int secrets_writeKeys(char *secret_file)
int secrets_writeKeys(char *path)
{
int fd,randfd;
unsigned int randval;
MAXKEYS key;
char secret_file[PATH_MAX + 10];
if(strlen(path) > PATH_MAX)
{
skygw_log_write(LOGFILE_ERROR,"Error: Pathname too long.");
return 1;
}
sprintf(secret_file,"%s/.secrets",path);
/* Open for writing | Create | Truncate the file for writing */
if ((fd = open(secret_file, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR)) < 0)
@ -332,7 +337,7 @@ char *ptr;
unsigned char encrypted[80];
int enlen;
keys = secrets_readKeys();
keys = secrets_readKeys(NULL);
if (!keys)
return strdup(crypt);
/*
@ -369,12 +374,12 @@ int enlen;
* Encrypt a password that can be stored in the MaxScale configuration file.
*
* Note the return is always a malloc'd string that the caller must free
*
* @param path Path the the .secrets file
* @param password The password to encrypt
* @return The encrypted password
*/
char *
encryptPassword(char *password)
encryptPassword(char* path, char *password)
{
MAXKEYS *keys;
AES_KEY aeskey;
@ -383,7 +388,7 @@ char *hex_output;
unsigned char padded_passwd[80];
unsigned char encrypted[80];
if ((keys = secrets_readKeys()) == NULL)
if ((keys = secrets_readKeys(path)) == NULL)
return NULL;
memset(padded_passwd, 0, 80);

View File

@ -32,6 +32,7 @@
* 26/06/14 Mark Riddoch Addition of server parameters
* 30/08/14 Massimiliano Pinto Addition of new service status description
* 30/10/14 Massimiliano Pinto Addition of SERVER_MASTER_STICKINESS description
* 01/06/15 Massimiliano Pinto Addition of server_update_address/port
*
* @endverbatim
*/
@ -731,3 +732,41 @@ int *data;
return set;
}
/*
* Update the address value of a specific server
*
* @param server The server to update
* @param address The new address
*
*/
void
server_update_address(SERVER *server, char *address)
{
spinlock_acquire(&server_spin);
if (server && address) {
if (server->name) {
free(server->name);
}
server->name = strdup(address);
}
spinlock_release(&server_spin);
}
/*
* Update the port value of a specific server
*
* @param server The server to update
* @param port The new port value
*
*/
void
server_update_port(SERVER *server, unsigned short port)
{
spinlock_acquire(&server_spin);
if (server && port > 0) {
server->port = port;
}
spinlock_release(&server_spin);
}

View File

@ -61,12 +61,17 @@
#include <sys/types.h>
#include <housekeeper.h>
#include <resultset.h>
#include <gw.h>
#include <gwdirs.h>
/** Defined in log_manager.cc */
extern int lm_enabled_logfiles_bitmask;
extern size_t log_ses_count[];
extern __thread log_info_t tls_log_info;
static RSA *rsa_512 = NULL;
static RSA *rsa_1024 = NULL;
/** To be used with configuration type checks */
typedef struct typelib_st {
int tl_nelems;
@ -112,7 +117,7 @@ SERVICE *service;
return NULL;
if ((service->router = load_module(router, MODULE_ROUTER)) == NULL)
{
char* home = get_maxscale_home();
char* home = get_libdir();
char* ldpath = getenv("LD_LIBRARY_PATH");
LOGIF(LE, (skygw_log_write_flush(
@ -120,12 +125,13 @@ SERVICE *service;
"Error : Unable to load %s module \"%s\".\n\t\t\t"
" Ensure that lib%s.so exists in one of the "
"following directories :\n\t\t\t "
"- %s/modules\n\t\t\t - %s",
"- %s\n%s%s",
MODULE_ROUTER,
router,
router,
home,
ldpath)));
ldpath?"\t\t\t - ":"",
ldpath?ldpath:"")));
free(service);
return NULL;
}
@ -133,7 +139,14 @@ SERVICE *service;
service->routerModule = strdup(router);
service->users_from_all = false;
service->resources = NULL;
service->ssl_mode = SSL_DISABLED;
service->ssl_init_done = false;
service->ssl_ca_cert = NULL;
service->ssl_cert = NULL;
service->ssl_key = NULL;
service->ssl_cert_verify_depth = DEFAULT_SSL_CERT_VERIFY_DEPTH;
/** Support the highest possible SSL/TLS methods available as the default */
service->ssl_method_type = SERVICE_SSL_TLS_MAX;
if (service->name == NULL || service->routerModule == NULL)
{
if (service->name)
@ -229,11 +242,7 @@ GWPROTOCOL *funcs;
{
/* Try loading authentication data from file cache */
char *ptr, path[4097];
strcpy(path, "/usr/local/mariadb-maxscale");
if ((ptr = getenv("MAXSCALE_HOME")) != NULL)
{
strncpy(path, ptr, 4096);
}
strcpy(path, get_cachedir());
strncat(path, "/", 4096);
strncat(path, service->name, 4096);
strncat(path, "/.cache/dbusers", 4096);
@ -257,15 +266,11 @@ GWPROTOCOL *funcs;
else
{
/* Save authentication data to file cache */
char *ptr, path[4097];
char *ptr, path[PATH_MAX + 1];
int mkdir_rval = 0;
strcpy(path, "/usr/local/mariadb-maxscale");
if ((ptr = getenv("MAXSCALE_HOME")) != NULL)
{
strncpy(path, ptr, 4096);
}
strncpy(path, get_cachedir(),PATH_MAX);
strncat(path, "/", 4096);
strncat(path, service->name, 4096);
strncat(path, service->name, PATH_MAX);
if (access(path, R_OK) == -1)
{
mkdir_rval = mkdir(path, 0777);
@ -273,14 +278,17 @@ GWPROTOCOL *funcs;
if(mkdir_rval)
{
skygw_log_write(LOGFILE_ERROR,"Error : Failed to create directory '%s': [%d] %s",
path,
errno,
strerror(errno));
if(errno != EEXIST)
{
skygw_log_write(LOGFILE_ERROR,"Error : Failed to create directory '%s': [%d] %s",
path,
errno,
strerror(errno));
}
mkdir_rval = 0;
}
strncat(path, "/.cache", 4096);
strncat(path, "/.cache", PATH_MAX);
if (access(path, R_OK) == -1)
{
mkdir_rval = mkdir(path, 0777);
@ -288,13 +296,16 @@ GWPROTOCOL *funcs;
if(mkdir_rval)
{
skygw_log_write(LOGFILE_ERROR,"Error : Failed to create directory '%s': [%d] %s",
path,
errno,
strerror(errno));
if(errno != EEXIST)
{
skygw_log_write(LOGFILE_ERROR,"Error : Failed to create directory '%s': [%d] %s",
path,
errno,
strerror(errno));
}
mkdir_rval = 0;
}
strncat(path, "/dbusers", 4096);
strncat(path, "/dbusers", PATH_MAX);
dbusers_save(service->users, path);
}
if (loaded == 0)
@ -417,6 +428,17 @@ serviceStart(SERVICE *service)
SERV_PROTOCOL *port;
int listeners = 0;
if(service->ssl_mode != SSL_DISABLED)
{
if(serviceInitSSL(service) != 0)
{
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,
"%s: SSL initialization failed. Service not started.",
service->name)));
service->state = SERVICE_STATE_FAILED;
return 0;
}
}
if ((service->router_instance = service->router->createInstance(service,
service->routerOptions)) == NULL)
{
@ -518,11 +540,16 @@ int listeners = 0;
port = service->ports;
while (port)
{
poll_remove_dcb(port->listener);
port->listener->session->state = SESSION_STATE_LISTENER_STOPPED;
listeners++;
port = port->next;
if(port->listener &&
port->listener->session->state == SESSION_STATE_LISTENER)
{
if(poll_remove_dcb(port->listener) == 0)
{
port->listener->session->state = SESSION_STATE_LISTENER_STOPPED;
listeners++;
}
}
port = port->next;
}
service->state = SERVICE_STATE_STOPPED;
@ -546,13 +573,18 @@ int listeners = 0;
port = service->ports;
while (port)
{
if (poll_add_dcb(port->listener) == 0) {
port->listener->session->state = SESSION_STATE_LISTENER;
listeners++;
}
port = port->next;
if(port->listener &&
port->listener->session->state == SESSION_STATE_LISTENER_STOPPED)
{
if(poll_add_dcb(port->listener) == 0)
{
port->listener->session->state = SESSION_STATE_LISTENER;
listeners++;
}
}
port = port->next;
}
service->state = SERVICE_STATE_STARTED;
return listeners;
}
@ -860,6 +892,99 @@ serviceOptimizeWildcard(SERVICE *service, int action)
return 1;
}
/**
* Set the locations of the server's SSL certificate, server's private key and the CA
* certificate which both the client and the server should trust.
* @param service Service to configure
* @param cert SSL certificate
* @param key SSL private key
* @param ca_cert SSL CA certificate
*/
void
serviceSetCertificates(SERVICE *service, char* cert,char* key, char* ca_cert)
{
if(service->ssl_cert)
free(service->ssl_cert);
service->ssl_cert = strdup(cert);
if(service->ssl_key)
free(service->ssl_key);
service->ssl_key = strdup(key);
if(service->ssl_ca_cert)
free(service->ssl_ca_cert);
service->ssl_ca_cert = strdup(ca_cert);
}
/**
* Set the maximum SSL/TLS version the service will support
* @param service Service to configure
* @param version SSL/TLS version string
* @return 0 on success, -1 on invalid version string
*/
int
serviceSetSSLVersion(SERVICE *service, char* version)
{
if(strcasecmp(version,"SSLV3") == 0)
service->ssl_method_type = SERVICE_SSLV3;
else if(strcasecmp(version,"TLSV10") == 0)
service->ssl_method_type = SERVICE_TLS10;
#ifdef OPENSSL_1_0
else if(strcasecmp(version,"TLSV11") == 0)
service->ssl_method_type = SERVICE_TLS11;
else if(strcasecmp(version,"TLSV12") == 0)
service->ssl_method_type = SERVICE_TLS12;
#endif
else if(strcasecmp(version,"MAX") == 0)
service->ssl_method_type = SERVICE_SSL_TLS_MAX;
else return -1;
return 0;
}
/**
* Set the service's SSL certificate verification depth. Depth of 0 means the peer
* certificate, 1 is the CA and 2 is a higher CA and so on.
* @param service Service to configure
* @param depth Certificate verification depth
* @return 0 on success, -1 on incorrect depth value
*/
int serviceSetSSLVerifyDepth(SERVICE* service, int depth)
{
if(depth < 0)
return -1;
service->ssl_cert_verify_depth = depth;
return 0;
}
/**
* Enable or disable the service SSL capability of a service.
* The SSL mode string passed as a parameter should be one of required, enabled
* or disabled. Required requires all connections to use SSL encryption, enabled
* allows both SSL and non-SSL connections and disabled does not use SSL encryption.
* If the service SSL mode is set to enabled, then the client will decide whether
* SSL encryption is used.
* @param service Service to configure
* @param action Mode string. One of required, enabled or disabled.
* @return 0 on success, -1 on error
*/
int
serviceSetSSL(SERVICE *service, char* action)
{
int rval = 0;
if(strcasecmp(action,"required") == 0)
service->ssl_mode = SSL_REQUIRED;
else if(strcasecmp(action,"enabled") == 0)
service->ssl_mode = SSL_ENABLED;
else if(strcasecmp(action,"disabled") == 0)
service->ssl_mode = SSL_DISABLED;
else
rval = -1;
return rval;
}
/**
* Whether to strip escape characters from the name of the database the client
* is connecting to.
@ -1023,6 +1148,8 @@ int i;
printf("\tUsers data: %p\n", (void *)service->users);
printf("\tTotal connections: %d\n", service->stats.n_sessions);
printf("\tCurrently connected: %d\n", service->stats.n_current);
printf("\tSSL: %s\n", service->ssl_mode == SSL_DISABLED ? "Disabled":
(service->ssl_mode == SSL_ENABLED ? "Enabled":"Required"));
}
/**
@ -1132,6 +1259,8 @@ int i;
service->stats.n_sessions);
dcb_printf(dcb, "\tCurrently connected: %d\n",
service->stats.n_current);
dcb_printf(dcb,"\tSSL: %s\n", service->ssl_mode == SSL_DISABLED ? "Disabled":
(service->ssl_mode == SSL_ENABLED ? "Enabled":"Required"));
}
/**
@ -1260,7 +1389,14 @@ void *router_obj;
}
}
/**
* Refresh the database users for the service
* This function replaces the MySQL users used by the service with the latest
* version found on the backend servers. There is a limit on how often the users
* can be reloaded and if this limit is exceeded, the reload will fail.
* @param service Service to reload
* @return 0 on success and 1 on error
*/
int service_refresh_users(SERVICE *service) {
int ret = 1;
/* check for another running getUsers request */
@ -1780,3 +1916,140 @@ int *data;
return set;
}
/**
* The RSA ket generation callback function for OpenSSL.
* @param s SSL structure
* @param is_export Not used
* @param keylength Length of the key
* @return Pointer to RSA structure
*/
RSA *tmp_rsa_callback(SSL *s, int is_export, int keylength)
{
RSA *rsa_tmp=NULL;
switch (keylength) {
case 512:
if (rsa_512)
rsa_tmp = rsa_512;
else { /* generate on the fly, should not happen in this example */
rsa_tmp = RSA_generate_key(keylength,RSA_F4,NULL,NULL);
rsa_512 = rsa_tmp; /* Remember for later reuse */
}
break;
case 1024:
if (rsa_1024)
rsa_tmp=rsa_1024;
break;
default:
/* Generating a key on the fly is very costly, so use what is there */
if (rsa_1024)
rsa_tmp=rsa_1024;
else
rsa_tmp=rsa_512; /* Use at least a shorter key */
}
return(rsa_tmp);
}
/**
* Initialize the servce's SSL context. This sets up the generated RSA
* encryption keys, chooses the server encryption level and configures the server
* certificate, private key and certificate authority file.
* @param service
* @return
*/
int serviceInitSSL(SERVICE* service)
{
DH* dh;
RSA* rsa;
if(!service->ssl_init_done)
{
switch(service->ssl_method_type)
{
case SERVICE_SSLV3:
service->method = (SSL_METHOD*)SSLv3_server_method();
break;
case SERVICE_TLS10:
service->method = (SSL_METHOD*)TLSv1_server_method();
break;
#ifdef OPENSSL_1_0
case SERVICE_TLS11:
service->method = (SSL_METHOD*)TLSv1_1_server_method();
break;
case SERVICE_TLS12:
service->method = (SSL_METHOD*)TLSv1_2_server_method();
break;
#endif
/** Rest of these use the maximum available SSL/TLS methods */
case SERVICE_SSL_MAX:
service->method = (SSL_METHOD*)SSLv23_server_method();
break;
case SERVICE_TLS_MAX:
service->method = (SSL_METHOD*)SSLv23_server_method();
break;
case SERVICE_SSL_TLS_MAX:
service->method = (SSL_METHOD*)SSLv23_server_method();
break;
default:
service->method = (SSL_METHOD*)SSLv23_server_method();
break;
}
service->ctx = SSL_CTX_new(service->method);
/** Enable all OpenSSL bug fixes */
SSL_CTX_set_options(service->ctx,SSL_OP_ALL);
/** Generate the 512-bit and 1024-bit RSA keys */
if(rsa_512 == NULL)
{
rsa_512 = RSA_generate_key(512,RSA_F4,NULL,NULL);
if (rsa_512 == NULL)
skygw_log_write(LE,"Error: 512-bit RSA key generation failed.");
}
if(rsa_1024 == NULL)
{
rsa_1024 = RSA_generate_key(1024,RSA_F4,NULL,NULL);
if (rsa_1024 == NULL)
skygw_log_write(LE,"Error: 1024-bit RSA key generation failed.");
}
if(rsa_512 != NULL && rsa_1024 != NULL)
SSL_CTX_set_tmp_rsa_callback(service->ctx,tmp_rsa_callback);
/** Load the server sertificate */
if (SSL_CTX_use_certificate_file(service->ctx, service->ssl_cert, SSL_FILETYPE_PEM) <= 0) {
skygw_log_write(LE,"Error: Failed to set server SSL certificate.");
return -1;
}
/* Load the private-key corresponding to the server certificate */
if (SSL_CTX_use_PrivateKey_file(service->ctx, service->ssl_key, SSL_FILETYPE_PEM) <= 0) {
skygw_log_write(LE,"Error: Failed to set server SSL key.");
return -1;
}
/* Check if the server certificate and private-key matches */
if (!SSL_CTX_check_private_key(service->ctx)) {
skygw_log_write(LE,"Error: Server SSL certificate and key do not match.");
return -1;
}
/* Load the RSA CA certificate into the SSL_CTX structure */
if (!SSL_CTX_load_verify_locations(service->ctx, service->ssl_ca_cert, NULL)) {
skygw_log_write(LE,"Error: Failed to set Certificate Authority file.");
return -1;
}
/* Set to require peer (client) certificate verification */
SSL_CTX_set_verify(service->ctx,SSL_VERIFY_PEER,NULL);
/* Set the verification depth */
SSL_CTX_set_verify_depth(service->ctx,service->ssl_cert_verify_depth);
service->ssl_init_done = true;
}
return 0;
}

View File

@ -44,19 +44,4 @@ add_test(Internal-TestUsers test_users)
add_test(Internal-TestAdminUsers test_adminusers)
add_test(Internal-TestMemlog testmemlog)
add_test(TestFeedback testfeedback)
set_tests_properties(Internal-TestMySQLUsers
Internal-TestHash
Internal-TestHint
Internal-TestSpinlock
Internal-TestFilter
Internal-TestBuffer
Internal-TestDCB
Internal-TestModutil
Internal-TestPoll
Internal-TestService
Internal-TestServer
Internal-TestUsers
Internal-TestAdminUsers
Internal-TestMemlog
TestFeedback PROPERTIES ENVIRONMENT MAXSCALE_HOME=${CMAKE_BINARY_DIR}/)
set_tests_properties(TestFeedback PROPERTIES TIMEOUT 30)

View File

@ -30,7 +30,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gwdirs.h>
#include <adminusers.h>
@ -40,7 +40,7 @@
* Test that the username password admin/mariadb is accepted if no users
* have been created and that no other users are accepted
*
* WARNING: $MAXSCALE_HOME/etc/passwd must be removed before this test is run
* WARNING: The passwd file must be removed before this test is run
*/
static int
test1()
@ -269,9 +269,8 @@ int result = 0;
char *home, buf[1024];
/* Unlink any existing password file before running this test */
if ((home = getenv("MAXSCALE_HOME")) == NULL || strlen(home) >= 1024)
home = "/usr/local/mariadb-maxscale";
sprintf(buf, "%s/etc/passwd", home);
sprintf(buf, "%s/passwd", default_cachedir);
if(!is_valid_posix_path(buf))
exit(1);
if (strcmp(buf, "/etc/passwd") != 0)

View File

@ -73,17 +73,8 @@ int main(int argc, char** argv)
char* cnf;
hkinit();
home = getenv("MAXSCALE_HOME");
if(home == NULL)
{
FAILTEST("MAXSCALE_HOME was not defined.");
}
printf("Home: %s\n",home);
cnf = malloc(strlen(home) + strlen("/etc/MaxScale.cnf") + 1);
strcpy(cnf,home);
strcat(cnf,"/etc/MaxScale.cnf");
cnf = strdup("/etc/MaxScale.cnf");
printf("Config: %s\n",cnf);
@ -116,4 +107,4 @@ int main(int argc, char** argv)
}
mysql_library_end();
return 0;
}
}

View File

@ -23,6 +23,9 @@
#include <gwbitmask.h>
#include <skygw_utils.h>
#include <netinet/in.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define ERRHANDLE
@ -265,6 +268,7 @@ typedef struct dcb {
unsigned int high_water; /**< High water mark */
unsigned int low_water; /**< Low water mark */
struct server *server; /**< The associated backend server */
SSL* ssl; /*< SSL struct for connection */
#if defined(SS_DEBUG)
int dcb_port; /**< port of target server */
skygw_chk_t dcb_chk_tail;
@ -312,6 +316,7 @@ void dcb_free(DCB *);
DCB *dcb_connect(struct server *, struct session *, const char *);
DCB *dcb_clone(DCB *);
int dcb_read(DCB *, GWBUF **);
int dcb_read_n(DCB*,GWBUF **,int);
int dcb_drain_writeq(DCB *);
void dcb_close(DCB *);
DCB *dcb_process_zombies(int); /* Process Zombies except the one behind the pointer */
@ -337,7 +342,13 @@ bool dcb_set_state(DCB* dcb, dcb_state_t new_state, dcb_state_t* old_state);
void dcb_call_foreach (struct server* server, DCB_REASON reason);
size_t dcb_get_session_id(DCB* dcb);
bool dcb_get_ses_log_info(DCB* dcb, size_t* sesid, int* enabled_logs);
int dcb_create_SSL(DCB* dcb);
int dcb_accept_SSL(DCB* dcb);
int dcb_connect_SSL(DCB* dcb);
int gw_write_SSL(SSL* ssl, const void *buf, size_t nbytes);
int dcb_write_SSL(DCB *dcb,GWBUF *queue);
int dcb_read_SSL(DCB *dcb,GWBUF **head);
int dcb_drain_writeq_SSL(DCB *dcb);
/**

View File

@ -0,0 +1,20 @@
#ifndef _EXTERN_CMD_HG
#define _EXTERN_CMD_HG
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <skygw_utils.h>
#include <log_manager.h>
#define MAXSCALE_EXTCMD_ARG_MAX 256
typedef struct extern_cmd_t{
char* parameters[MAXSCALE_EXTCMD_ARG_MAX]; /*< Command arguments */
int n_exec; /*< Number of times executed */
pid_t child; /*< PID of the child process */
}EXTERNCMD;
EXTERNCMD* externcmd_allocate(char* argstr);
void externcmd_free(EXTERNCMD* cmd);
int externcmd_execute(EXTERNCMD* cmd);
#endif

View File

@ -1,3 +1,25 @@
#ifndef _GW_HG
#define _GW_HG
/*
* This file is distributed as part of the MariaDB Corporation MaxScale. It is free
* software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation,
* version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright MariaDB Corporation Ab 2013-2014
*/
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
@ -16,8 +38,8 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <gwdirs.h>
#define EXIT_FAILURE 1
@ -65,3 +87,5 @@ int gw_write(DCB *dcb, const void *buf, size_t nbytes);
int gw_getsockerrno(int fd);
int parse_bindconfig(char *, unsigned short, struct sockaddr_in *);
int setipaddress(struct in_addr *, char *);
char* get_libdir();
#endif

View File

@ -0,0 +1,48 @@
#ifndef _GW_DIRS_HG
#define _GW_DIRS_HG
/*
* This file is distributed as part of the MariaDB Corporation MaxScale. It is free
* software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation,
* version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright MariaDB Corporation Ab 2015
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdlib.h>
#include <string.h>
/** Default file locations, configured by CMake */
static const char* default_cnf_fname = "maxscale.cnf";
static const char* default_configdir = "/etc/";
static const char* default_piddir = "@MAXSCALE_VARDIR@/run/maxscale/"; /*< This should be changed to just /run eventually,
* the /var/run folder is an old standard and the newe FSH 3.0
* uses /run for PID files.*/
static const char* default_logdir = "@MAXSCALE_VARDIR@/log/maxscale/";
static const char* default_datadir = "@MAXSCALE_VARDIR@/lib/maxscale/";
static const char* default_libdir = "@CMAKE_INSTALL_PREFIX@/@MAXSCALE_LIBDIR@";
static const char* default_cachedir = "@MAXSCALE_VARDIR@/cache/maxscale/";
static const char* default_langdir = "@MAXSCALE_VARDIR@/lib/maxscale/";
static char* configdir = NULL;
static char* logdir = NULL;
static char* libdir = NULL;
static char* cachedir = NULL;
static char* maxscaledatadir = NULL;
static char* langdir = NULL;
static char* piddir = NULL;
char* get_libdir();
char* get_datadir();
char* get_cachedir();
#endif

View File

@ -68,7 +68,6 @@ extern void unload_all_modules();
extern void printModules();
extern void dprintAllModules(DCB *);
extern RESULTSET *moduleGetList();
extern char *get_maxscale_home(void);
extern void module_feedback_send(void*);
extern void moduleShowFeedbackReport(DCB *dcb);

View File

@ -17,6 +17,7 @@
*
* Copyright MariaDB Corporation Ab 2013-2014
*/
#include <mysql.h>
#include <server.h>
#include <dcb.h>
#include <resultset.h>
@ -69,19 +70,14 @@
typedef struct {
void *(*startMonitor)(void *, void*);
void (*stopMonitor)(void *);
void (*registerServer)(void *, SERVER *);
void (*unregisterServer)(void *, SERVER *);
void (*defaultUser)(void *, char *, char *);
void (*diagnostics)(DCB *, void *);
void (*setInterval)(void *, size_t);
void (*setNetworkTimeout)(void *, int, int);
} MONITOR_OBJECT;
/**
* The monitor API version number. Any change to the monitor module API
* must change these versions usign the rules defined in modinfo.h
*/
#define MONITOR_VERSION {2, 0, 0}
#define MONITOR_VERSION {3, 0, 0}
/** Monitor's poll frequency */
#define MON_BASE_INTERVAL_MS 100
@ -112,12 +108,47 @@ typedef enum
#define DEFAULT_READ_TIMEOUT 1
#define DEFAULT_WRITE_TIMEOUT 2
#define MONITOR_RUNNING 1
#define MONITOR_STOPPING 2
#define MONITOR_STOPPED 3
#define MONITOR_INTERVAL 10000 // in milliseconds
#define MONITOR_DEFAULT_ID 1UL // unsigned long value
#define MONITOR_MAX_NUM_SLAVES 20 //number of MySQL slave servers associated to a MySQL master server
/**
* The linked list of servers that are being monitored by the monitor module.
*/
typedef struct monitor_servers {
SERVER *server; /**< The server being monitored */
MYSQL *con; /**< The MySQL connection */
bool log_version_err;
int mon_err_count;
unsigned int mon_prev_status;
unsigned int pending_status; /**< Pending Status flag bitmap */
struct monitor_servers
*next; /**< The next server in the list */
} MONITOR_SERVERS;
/**
* Representation of the running monitor.
*/
typedef struct monitor {
char *name; /**< The name of the monitor module */
char* user; /*< Monitor username */
char* password; /*< Monitor password */
SPINLOCK lock;
MONITOR_SERVERS* databases; /*< List of databases the monitor monitors */
monitor_state_t state; /**< The state of the monitor */
int connect_timeout; /**< Connect timeout in seconds for mysql_real_connect */
int read_timeout; /**< Timeout in seconds to read from the server.
* There are retries and the total effective timeout value is three times the option value.
*/
int write_timeout; /**< Timeout in seconds for each attempt to write to the server.
* There are retries and the total effective timeout value is two times the option value.
*/
MONITOR_OBJECT *module; /**< The "monitor object" */
void *handle; /**< Handle returned from startMonitor */
size_t interval; /**< The monitor interval */

View File

@ -53,5 +53,5 @@ typedef struct maxkeys {
extern int secrets_writeKeys(char *filename);
extern char *decryptPassword(char *);
extern char *encryptPassword(char *);
extern char *encryptPassword(char*,char *);
#endif

View File

@ -43,6 +43,7 @@
* 30/08/14 Massimiliano Pinto Addition of SERVER_STALE_STATUS
* 27/10/14 Massimiliano Pinto Addition of SERVER_MASTER_STICKINESS
* 19/02/15 Mark Riddoch Addition of serverGetList
* 01/06/15 Massimiliano Pinto Addition of server_update_address/port
*
* @endverbatim
*/
@ -189,5 +190,7 @@ extern void serverAddParameter(SERVER *, char *, char *);
extern char *serverGetParameter(SERVER *, char *);
extern void server_update(SERVER *, char *, char *, char *);
extern void server_set_unique_name(SERVER *, char *);
extern void server_update_address(SERVER *, char *);
extern void server_update_port(SERVER *, unsigned short);
extern RESULTSET *serverGetList();
#endif

View File

@ -26,7 +26,10 @@
#include <hashtable.h>
#include <resultset.h>
#include <maxconfig.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/dh.h>
/**
* @file service.h
*
@ -105,6 +108,26 @@ typedef struct server_ref_t{
SERVER* server;
}SERVER_REF;
typedef enum {
SSL_DISABLED,
SSL_ENABLED,
SSL_REQUIRED
} ssl_mode_t;
enum{
SERVICE_SSLV3,
SERVICE_TLS10,
#ifdef OPENSSL_1_0
SERVICE_TLS11,
SERVICE_TLS12,
#endif
SERVICE_SSL_MAX,
SERVICE_TLS_MAX,
SERVICE_SSL_TLS_MAX
};
#define DEFAULT_SSL_CERT_VERIFY_DEPTH 100 /*< The default certificate verification depth */
/**
* Defines a service within the gateway.
*
@ -149,8 +172,19 @@ typedef struct service {
FILTER_DEF **filters; /**< Ordered list of filters */
int n_filters; /**< Number of filters */
int conn_timeout; /*< Session timeout in seconds */
ssl_mode_t ssl_mode; /*< one of DISABLED, ENABLED or REQUIRED */
char *weightby;
struct service *next; /**< The next service in the linked list */
SSL_CTX *ctx;
SSL_METHOD *method; /*< SSLv3 or TLS1.0/1.1/1.2 methods
* see: https://www.openssl.org/docs/ssl/SSL_CTX_new.html */
int ssl_cert_verify_depth; /*< SSL certificate verification depth */
int ssl_method_type; /*< Which of the SSLv3 or TLS1.0/1.1/1.2 methods to use */
char* ssl_cert; /*< SSL certificate */
char* ssl_key; /*< SSL private key */
char* ssl_ca_cert; /*< SSL CA certificate */
bool ssl_init_done; /*< If SSL has already been initialized for this service */
} SERVICE;
typedef enum count_spec_t {COUNT_NONE=0, COUNT_ATLEAST, COUNT_EXACT, COUNT_ATMOST} count_spec_t;
@ -178,6 +212,11 @@ extern int serviceRestart(SERVICE *);
extern int serviceSetUser(SERVICE *, char *, char *);
extern int serviceGetUser(SERVICE *, char **, char **);
extern void serviceSetFilters(SERVICE *, char *);
extern int serviceSetSSL(SERVICE *service, char* action);
extern int serviceInitSSL(SERVICE* service);
extern int serviceSetSSLVersion(SERVICE *service, char* version);
extern int serviceSetSSLVerifyDepth(SERVICE* service, int depth);
extern void serviceSetCertificates(SERVICE *service, char* cert,char* key, char* ca_cert);
extern int serviceEnableRootUser(SERVICE *, int );
extern int serviceSetTimeout(SERVICE *, int );
extern void serviceWeightBy(SERVICE *, char *);

View File

@ -1,5 +1,5 @@
#
# Example MaxScale.cnf for the Binlog Server.
# Example maxscale.cnf for the Binlog Server.
#
#
@ -37,14 +37,13 @@ threads=6
# The MaxScale Binlog Server Service.
#
# The name of this service will be used as the directory name
# in $MAXSCALE_HOME where the binlogs will be saved.
# in the cache directory where the binlogs will be saved.
# If this name is changed, it must be changed in the listener
# configuration below.
[Binlog_Service]
# type must be service
# router must be binlogrouter
# (corresponding to the so file in $MAXSCALE_HOME/modules).
type=service
router=binlogrouter

Some files were not shown because too many files have changed in this diff Show More