Chapter 2 Installation

Table of Contents

2.1 Installing MySQL Router on Linux
2.2 Installing MySQL Router on OS X
2.3 Installing MySQL Router on Windows
2.4 Installing MySQL Router from Source Code
2.4.1 Prerequisites
2.4.2 Compiling the Source Code
2.4.3 Installing from Source Code
2.4.4 Testing the Installation
2.5 Postinstallation Testing

This chapter describes how to obtain and install MySQL Router. Downloads are available from the download site.

Requirements

2.1 Installing MySQL Router on Linux

There are binary distributions of MySQL Router available for several variants of Linux, including Fedora, Oracle Linux, and Ubuntu.

Installation options include:

The procedure for installing on Linux depends on your Linux distribution.

Installing DEB packages

On Ubuntu, and other systems that use the Debian package scheme, you can either download and install .deb packages or use the APT package manager.

Using the APT Package Manager

  • First, install the MySQL APT repository as described in the MySQL APT Repository documentation. For example:

    shell> sudo dpkg -i mysql-apt-config_0.6.0-1_all.deb
    

    Enable the "MySQL Tools & Connectors" on the configuration screen.

  • Update your APT repository:

    shell> sudo apt-get update
    
  • Next, install MySQL Router. For example:

    shell> sudo apt-get install mysql-router
    

Manually Installing a Package

You can also download the .deb package and install it from the command line similarly to

shell> sudo dpkg -i package.deb

package.deb is the MySQL Router package name; for example, mysql-router-version1ubu1404-amd64.deb, where version is the MySQL Router version number.

Installing RPM packages

On Red Hat-based systems, and other systems that use the RPM package format, you can either download and install RPM packages or use the Yum package manager.

Using the Yum Package Manager

  • First, install the MySQL Yum repository as described in the MySQL Yum Repository documentation. For example:

    shell> sudo rpm -Uvh mysql-community-release-el7-7.noarch.rpm
    
  • Next, install MySQL Router. For example:

    shell> sudo yum install mysql-router
    

Manually Installing an RPM Package

shell> sudo rpm -i package.rpm

package.rpm is the MySQL Router package name; for example, mysql-router-version-1fc10.x86_64.rpm, where version is the MySQL Router version number.

Uninstalling

The procedure for uninstalling MySQL Router on Linux depends on the package you are using.

Uninstalling DEB packages

To uninstall a Debian package, use this command:

shell> sudo dpkg -r mysql-router

This command does not remove the configuration files. If you wish to also remove the configuration files, use this command:

shell> sudo dpkg --purge mysql-router

Uninstalling RPM packages

To uninstall an RPM package, use this command:

shell> sudo rpm -e mysql-router

This command does not remove the configuration files.

What Is Not Removed

By default, the uninstallation process does not remove your configuration files. On Debian systems, this might include files such as:

/etc/init.d/mysqlrouter
/etc/mysqlrouter/mysqlrouter.ini
/etc/apparmor.d/usr.sbin.mysqlrouter

2.2 Installing MySQL Router on OS X

See the Linux installation instructions.

For information about how to compile MySQL Router, see Section 2.4.2, “Compiling the Source Code”.

2.3 Installing MySQL Router on Windows

Windows binaries are not yet available.

2.4 Installing MySQL Router from Source Code

The MySQL Router is written using the C++11 standard. As such, you must compile the code before you can install it. Compilation is typical of most C++ applications as demonstrated below.

The CMake program provides a great deal of control over how you configure a MySQL Router source distribution. Typically, you do this using options on the CMake command line. For information about options supported by CMake, run either of these commands in the top-level MySQL Router source directory:

shell> cmake . -LH
shell> ccmake .

The default CMake installation prefixes are used. These are different for each platform, but for most (if not all) Unices this is "/usr/local". It is possible to alter the installation path with the CMake variable "CMAKE_INSTALL_PREFIX". For example:

shell> mkdir build && cd build
shell> cmake .. -DINSTALL_LAYOUT=STANDALONE -DCMAKE_INSTALL_PREFIX=/opt/mysql/router2.0

Notice we use the -DINSTALL_LAYOUT=STANDALONE option to use the same installation layout as used for .tar.gz and .zip packages. This is the recommended setting for building the source.

Note

All of the CMake options are not documented here, but they are similar to the MySQL Server CMake options. For additional (related) information, see MySQL Source-Configuration Options.

