HA Proxy for MySQL - Failover only

Is it possible use HA proxy as a fail over only and if so, how would you set it?

Yes, it is possible by adding the backup option to the end of server line, something like this:

frontend FE_mysql_writer
    bind V.I.P.A:3306
    default_backend BE_mysql_writer

backend BE_mysql_writer
    mode tcp
    balance roundrobin
    option tcpka
    option httpchk
    server mysql1 ip1:3306 weight 1 check port 9199 inter 12000 rise 3 fall 3
    server mysql2 ip2:3306 weight 1 check port 9199 inter 12000 rise 3 fall 3 backup

Port 9199 is used to monitor MySQL status:

/etc/services

mysqlchk    9199/tcp            # mysqlchk

/etc/xinetd.d/mysqlchk

# /etc/xinetd.d/mysqlchk
# default: on
# description: mysqlchk
service mysqlchk
{
        flags           = REUSE
        socket_type     = stream
        port            = 9199
        wait            = no
        user            = nobody
        server          = /opt/mysqlchk
        log_on_failure  += USERID
        disable         = no
        only_from       = 0.0.0.0/0 # recommended to put the IPs that need
                                    # to connect exclusively (security purposes)
        per_source      = UNLIMITED # Recently added (May 20, 2010)
                                    # Prevents the system from complaining
                                    # about having too many connections open from
                                    # the same IP. More info:
                                    # http://www.linuxfocus.org/English/November2000/article175.shtml
}

/opt/mysqlchk

#!/bin/bash
# /opt/mysqlchk 
# This script checks if a mysql server is healthy running on localhost. It will
# return:
#
# "HTTP/1.x 200 OK\r" (if mysql is running smoothly)
#
# - OR -
#
# "HTTP/1.x 500 Internal Server Error\r" (else)
#
# The purpose of this script is make haproxy capable of monitoring mysql properly
#
# Author: Unai Rodriguez
#
# It is recommended that a low-privileged-mysql user is created to be used by
# this script. Something like this:
#
# mysql> GRANT SELECT on mysql.* TO 'mysqlchkusr'@'localhost' \
#     -> IDENTIFIED BY '257retfg2uysg218' WITH GRANT OPTION;
# mysql> flush privileges;

MYSQL_HOST="localhost"
MYSQL_PORT="3306"
MYSQL_USERNAME="mysqlchkusr"
MYSQL_PASSWORD="pa$$w0rd"

TMP_FILE="/tmp/mysqlchk.out"
ERR_FILE="/tmp/mysqlchk.err"

#
# We perform a simple query that should return a few results :-p
#
/usr/bin/mysql --host=$MYSQL_HOST --port=$MYSQL_PORT --user=$MYSQL_USERNAME \
    --password=$MYSQL_PASSWORD -e"show databases;" > $TMP_FILE 2> $ERR_FILE

#
# Check the output. If it is not empty then everything is fine and we return
# something. Else, we just do not return anything.
#
if [ "$(/bin/cat $TMP_FILE)" != "" ]
then
    # mysql is fine, return http 200
    /bin/echo -e "HTTP/1.1 200 OK\r\n"
    /bin/echo -e "Content-Type: Content-Type: text/plain\r\n"
    /bin/echo -e "\r\n"
    /bin/echo -e "MySQL is running.\r\n"
    /bin/echo -e "\r\n"
else
    # mysql is fine, return http 503
    /bin/echo -e "HTTP/1.1 503 Service Unavailable\r\n"
    /bin/echo -e "Content-Type: Content-Type: text/plain\r\n"
    /bin/echo -e "\r\n"
    /bin/echo -e "MySQL is *down*.\r\n"
    /bin/echo -e "\r\n"
fi

Source: http://sysbible.org/2008/12/04/having-haproxy-check-mysql-status-through-a-xinetd-script/


But wait, when a master fails, how do you point the slaves to the new master? You had better use HAProxy to load balancing the read operations and let the write operation (includes the failover) to the Percona Pacemaker Resource Agents handle.


Note that some client implementations of mysql (such as the official JDBC connector) supports this without using load balancer software. If you happen to be so lucky (or unlucky) that you have such a connector and control over it's config, there are a few benefits, namely:

  • Client side failover. One less instance where something can go wrong.

  • Increased read performance by using the failover nodes for reads.

  • Lower latency (which is mostly nitpicking, but very important in some setups)

See examples for JDBC.

And there is mysqlproxy which solves it more or less the same way as ha-proxy.