Download and unpack the source files. Then:

Linux and OS X

shell> tar xzf mysql-router-2.0.3-src.tar.gz
shell> cd mysql-router-2.0.3-src

Once this is complete, you need to configure and compile MySQL Router using cmake. Our examples use the default installation location of /usr/local.

Note

Installing MySQL Router generates a file named install_manifest.txt that lists all files (with paths) that were installed on the system. This file is useful to uninstall MySQL Router.

However, there are a couple of things that you need to do in order to prepare your system for compiling the source code.

2.4.1 Prerequisites

The following components and libraries are required to compile MySQL Router.

  • CMake 2.8.9 or higher

  • MySQL Server 5.5 or higher client libraries and header files

  • Code development tools including gcc, make, and assorted utilities for C++ 11 including GCC 4.8 and later, glibc 2.17 and later, and clang 3.3 and later

  • Python (optional, for some unit tests)

Note

If your MySQL Server installation does not include the header files and compiled client libraries, then you may need to download the MySQL Server source code.

2.4.2 Compiling the Source Code

To compile the source code, you should create a folder to contain the compiled binaries and executables, run cmake to create the make file, then compile the code. The following demonstrates the steps needed on a Ubuntu machine. Other platforms are similar.

Note

For some platforms, such as Oracle Enterprise Linux 6, you may also need to install the devtoolset software collection.

If you get an error stating that the MySQL libraries cannot be found, then check the listed paths. If the client libraries or the include folder does not exist, you may need to reference a compiled copy of the MySQL Server source code by using the -DWITH_MYSQL=<path to server code> option. More specifically, the compiler needs to be able to find the MySQL client libraries and include files. A compiled server source code tree will have these files. So too will most installations of the MySQL server.

For example, on Debian and RPM-based platforms, you would need the packages which contain the libraries and the development (include) files. If you installed MySQL from a platform-specific repository, you would need to install the mysql-community-libs and mysql-community-devel packages.

Note

If you change anything and need to recompile from scratch, be sure to delete the CMakeCache.txt file before running the cmake command.

Begin by running the cmake command to create the makefile. The following commands are run from the root of the MySQL Router source code tree. You should see similar results with the appropriate paths for your system.

shell>  mkdir build
shell>  cd build
shell>  cmake ..  -DWITH_MYSQL=<path to binaries and libraries>
-- The C compiler identification is GNU 4.9.2
-- The CXX compiler identification is GNU 4.9.2
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Loading internal repository
-- Installation layout set to DEFAULT
-- Adding MySQL Harness from /home/cbell/source/git/mysql-router-2.0.2/mysql_harness
-- Harness will install plugins in lib/mysqlrouter
-- MySQL Harness CPU Descriptor is x86_64
-- MySQL Harness OS Descriptor is linux
-- MySQL Harness Compiler Descriptor is gnu-3
-- MySQL Harness Runtime Descriptor is *
-- Found Doxygen: /usr/bin/doxygen (found version "1.8.9.1") 
-- Performing Test COMPILER_SUPPORTS_CXX11
-- Performing Test COMPILER_SUPPORTS_CXX11 - Success
-- Performing Test COMPILER_SUPPORTS_CXX0X
-- Performing Test COMPILER_SUPPORTS_CXX0X - Success
-- Looking for include file pthread.h
-- Looking for include file pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Performing Test support_11
-- Performing Test support_11 - Success
-- Performing Test support_0x
-- Performing Test support_0x - Success
-- Found MySQL Libraries 5.6.27; using <path to server code>/lib/libmysqlclient.so
-- Loading module 'router'
-- Loading module 'fabric_cache'
-- Loading module 'routing'
-- Configuring done
-- Generating done
-- Build files have been written to: <path to router code>/build

Next, compile the code. For this we only need the make command as shown. Again, you should see similar results on your system.

shell>  make
Scanning dependencies of target harness-archive
[  2%] Building CXX object harness/harness/CMakeFiles/harness-archive.dir/src/loader.cc.o
[  5%] Building CXX object harness/harness/CMakeFiles/harness-archive.dir/src/utilities.cc.o
[  8%] Building CXX object harness/harness/CMakeFiles/harness-archive.dir/src/config_parser.cc.o
[ 11%] Building CXX object harness/harness/CMakeFiles/harness-archive.dir/src/designator.cc.o
[ 14%] Building CXX object harness/harness/CMakeFiles/harness-archive.dir/src/filesystem-posix.cc.o
Linking CXX static library libmysqlharness.a
[ 14%] Built target harness-archive
Scanning dependencies of target harness-library
[ 17%] Building CXX object harness/harness/CMakeFiles/harness-library.dir/src/loader.cc.o
[ 20%] Building CXX object harness/harness/CMakeFiles/harness-library.dir/src/utilities.cc.o
[ 22%] Building CXX object harness/harness/CMakeFiles/harness-library.dir/src/config_parser.cc.o
[ 25%] Building CXX object harness/harness/CMakeFiles/harness-library.dir/src/designator.cc.o
[ 28%] Building CXX object harness/harness/CMakeFiles/harness-library.dir/src/filesystem-posix.cc.o
Linking CXX shared library libmysqlharness.so
[ 28%] Built target harness-library
Scanning dependencies of target logger
[ 31%] Building CXX object harness/plugins/logger/CMakeFiles/logger.dir/logger.cc.o
Linking CXX shared library ../../../stage/lib/mysqlrouter/logger.so
[ 31%] Built target logger
Scanning dependencies of target keepalive
[ 34%] Building CXX object harness/plugins/keepalive/CMakeFiles/keepalive.dir/src/keepalive.cc.o
Linking CXX shared library ../../../stage/lib/mysqlrouter/keepalive.so
[ 34%] Built target keepalive
Scanning dependencies of target router_lib
[ 37%] Building CXX object src/router/src/CMakeFiles/router_lib.dir/router_app.cc.o
[ 40%] Building CXX object src/router/src/CMakeFiles/router_lib.dir/arg_handler.cc.o
[ 42%] Building CXX object src/router/src/CMakeFiles/router_lib.dir/utils.cc.o
[ 45%] Building CXX object src/router/src/CMakeFiles/router_lib.dir/datatypes.cc.o
[ 48%] Building CXX object src/router/src/CMakeFiles/router_lib.dir/plugin_config.cc.o
Linking CXX shared library ../../../stage/lib/libmysqlrouter.so
[ 48%] Built target router_lib
Scanning dependencies of target mysqlrouter
[ 51%] Building CXX object src/router/src/CMakeFiles/mysqlrouter.dir/main.cc.o
Linking CXX executable ../../../stage/bin/mysqlrouter
[ 51%] Built target mysqlrouter
Scanning dependencies of target fabric_cache
[ 54%] Building CXX object src/fabric_cache/CMakeFiles/fabric_cache.dir/src/fabric_cache_plugin.cc.o
[ 57%] Building CXX object src/fabric_cache/CMakeFiles/fabric_cache.dir/src/plugin_config.cc.o
[ 60%] Building CXX object src/fabric_cache/CMakeFiles/fabric_cache.dir/src/fabric_factory.cc.o
[ 62%] Building CXX object src/fabric_cache/CMakeFiles/fabric_cache.dir/src/fabric.cc.o
[ 65%] Building CXX object src/fabric_cache/CMakeFiles/fabric_cache.dir/src/fabric_cache.cc.o
[ 68%] Building CXX object src/fabric_cache/CMakeFiles/fabric_cache.dir/src/utils.cc.o
[ 71%] Building CXX object src/fabric_cache/CMakeFiles/fabric_cache.dir/src/cache_api.cc.o
Linking CXX shared library ../../stage/lib/mysqlrouter/fabric_cache.so
[ 71%] Built target fabric_cache
Scanning dependencies of target cache_test
[ 74%] Building CXX object src/fabric_cache/CMakeFiles/cache_test.dir/fabric_cache_dev.cc.o
Linking CXX executable ../../stage/bin/cache_test
[ 74%] Built target cache_test
Scanning dependencies of target routing
[ 77%] Building CXX object src/routing/CMakeFiles/routing.dir/src/routing_plugin.cc.o
[ 80%] Building CXX object src/routing/CMakeFiles/routing.dir/src/plugin_config.cc.o
[ 82%] Building CXX object src/routing/CMakeFiles/routing.dir/src/mysql_routing.cc.o
[ 85%] Building CXX object src/routing/CMakeFiles/routing.dir/src/utils.cc.o
[ 88%] Building CXX object src/routing/CMakeFiles/routing.dir/src/destination.cc.o
[ 91%] Building CXX object src/routing/CMakeFiles/routing.dir/src/dest_fabric_cache.cc.o
[ 94%] Building CXX object src/routing/CMakeFiles/routing.dir/src/dest_first_available.cc.o
[ 97%] Building CXX object src/routing/CMakeFiles/routing.dir/src/uri.cc.o
[100%] Building CXX object src/routing/CMakeFiles/routing.dir/src/routing.cc.o
Linking CXX shared library ../../stage/lib/mysqlrouter/routing.so
[100%] Built target routing

2.4.3 Installing from Source Code

Once the source code is compiled, you can install the MySQL Router on your system with the following command. Note that you may need elevated privileges (e.g. sudo) to install.

shell>  sudo make install
[ 14%] Built target harness-archive
[ 28%] Built target harness-library
[ 31%] Built target logger
[ 34%] Built target keepalive
[ 48%] Built target router_lib
[ 51%] Built target mysqlrouter
[ 71%] Built target fabric_cache
[ 74%] Built target cache_test
[100%] Built target routing
Install the project...
-- Install configuration: ""
-- Up-to-date: /usr/local/include/mysql/mysqlrouter/loader.h
-- Up-to-date: /usr/local/include/mysql/mysqlrouter/filesystem.h
-- Up-to-date: /usr/local/include/mysql/mysqlrouter/plugin.h
-- Up-to-date: /usr/local/include/mysql/mysqlrouter/config_parser.h
-- Installing: /usr/local/lib/libmysqlharness.a
-- Installing: /usr/local/lib/libmysqlharness.so.0
-- Up-to-date: /usr/local/lib/libmysqlharness.so
-- Set runtime path of "/usr/local/lib/libmysqlharness.so.0" to "$ORIGIN/../lib"
-- Installing: /usr/local/lib/mysqlrouter/keepalive.so
-- Set runtime path of "/usr/local/lib/mysqlrouter/keepalive.so" to "$ORIGIN"
-- Installing: /usr/local/lib/mysqlrouter/logger.so
-- Set runtime path of "/usr/local/lib/mysqlrouter/logger.so" to "$ORIGIN"
-- Up-to-date: /usr/local/include/mysql/mysqlrouter/logger.h
-- Up-to-date: /usr/local/share/doc/mysqlrouter/README.txt
-- Up-to-date: /usr/local/share/doc/mysqlrouter/License.txt
-- Up-to-date: /usr/local/include/mysql/mysqlrouter/plugin_config.h
-- Up-to-date: /usr/local/include/mysql/mysqlrouter/utils.h
-- Up-to-date: /usr/local/include/mysql/mysqlrouter/datatypes.h
-- Installing: //var
-- Installing: //var/local
-- Installing: //var/local/mysqlrouter
-- Installing: //var/local/mysqlrouter/log
-- Installing: //var
-- Installing: //var/local
-- Installing: //var/local/mysqlrouter
-- Installing: //var/local/mysqlrouter/run
-- Installing: /usr/local/etc
-- Installing: /usr/local/etc/mysqlrouter
-- Installing: /usr/local/bin/mysqlrouter
-- Set runtime path of "/usr/local/bin/mysqlrouter" to "$ORIGIN/../lib"
-- Installing: /usr/local/lib/libmysqlrouter.so.1
-- Up-to-date: /usr/local/lib/libmysqlrouter.so
-- Set runtime path of "/usr/local/lib/libmysqlrouter.so.1" to "$ORIGIN/../lib"
-- Installing: /usr/local/lib/mysqlrouter/fabric_cache.so
-- Set runtime path of "/usr/local/lib/mysqlrouter/fabric_cache.so" to "$ORIGIN:<path to server code>/lib"
-- Up-to-date: /usr/local/include/mysql/mysqlrouter/fabric_cache.h
-- Installing: /usr/local/lib/mysqlrouter/routing.so
-- Set runtime path of "/usr/local/lib/mysqlrouter/routing.so" to "$ORIGIN"
-- Up-to-date: /usr/local/include/mysql/mysqlrouter/routing.h

2.4.4 Testing the Installation

You can ensure the installation succeeded by running the following command. You should see a similar output on your system. An example of setting the Router for simple routing is shown in the Postinstallation Testing section.

Note

Our example assumes that mysqlrouter is in the system's PATH. In this case, PATH includes /usr/local/bin.

shell>  mysqlrouter --help

MySQL Router v2.0.3 on Linux (64-bit) (GPL community edition)
Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Start MySQL Router.

Configuration read from the following files in the given order (enclosed
in parentheses means not available for reading):
  (/usr/local/etc/mysqlrouter/mysqlrouter.ini)
  (/home/cbell/.mysqlrouter.ini)

Usage: mysqlrouter [-v|--version] [-h|--help]
                   [-c|--config=<path>]
                   [-a|--extra-config=<path>]

Options:
  -v, --version
        Display version information and exit.
  -h, --help
        Display this help and exit.
  -c <path>, --config <path>
        Only read configuration from given file.
  -a <path>, --extra-config <path>
        Read this file after configuration files are read from either
        default locations or from files specified by the --config
        option.

Note

Use the mysqlrouter --version command to check the version.

2.5 Postinstallation Testing

In this section, we will see how to test your MySQL Router installation by setting up the Router to perform simple routing. In this case, the Router will act as an intermediate node redirecting client connections to a list of servers. If one server fails, clients will be redirected to the next available server in the list.

To illustrate this concept, we will use a simple Python script and a set of three MySQL Servers. Ordinarily, these servers would be setup in a replication topology but for this example we want to test simple routing. Thus, the servers are not setup in a replication topology. Thus, this test is only a test and not indicative of an actual application or use case for MySQL Router

Setup the Servers

Begin by starting three MySQL Servers. You can do this in a variety of ways from using the mysql-test-run.pl script, installing three servers on three machines or the same machine, or using MySQL Utilities to clone a running server. The following shows how to start three servers cloned from the original server. The original server is listening on port 3306. The cloned servers will be running on the localhost and listening on ports 13001, 13002, and 13003 respectfully.

shell>  mysqlserverclone --source=root:secret@localhost --new-data=./test_13001 --new-port=13001 --root=secret --delete 
# Cloning the MySQL server located at localhost:3306
# Creating new data directory...
# Configuring new instance...
# Locating mysql tools...
# Setting up empty database and mysql tables...
# Starting new instance of the server...
# Testing connection to new instance...
# Success!
# Setting the root password...
# Connection Information:
#  -uroot -psecret --socket=/test_13001/mysql.sock
#...done.
shell>  mysqlserverclone --source=root:secret@localhost --new-data=./test_13002 --new-port=13002 --root=secret --delete 
# Cloning the MySQL server located at localhost:3306
# Creating new data directory...
# Configuring new instance...
# Locating mysql tools...
# Setting up empty database and mysql tables...
# Starting new instance of the server...
# Testing connection to new instance...
# Success!
# Setting the root password...
# Connection Information:
#  -uroot -psecret --socket=/test_13002/mysql.sock
#...done.
shell>  mysqlserverclone --source=root:secret@localhost --new-data=./test_13003 --new-port=13003 --root=secret --delete 
# Cloning the MySQL server located at localhost:3306
# Creating new data directory...
# Configuring new instance...
# Locating mysql tools...
# Setting up empty database and mysql tables...
# Starting new instance of the server...
# Testing connection to new instance...
# Success!
# Setting the root password...
# Connection Information:
#  -uroot -psecret --socket=/test_13003/mysql.sock
#...done.
Note

For a complete explanation of how to use mysqlserverclone, see mysqlserverclone — Clone Existing Server to Create New Server.

Next, we make a minor change to each server so that we can see the redirect in action. More specifically, we create a different database on each server to uniquely identify each server as shown.

shell>  mysql -uroot -p -h 127.0.0.1 --port=13001 -e "CREATE DATABASE test_13001" 
shell>  mysql -uroot -p -h 127.0.0.1 --port=13002 -e "CREATE DATABASE test_13002" 
shell>  mysql -uroot -p -h 127.0.0.1 --port=13003 -e "CREATE DATABASE test_13003" 

As you can see, we created a database with the port of the server in the name. This way, we can tell to which server the Router has sent the client.

Set Up the Router

Next, we set up MySQL Router to redirect to these servers. We must set up a configuration file to tell the Router how to route the connections. The following shows a simple configuration to match this test.

A complete explanation of the configuration file and all of the options is describe in a later chapter. For now, we will use a simplified configuration.

[DEFAULT]
logging_folder =

[logger]
level = INFO

[routing:basic_redirect]
bind_port = 7001
mode = read-write
destinations = localhost:13001,localhost:13002,localhost:13003

The first section, DEFAULT, lists the paths to the Router installation and MySQL server. These paths are common for most Unix and Linux platforms (e.g. Ubuntu) but other platforms may differ. Be sure to change these to match your system. We left the optional logging_folder blank, in order to view logger output in the console. That is also default behavior.

The second section, logger, is used to set the logging level. In this case, we turn on basic logging to the console.

The third section, routing:basic_redirect, is where the magic happens. Here we see the Router is instructed to listen on the localhost and port 7001 using the bind_port setting. We turn on read-write mode for reading and writing. The destinations option is where we specify the list of servers to use in the redirect. In this case, we see servers on the localhost at ports 13001, 13002, and 13003.

What this means is the client will connect to the Router on port 7001 and it will redirect client connections to the first available server in the destinations list.

If you are following along, save this file to a file named my_router.ini.

Now, let us start the Router. For this, we tell the Router which configuration file to read as shown below.

shell>   mysqlrouter -c my_router.ini 
2015-10-20 19:50:08 INFO    [7f9631018700] routing:basic_failover started: listening on localhost:7001; read-write

Here we see the Router has started and is waiting for connections on port 7001.

Testing the Router

Finally, let us test the Router. We will start a simple client script using Python and connect to the Router. While the script is running, we kill one of the servers then test how the Router redirects.

Begin by launching a Python console and entering the following statements.

shell>  python 
Python 2.7.9 (default, Apr  2 2015, 15:33:21) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mysql.connector
>>> cnx = mysql.connector.connect(host='localhost',port=7001,user='root',password='secret')
>>> cur = cnx.cursor()
>>> cur.execute("SHOW DATABASES")
>>> print cur.fetchall()
[(u'information_schema',), (u'mysql',), (u'performance_schema',), (u'test_13001',)]

Notice we connected to the Router on port 7001. When we executed a simple query, SHOW DATABASES, we see the result includes the test_13001 database and therefore we know the Router has redirected the client to the server on port 13001 as shown in the configuration file.

Next, we shutdown the server running on port 13001 as follows.

Note

If you don't want to use the database name method, you can also execute the query, SHOW VARIABLES LIKE 'port' to get the port for the connected server.

shell>  mysqladmin shutdown -uroot -p -h 127.0.0.1 --port=13001        
      

Next, return to the Python console and attempt to run the query again. What you should see is an error stating the connection has dropped. Indeed, this is the case because the client was connected (redirected via the Router) to the server running on port 13001, which has just been shutdown.

>>> cur.execute("SHOW DATABASES")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/mysql/connector/cursor.py", line 511, in execute
    self._handle_result(self._connection.cmd_query(stmt))
  File "/usr/local/lib/python2.7/dist-packages/mysql/connector/connection.py", line 486, in cmd_query
    result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
  File "/usr/local/lib/python2.7/dist-packages/mysql/connector/connection.py", line 270, in _send_cmd
    return self._socket.recv()
  File "/usr/local/lib/python2.7/dist-packages/mysql/connector/network.py", line 228, in recv_plain
    raise errors.InterfaceError(errno=2013)
mysql.connector.errors.InterfaceError: 2013: Lost connection to MySQL server during query

If this were an actual application, the developer would have written the code to catch errors like this and retry the connection. Another valid technique is to connect, execute, then disconnect which will ensure the Router will redirect without having to detect the error (but good error handling is always advisable and prudent).

Since this is only a test, we can simply reconnect to the Router, which will redirect us to the next server in the list. Reenter the same commands as before to connect and run the same query.

>>> cnx = mysql.connector.connect(host='localhost',port=7001,user='root',password='secret')
>>> cur = cnx.cursor()
>>> cur.execute("SHOW DATABASES")
>>> print cur.fetchall()
[(u'information_schema',), (u'mysql',), (u'performance_schema',), (u'sys',), (u'test_13002',)]

Notice this time the Router has redirected the client to the server running on port 13002, as intended.

If you then shutdown that server and reconnect, you will see the Router has redirected the client to the last server in the list.

>>> cnx = mysql.connector.connect(host='localhost',port=7001,user='root',password='secret')
>>> cur = cnx.cursor()
>>> cur.execute("SHOW DATABASES")
>>> print cur.fetchall()
[(u'information_schema',), (u'mysql',), (u'performance_schema',), (u'sys',), (u'test_13003',)]

We have now demonstrated the Router in action performing simple redirects to a list of servers.