Replication and auto-failover made easy with MySQL Utilities

MySQL utilities in Workbench

Utilities in MySQL Workbench

If you’re a user of MySQL Workbench then you may have noticed a pocket knife icon appear in the top right hand corner – click on that and a terminal opens which gives you access to the MySQL utilities. In this post I’m focussing on the replication utilities but you can also refer to the full MySQL Utilities documentation.

What I’ll step through is how to uses these utilities to:

  • Set up replication from a single master to multiple slaves
  • Automatically detect the failure of the master and promote one of the slaves to be the new master
  • Introduce the old master back into the topology as a new slave and then promote it to be the master again

Tutorial Video

Before going through the steps in detail here’s a demonstration of the replication utilities in action…

To get full use of these utilities you should use the InnoDB storage engine together with the Global Transaction ID functionality from the latest MySQL 5.6 DMR.

Do you really need/want auto-failover?

For many people, the instinctive reaction is to deploy a fully automated system that detects when the master database fails and then fails over (promotes a slave to be the new master) without human intervention. For many applications this may be the correct approach.

There are inherent risks to this though – What if the failover implementation has a flaw and fails (after all, we probably don’t test this out in the production system very often)? What if the slave isn’t able to cope with the workload and makes things worse? Is it just a transitory glitch and would the best approach have been just to wait it out?

Following a recent, high profile outage there has been a great deal of debate on the topic between those that recommend auto-failover and those that believe it should only ever be entrusted to a knowledgeable (of the application and the database architecture) and well informed (of the state of the database nodes, application load etc.) human. Of course, if the triggering of the failover is to be left to a human then you want that person to have access to the information they need and an extremely simple procedure (ideally a single command) to execute the failover. Probably the truth is that it all depends on your specific circumstances.

The MySQL replication utilities aim to support you whichever camp you belong to:

  • In the fully automated mode, the utilities will continually monitor the state of the master and in the event of its failure identify the best slave to promote – by default it will select the one that is most up-to-date and then apply any changes that are available on other slaves but not on this one before promoting it to be the new master. The user can override this behaviour (for example by limiting which of the slaves are eligible for promotion). The user is also able to bind in their own programs to be run before and after the failover (for example, to inform the application).
  • In the monitoring mode, the utility still continually checks the availability of the master, and informs the user if it should fail. The user then executes a single command to fail over to their preferred slave.

Step 1. Make sure MySQL Servers are configured correctly

For some of the utilities, it’s important that you’re using Global Transaction IDs; binary logging needs to be enabled; may as well use the new crash-safe slave functionality… It’s beyond the scope of this post to go through all of those and so instead I’ll just give example configuration files for the 5 MySQL Servers that will be used:

my1.cnf

[mysqld]
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
disable-gtid-unsafe-statements=true # Use enforce-gtid-consistency from 5.6.9+
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
datadir=/home/billy/mysql/data1
server-id=1
log-bin=util11-bin.log
report-host=utils1
report-port=3306
socket=/home/billy/mysql/sock1
port=3306

my2.cnf

[mysqld]
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
disable-gtid-unsafe-statements=true # Use enforce-gtid-consistency from 5.6.9+
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
datadir=/home/billy/mysql/data2
server-id=2
log-bin=util12-bin.log
report-host=utils1
report-port=3307
socket=/home/billy/mysql/sock2
port=3307

my3.cnf

[mysqld]
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
disable-gtid-unsafe-statements=true # Use enforce-gtid-consistency from 5.6.9+
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
datadir=/home/billy/mysql/data3
server-id=3
log-bin=util2-bin.log
report-host=utils2
report-port=3306
socket=/home/billy/mysql/sock3
port=3306

my4.cnf

[mysqld]
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
disable-gtid-unsafe-statements=true # Use enforce-gtid-consistency from 5.6.9+
master-info-repository=TABLE
relay-log-info-repository=TABLE
master-info-file=/home/billy/mysql/master4.info
datadir=/home/billy/mysql/data4
server-id=4
log-bin=util4-bin.log
report-host=utils2
report-port=3307
socket=/home/billy/mysql/sock4
port=3307

my5.cnf

[mysqld]
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
disable-gtid-unsafe-statements=true # Use enforce-gtid-consistency from 5.6.9+
datadir=/home/billy/mysql/data5
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
#master-info-file=/home/billy/mysql/master5.info
server-id=5
log-bin=util5-bin.log
report-host=utils2
report-port=3308
socket=/home/billy/mysql/sock5
port=3308

The utilities are actually going to be run from a remote host and so it will be necessary for that host to access each of the MySQL Servers and so a user has to be granted remote access (note that the utilities will automatically create the replication user):

[billy@utils1 ~]$ mysql -h 127.0.0.1 -P3306 -u root -e "grant all on *.* to root@'%' with grant option;"
[billy@utils1 ~]$ mysql -h 127.0.0.1 -P3307 -u root -e "grant all on *.* to root@'%' with grant option;"
[billy@utils2 ~]$ mysql -h 127.0.0.1 -P3306 -u root -e "grant all on *.* to root@'%' with grant option;"
[billy@utils2 ~]$ mysql -h 127.0.0.1 -P3307 -u root -e "grant all on *.* to root@'%' with grant option;"
[billy@utils2 ~]$ mysql -h 127.0.0.1 -P3308 -u root -e "grant all on *.* to root@'%' with grant option;"

OK – that’s the most painful part of the whole process out of the way!

Set up replication

While there are extra options (such as specifying what username/password to use for the replication user or providing a password for the root user) I’m going to keep things simple and use the defaults as much as possible. The following commands are run from the MySQL Utilities terminal – just click on the pocket-knife icon in MySQL Workbench.

mysqlreplicate --master=root@utils1:3306 --slave=root@utils1:3307
# master on utils1: ... connected.
# slave on utils1: ... connected.
# Checking for binary logging on master...
# Setting up replication...
# ...done.

mysqlreplicate --master=root@utils1:3306 --slave=root@utils2:3306
# master on utils1: ... connected.
# slave on utils2: ... connected.
# Checking for binary logging on master...
# Setting up replication...
# ...done.

mysqlreplicate --master=root@utils1:3306 --slave=root@utils2:3307
# master on utils1: ... connected.
# slave on utils2: ... connected.
# Checking for binary logging on master...
# Setting up replication...
# ...done.

mysqlreplicate --master=root@utils1:3306 --slave=root@utils2:3308
# master on utils1: ... connected.
# slave on utils2: ... connected.
# Checking for binary logging on master...
# Setting up replication...
# ...done.

That’s it, replication has now been set up from one master to four slaves.

You can now check that the replication topology matches what you intended:

mysqlrplshow --master=root@utils1 --discover-slaves-login=root;
# master on utils1: ... connected.
# Finding slaves for master: utils1:3306

# Replication Topology Graph
utils1:3306 (MASTER)
   |
   +--- utils1:3307 - (SLAVE)
   |
   +--- utils2:3306 - (SLAVE)
   |
   +--- utils2:3307 - (SLAVE)
   |
   +--- utils2:3308 - (SLAVE)

Additionally, you can also check that any of the replication relationships is correctly configure:

mysqlrplcheck --master=root@utils1 --slave=root@utils2
# master on utils1: ... connected.
# slave on utils2: ... connected.
Test Description                                                     Status
---------------------------------------------------------------------------
Checking for binary logging on master                                [pass]
Are there binlog exceptions?                                         [pass]
Replication user exists?                                             [pass]
Checking server_id values                                            [pass]
Is slave connected to master?                                        [pass]
Check master information file                                        [pass]
Checking InnoDB compatibility                                        [pass]
Checking storage engines compatibility                               [pass]
Checking lower_case_table_names settings                             [pass]
Checking slave delay (seconds behind master)                         [pass]
# ...done.

Including the -s option would have included the output that you’d expect to see from SHOW SLAVE STATUSG on the slave.

Automated monitoring and failover

The previous section showed how you can save some serious time (and opportunity for user-error) when setting up MySQL replication. We now look at using the utilities to automatically monitor the state of the master and then automatically promote a new master from the pool of slaves. For simplicity I’ll stick with default values wherever possible but note that there are a number of extra options available to you such as:

  • Constraining which slaves are eligible for promotion to master; the default is to take the most up-to-date slave
  • Binding in your own scripts to be run before or after the failover (e.g. inform your application to switch master?)
  • Have the utility monitor the state of the servers but don’t automatically initiate failover

Here is how to set it up:

mysqlfailover --master=root@utils1:3306 --discover-slaves-login=root --rediscover

MySQL Replication Failover Utility
Failover Mode = auto     Next Interval = Wed Aug 15 13:19:30 2012

Master Information
------------------
Binary Log File    Position  Binlog_Do_DB  Binlog_Ignore_DB
util11-bin.000001  2586

Replication Health Status
+---------+-------+---------+--------+------------+---------+
| host    | port  | role    | state  | gtid_mode  | health  |
+---------+-------+---------+--------+------------+---------+
| utils1  | 3306  | MASTER  | UP     | ON         | OK      |
| utils1  | 3307  | SLAVE   | UP     | ON         | OK      |
| utils2  | 3306  | SLAVE   | UP     | ON         | OK      |
| utils2  | 3307  | SLAVE   | UP     | ON         | OK      |
| utils2  | 3308  | SLAVE   | UP     | ON         | OK      |
+---------+-------+---------+--------+------------+---------+

Q-quit R-refresh H-health G-GTID Lists U-UUIDs

mysqlfailover will then continue to run, refreshing the state – just waiting for something to go wrong.

Rather than waiting, I kill the master MySQL Server:

mysqladmin -h utils1 -P3306 -u root shutdown

Checking with the still-running mysqlfailover we can see that it has promoted utils1:3307.

MySQL Replication Failover Utility
Failover Mode = auto     Next Interval = Wed Aug 15 13:21:13 2012

Master Information
------------------
Binary Log File    Position  Binlog_Do_DB  Binlog_Ignore_DB
util12-bin.000001  7131

Replication Health Status
+---------+-------+---------+--------+------------+---------+
| host    | port  | role    | state  | gtid_mode  | health  |
+---------+-------+---------+--------+------------+---------+
| utils1  | 3307  | MASTER  | UP     | ON         | OK      |
| utils2  | 3306  | SLAVE   | UP     | ON         | OK      |
| utils2  | 3307  | SLAVE   | UP     | ON         | OK      |
| utils2  | 3308  | SLAVE   | UP     | ON         | OK      |
+---------+-------+---------+--------+------------+---------+

Q-quit R-refresh H-health G-GTID Lists U-UUIDs

Add the recovered MySQL Server back into the topology

After restarting the failed MySQL Server, it can be added back into the mix as a slave to the new master:

mysqlreplicate --master=root@utils1:3307 --slave=root@utils1:3306
# master on utils1: ... connected.
# slave on utils1: ... connected.
# Checking for binary logging on master...
# Setting up replication...
# ...done.

The output from mysqlfailover (still running) confirms the addition:

MySQL Replication Failover Utility
Failover Mode = auto     Next Interval = Wed Aug 15 13:24:38 2012

Master Information
------------------
Binary Log File    Position  Binlog_Do_DB  Binlog_Ignore_DB
util12-bin.000001  7131

Replication Health Status
+---------+-------+---------+--------+------------+---------+
| host    | port  | role    | state  | gtid_mode  | health  |
+---------+-------+---------+--------+------------+---------+
| utils1  | 3307  | MASTER  | UP     | ON         | OK      |
| utils1  | 3306  | SLAVE   | UP     | ON         | OK      |
| utils2  | 3306  | SLAVE   | UP     | ON         | OK      |
| utils2  | 3307  | SLAVE   | UP     | ON         | OK      |
| utils2  | 3308  | SLAVE   | UP     | ON         | OK      |
+---------+-------+---------+--------+------------+---------+

Q-quit R-refresh H-health G-GTID Lists U-UUIDs

If it were important that the recovered MySQL Server be restored as the master then it is simple to manually trigger the promotion (after quitting out of mysqlfailover):

mysqlrpladmin --master=root@utils1:3307 --new-master=root@utils1:3306 --demote-master 
  --discover-slaves-login=root switchover

# Discovering slaves for master at utils1:3307
# Checking privileges.
# Performing switchover from master at utils1:3307 to slave at utils1:3306.
# Checking candidate slave prerequisites.
# Waiting for slaves to catch up to old master.
# Stopping slaves.
# Performing STOP on all slaves.
# Demoting old master to be a slave to the new master.
# Switching slaves to new master.
# Starting all slaves.
# Performing START on all slaves.
# Checking slaves for errors.
# Switchover complete.
#
# Replication Topology Health:
+---------+-------+---------+--------+------------+---------+
| host    | port  | role    | state  | gtid_mode  | health  |
+---------+-------+---------+--------+------------+---------+
| utils1  | 3306  | MASTER  | UP     | ON         | OK      |
| utils1  | 3307  | SLAVE   | UP     | ON         | OK      |
| utils2  | 3306  | SLAVE   | UP     | ON         | OK      |
| utils2  | 3307  | SLAVE   | UP     | ON         | OK      |
| utils2  | 3308  | SLAVE   | UP     | ON         | OK      |
+---------+-------+---------+--------+------------+---------+
# ...done.

As always, we’d really appreciate people trying this out and giving us feedback!





77 comments

  1. You are probably not unaware (at least you should not be!) that on planet.mysql.com there have been quite a lot of discussion about automatic failover recently (triggered by recent failure at GitHub).

    You don’t relate to this at all and I think you should. Reading this post leaves the impression that automativ failover is unproblematic.

    I think you should address/comment the problems raised by others (what of course are – more or less -independent of whether WB or other methods/tools are used for setting up the failover system).

  2. oops .. I totally missed this. I am trying to find my mousehole!

  3. Ulf Wendel says:

    Where to get MySQL Utilities from if one does not want to install MySQL Workbench but only the command line utils?

    • andrew says:

      Hi Ulf,

      I think you already know the answer to this now but you can either get the source from Launchpad or wait until we release it in a package independently of WorkBench.

      Andrew.

  4. [...] want to evaluate the new mysqlfailover utility designed for MySQL 5.6 and GTIDs. There’s a nice demo. The mysqlfailover utility offers hooks like MHA but does not pass any information on the cluster [...]

  5. Mohammad Khan says:

    Hi All,

    I am seeing some issues while setting up MySQL Master Master replication and I would appreciate any help in resolving this problem.

    I Installed Server vsersion:5.5.29-ndb-7.2.10-cluster-gpl-log MySQL Cluster Community server on two separate windows 2003 machines.installed my database on both machines.Setup replication user.In mysql command line utility on mySLQ server1,ran the following commands:

    change master to master_host=’IP1′,master_user=’user1′,master_password=’PW1′;

    start slave;

    On the second mysql server2, ran the commands:

    change master to master_host=’IP2′,master_user=’user1′,master_password=’PW1′;

    start slave;

    However, when I run the following command on machine 1, I see:

    mysql> show slave statusG;
    *************************** 1. row ***************************
    Slave_IO_State:
    Master_Host: 10.0.0.71
    Master_User: replication
    Master_Port: 3306
    Connect_Retry: 60
    Master_Log_File:
    Read_Master_Log_Pos: 4
    Relay_Log_File: MySQLStreamA-relay-bin.000001
    Relay_Log_Pos: 4
    Relay_Master_Log_File:
    Slave_IO_Running: No
    Slave_SQL_Running: Yes
    Replicate_Do_DB:
    Replicate_Ignore_DB:
    Replicate_Do_Table:
    Replicate_Ignore_Table: activevos.AeURNValues,activevos.AeCounter,activev
    os.AeLock,activevos.AeMetaInfo
    Replicate_Wild_Do_Table:
    Replicate_Wild_Ignore_Table:
    Last_Errno: 0
    Last_Error:
    Skip_Counter: 0
    Exec_Master_Log_Pos: 0
    Relay_Log_Space: 112
    Until_Condition: None
    Until_Log_File:
    Until_Log_Pos: 0
    Master_SSL_Allowed: No
    Master_SSL_CA_File:
    Master_SSL_CA_Path:
    Master_SSL_Cert:
    Master_SSL_Cipher:
    Master_SSL_Key:
    Seconds_Behind_Master: NULL
    Master_SSL_Verify_Server_Cert: No
    Last_IO_Errno: 1593
    Last_IO_Error: Fatal error: The slave I/O thread stops because m
    aster and slave have equal MySQL server ids; these ids must be different for rep
    lication to work (or the –replicate-same-server-id option must be used on slave
    but this does not always make sense; please check the manual before using it).
    Last_SQL_Errno: 0
    Last_SQL_Error:
    Replicate_Ignore_Server_Ids:
    Master_Server_Id: 3
    Master_Bind:
    1 row in set (0.00 sec)

    ERROR:
    No query specified

    mysql>

    Similar error is seen in machine2 also.

    I double checked that each of the mysql servers had unique server IDs.And I varified it using ‘SHOW VARIABLES’ command as well as from the .ini file. Also here are the replication settings in .ini file:

    On machine1:

    # If you’re using replication with chained slaves (A->B->C), you need to
    # enable this option on server B. It enables logging of updates done by
    # the slave thread into the slave’s binary log.
    log_slave_updates

    # *** Replication related settings

    # Unique server identification number between 1 and 2^32-1. This value
    # is required for both master and slave hosts. It defaults to 1 if
    # “master-host” is not set, but will MySQL will not function as a master
    # if it is omitted.
    server-id = 3
    replicate-same-server-id = 0
    auto-increment-increment = 2
    auto-increment-offset = 3

    sync_binlog=1
    log-bin = C:mysqlloglog-bin.log # change this to a path/name appropriate to your system
    relay-log=MySQLStreamA-relay-bin

    And on machine2:

    # If you’re using replication with chained slaves (A->B->C), you need to
    # enable this option on server B. It enables logging of updates done by
    # the slave thread into the slave’s binary log.
    log_slave_updates

    # *** Replication related settings

    # Unique server identification number between 1 and 2^32-1. This value
    # is required for both master and slave hosts. It defaults to 1 if
    # “master-host” is not set, but will MySQL will not function as a master
    # if it is omitted.
    server-id = 4
    replicate-same-server-id = 0
    auto-increment-increment = 2
    auto-increment-offset = 4

    sync_binlog=1
    log-bin = C:mysqlloglog-bin.log # change this to a path/name appropriate to your system
    relay-log=MySQLStreamB-relay-bin

    It is not clear to me why I am seeing this error.

    Any suggestions on how I can resolve this problem?

    Thanks.

  6. OTHMAN says:

    Hi,
    Great works, this tutorial helped me a lot to make my database architecture, but after replication phase, when I can’t see Graph topology inspite mysqlrplcheck works very well and SHOW SLAVE HOSTS command too, but I can’t see the topology using mysqlrplshow,
    please help !
    thanks

  7. Esteban says:

    Hi, I’m relatively new at mysql, and I need to set up a topology like this, only a master and one slave, a have a few question about it, and would appreciate if you answer them, this replication mode means that any changes made in the master’s database will be made in the slaves’s? also, when the master fails, automatically a slave starts serving, but when the master comes up again, Does mysql automatically detects it?

    • andrew says:

      Esteban,

      Yes – data will be replicated from the master to the slaves.

      If the original master is recovered then you manually use the utilities to add the master back in as a slave; once it has caught up with any changes it has missed then you can again use the utilities to promote it back into being the master.

      Andrew.

  8. runingday says:

    hello,i do this test in root user!
    my.cnf

    [mysqld]
    datadir=/var/lib/mysql
    socket=/var/lib/mysql/mysql.sock
    binlog-format=ROW
    log-slave-updates=true
    gtid-mode=on
    disable-gtid-unsafe-statements=true # Use enforce-gtid-consistency from 5.6.9+
    master-info-repository=TABLE
    relay-log-info-repository=TABLE
    sync-master-info=1
    server-id=1
    log-bin=util11-bin.log
    report-host=utils1
    report-port=3306
    port=3306

    [root@utils1 ~]# rpm -qa | grep mysql
    php-mysql-5.1.6-27.el5_5.3
    mysql-5.0.77-4.el5_5.4
    mysql-server-5.0.77-4.el5_5.4

    the server can not start now!

    [root@utils1 ~]# /etc/init.d/mysqld restart
    停止 MySQL: [失败]
    Timeout error occurred trying to start MySQL Daemon.
    启动 MySQL: [失败]

    what should i do?
    thanks!!!

    • andrew says:

      runningday,

      it looks like you’re trying to run MySQL 5.0 with the config file setup with MySQL 5.6 features. You should download & install MySQL from mysql.com and then try again. Note that you should also customise the config file to your envuironment – e.g. report-host should be your hostname.

      Andrew.

  9. Ed says:

    I have a small 1 Mgm Node, 2 Data Nodes, and 2 SQL(API) Nodes setup. I have not setup any SQL node as “slave” explicitly, so my assumption is that both my SQL Nodes are Masters. Is that assumption correct? I can make modifications to either one and the changes are reflected on the other server. However, that is not true during a fail-over scenario.

    If I down one of the SQL Nodes while connected to it from my UI interface, and proceed to try to perform modification operations, I get exceptions like this one:

    Caused by: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed

    Now, I read that the connection goes read-only during fail over if the autocommit property is set to true. Would I have to change this property value to false, if so, where? on each of the SQL Node’s my.cnf, the Mgmnt config.ini or in my JDBC URL? or is this even possible with MySQL Cluster?

    Or should I try handling the exception in my code, refresh the connection to hopefully get the new SQL Node that is running and try to execute the update query? My JDBC URL already has loadbalance, plus the list of SQL Nodes to use, it has the loadBalanceStrategy set to bestResponseTime, has the black list property,
    SQL state failover for errors starting with 08, and sub class failover property for java.sql.SQLTransientConnectionException.

    Any hints, ideas, and/or samples would be much appreciated.

    -Ed

    • andrew says:

      Hi Ed,

      you are correct that if part of the Cluster, both MySQL Servers can be treated as masters for any tables created using the NDBCLUSTER storage engine (ENGINE=NDB when creating or altering the table). The data isn’t actually stored or even cached (unless you’re using MySQL Server’s query cache – which in most cases isn’t a good idea with MySQL Cluster) in the MySQL Server – the mysqld just provides an SQL interface to reach through to the data nodes for the data.

      In the event that one MySQL Server should fail, there should be no impact on the other and all traffic can be sent to the other. You can just load ballance traffic between your 2 MySQL Servers.

      I confess that I’m not an expert on Connector/J but this chapter of the Connector/J manual covers configuring failover for MySQL Cluster and hopefully will give you the information you need… http://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-j2ee-concepts-load-balancing-failover.html

      If you need more help with Connector/J then you could also try this dedicated Connector/J forum.

      Regards, Andrew.

  10. Ed says:

    Thank you, Andrew. I noticed that I can add the failOverReadOnly flag to my JDBC URL and set it to false to create a r/w connection instead of read-only.

    If you know of any good JDBC wrappers, proxy, or whatever they’re called, which is open source, please let us know. I’m interested in something like HA-JDBC (http://ha-jdbc.github.io/) that could handle fail-over in a seamless way, without me having to change code(Java). I’d like to keep my code DB agnostic if at all possible.

    Thanks again for your help and suggestions.

    -Ed

  11. hola buenos dias. no soy experto en MySQL, pero me gusta, tengo 3 sucursales(SUC 1, SUC 2, SUC 3) y 1 matriz (MA1), en cada tienda un programa de inventario(POS) en JAVA, y un servidor MySQL en cada sucursal. Mis necesidades son: SI SE REALIZA UNA VENTA EN SUC 1(INSERT), QUE SE MUESTRE EN SUC 2, SUC3 Y MA1, SI LA MERCANCIA LLEGA EN MA1 (INSERT) QUE LAS 3 SUCURSALES SE MUESTRE EL INVENTARIO, TAMBIEN REALIZAR UN TRASPASO (SUC 1->SUC 2->SUC 3->MA1[VICEVERSA CONVINADOS]), PREGUNTA: CON LA REPLICACION RESUELVO MI DUDA?
    TRADUCCION EN INGLES (PERDONE SI NO PUEDO TRADUCIRLO (https://translate.google.com.mx))>

    hi good morning. I’m no expert on MySQL, but I like, I have 3 branches (SUC 1 SUC 2 SUC 3) and 1 matrix (MA1) in each store an inventory program (POS) in Java, and MySQL server in each branch . My needs are: IF YOU MAKE A SALE IN SUC 1 (INSERT), YOU POST IN SUC 2 MA1 SUC3 AND IF THE MERCHANDISE ARRIVES IN MA1 (INSERT) THAT ALL 3 BRANCHES INVENTORY SHOWN ALSO MAKE A TRANSFER (SUC 1 -> SUC 2 -> SUC 3 -> MA1 [VICEVERSA CONVINADOS]) QUESTION: REPLICATION TO RESOLVE MY QUESTIONS?
    TRANSLATION IN ENGLISH (FORGIVE IF I can not translate (https://translate.google.com.mx))>

    • andrew says:

      Hi Rafael,

      If I understand you correctly, you want to be able to insert or modify the data in any MySQL server and have the data appear in all of the other MySQL servers. To do that, you could set up a replication ring – where A->B->C-D->A.

      The risk with this approach is that (apart from with MySQL Cluster) MySQL doesn’t contain any conflict detection/resolution functionality and so the data could become inconsistent if you modified the data at A and then again at D before the update from A had replicated around the ring.

      Regards, Andrew.

  12. Pancho says:

    Hi Andrew,

    Firstly, thanks for the awesome video. I’ve been putting together a tree topology and have everything working until i found your video and decided to use the utilities. The account that I use to connect between the master and the two slaves is password protected. Now when I run the following command from the utilities I get the following error “Master connection values invalid or cannot be parsed”.

    mysqlrplshow –master=root:password@localhost:3306 –discover-slaves-login=root:password;

    Any ideas?

    Thanks in advance

    • andrew says:

      As a general rule with MySQL I avoid specifying localhost as there are restrictions around it – try swapping it for 127.0.0.1

      Andrew.

  13. Pancho says:

    I tried with the IP but no luck. I forgot to mention Im using windows server. Is the command still the same?

    Thanks

    • andrew says:

      Pancho,

      commands should be the same on any OS.

      Have you tried connecting with the mysql client from and to the same servers and with the same connect strings and use credentials?

      Andrew.

  14. Wasim says:

    hi i tried the scenario but at the second step i got this error when i write this instruction:

    mysqlrplshow –master=root@utils1;

    mysqlrplshow: error: The –discover-slaves-login is required to test slave conne
    ctivity.
    help plzzzz

    • andrew says:

      Looks like it’s now mandatory to include the –discover-slaves-login=[: ] for the utility to connect to the slaves to discover any nested slaves.

      Andrew.

  15. Frank says:

    Hello Andrew!

    I’am testing mysqlfailover and I think it is a good tool for help all us, but I have a question:

    Hot can I specify a password in the sintaxis?

    Thanks for your help!

  16. Max says:

    Hi Andrew,

    I think there is a type in the following two lines:

    mysqlrplshow –master=root@utils1;

    and

    mysqlrplcheck –master=root@utils1 –slave=root@utils2:3307 –discover-slaves-login=root

    should be replaced with

    mysqlrplshow –master=root@utils1 –discover-slaves-login=root

    and

    mysqlrplcheck –master=root@utils1 –slave=root@utils2:3307

    • andrew says:

      Hi Max,

      you’re correct – the synytax changed since this post was originally written. I’ve now update it.

      Thanks, Andrew.

  17. Harry says:

    Hi all,
    i had configured fail-over in master-slave replication.with the following steps.

    1)keeping master(A) read only(set global read_only=1;)
    2)keeping slave(B) read only off(set global read_only=0;)
    3)stop slave(B) io_thread;
    4)wait until it reads all relay log.
    5)stop slave(B);
    6)reset master(B);
    7)show master status(B);note the binlog pos.
    8)set old master(A) to be slave(change master to master_host=’—’,master_user=’—’,master_password=’—’,master_log_pos=–,master_log_file=’–’;)
    9)start slave(A);
    10)flush tables(A);

    A)steps performed in current master
    B)steps performed in current slave.

    but @ this stage i am facing error:
    slave_io_running: connecting
    slave_sql_running: yes
    Last_IO_Error: error connecting to master

    Could some one help me out @ this stage.

    Thanks a million in advance.

  18. Barni says:

    Hi!

    Very nice tutorial! It helped me a lot!

    But I ran into an issue when trying to make auto-failover work. I execute the mysqlfailover –master=root@utils1:3306 –discover-slaves-login=root –rediscover command but this is the output on the screen:

    mysqlfailover –master=root@DEIBTEMSL004:3306 –discover-slaves-login=root –rediscover
    # Discovering slaves for master at DEIBTEMSL004:3306
    # Checking privileges.
    # WARNING: You may be mixing host names and IP addresses. This may result in negative status reporting if your DNS services do not support reverse name lookup.
    #
    # Failover console will start in 10 seconds.
    # Discovering slaves for master at DEIBTEMSL004:3306
    2013-09-22 17:05:28 PM CRITICAL Query failed. 1193: Unknown system variable ‘GTID_DONE’
    ERROR: Query failed. 1193: Unknown system variable ‘GTID_DONE’

    I’m using MySQL v.5.6.14.

    What could be the problem? All your help is highly appreciated.

  19. Bright says:

    Thanks Andrew! this has really helped me alot. Keep it up.

    One question. If I have an application connected to the master database with all the neccesary IP grants, Do I have to manually re-point my application to the promoted slave or there’s a cleaver way I can achieve this.

    Thanks alot.

  20. regan says:

    Hi andrew, mysqlfailover looks great but I’m also struggling to work out how to redirect traffic to the new (potentially random) ip address of the new master if it’s left to mysqlfailover to automatically choose the best slave of N to promote. How do you automatically get the new master IP address? How do you interface mysqlfailover with a proxy or load balancer sitting in front of the cluster to actually start using the newly promoted master ip? I’ve googled it to death but all the blog posts etc all fail to link the back end with any front end. :|

    • andrew says:

      regan,

      There’s nothing in mysqlfailover to handle switching of the application (e.g. no handling of a virtual IP address) but you do have the option of binding in your own scripts at various points – including when the failover is about to start and again once it has completed. Take a look at the --exec** command-line arguments in the mysqlfailover documentation.

      Regards, Andrew.

  21. Vishal says:

    hi

    Thanks for your post. i tried following the steps mentioned on the site.
    When i use mysqlreplicate, it gave me this error.

    Please help.

    [root@localhost1 ~]# mysqlreplicate –master=root:root@127.0.0.1:3306 –slave=root:root@172.31.1.253:3306 ot:root@172.31.1.253:3306
    # master on 127.0.0.1: … connected.
    # slave on 172.31.1.253: … connected.
    # Checking for binary logging on master…
    # Setting up replication…
    Traceback (most recent call last):
    File “/usr/bin/mysqlreplicate”, line 167, in
    options, opt.test_db)
    File “/usr/lib/python2.6/site-packages/mysql/utilities/command/setup_rpl.py”, line 100, in setup_replication
    if not rpl.setup(rpl_user, 10):
    File “/usr/lib/python2.6/site-packages/mysql/utilities/common/replication.py”, line 633, in setup
    res = self.slave.get_slaves_errors()
    File “/usr/lib/python2.6/site-packages/mysql/utilities/common/replication.py”, line 1483, in get_slaves_errors
    res = self.get_status()
    File “/usr/lib/python2.6/site-packages/mysql/utilities/common/replication.py”, line 1261, in get_status
    return self.exec_query(“SHOW SLAVE STATUS”, col_options)
    File “/usr/lib/python2.6/site-packages/mysql/utilities/common/server.py”, line 924, in exec_query
    cursor_class=mysql.connector.cursor.MySQLCursorBufferedRaw)
    File “/usr/lib/python2.6/site-packages/mysql/connector/connection.py”, line 1154, in cursor
    raise errors.OperationalError(“MySQL Connection not available.”)
    mysql.connector.errors.OperationalError: MySQL Connection not available.
    [root@localhost1 ~]#

    ———————————————————————–
    master server my.cnf file
    ———————————————————————–
    [client]
    port=3306
    socket=/var/lib/mysql/mysql.sock

    [mysqld]
    port=3306
    socket=/var/lib/mysql/mysql.sock
    log-error=’/var/lib/mysql/log_error’
    general_log
    general_log_file=’/var/lib/mysql/log_general’
    slow_query_log
    slow_query_log_file=’/var/lib/mysql/log_slow_query’

    sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
    event_scheduler=ON
    log_bin = myreplication
    binlog-ignore-db = mysql
    binlog-ignore-db = performance_schema
    binlog-ignore-db = information_schema
    binlog_format = mixed
    log-slave-updates=true
    gtid-mode=on
    enforce-gtid-consistency
    master-info-repository=TABLE
    relay-log-info-repository=TABLE
    sync-master-info=1
    datadir=/var/lib/mysql
    report-host=localhost1
    server_id = 1
    report-port=3306
    expire_logs_days=5
    #read_only = 1

    ———————————————————————–
    slave 1 my.cnf file
    ———————————————————————–

    [client]
    port=3306
    socket=/var/lib/mysql/mysql.sock

    [mysqld]
    port=3306
    socket=/var/lib/mysql/mysql.sock
    log-error=’/var/lib/mysql/log_error’
    general_log
    general_log_file=’/var/lib/mysql/log_general’
    slow_query_log
    slow_query_log_file=’/var/lib/mysql/log_slow_query’

    sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
    event_scheduler=ON
    log_bin = myreplication
    binlog-ignore-db = mysql
    binlog-ignore-db = performance_schema
    binlog-ignore-db = information_schema
    binlog_format = mixed
    log-slave-updates=true
    gtid-mode=on
    enforce-gtid-consistency
    master-info-repository=TABLE
    relay-log-info-repository=TABLE
    sync-master-info=1
    datadir=/var/lib/mysql
    report-host=localhost2
    server_id = 2
    report-port=3306
    expire_logs_days=5
    #read_only = 1

    ———————————————————————–
    slave 2 my.cnf file:
    ———————————————————————–

    [client]
    port=3306
    socket=/var/lib/mysql/mysql.sock

    [mysqld]
    port=3306
    socket=/var/lib/mysql/mysql.sock
    log-error=’/var/lib/mysql/log_error’
    general_log
    general_log_file=’/var/lib/mysql/log_general’
    slow_query_log
    slow_query_log_file=’/var/lib/mysql/log_slow_query’

    sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
    event_scheduler=ON
    log_bin = myreplication
    binlog-ignore-db = mysql
    binlog-ignore-db = performance_schema
    binlog-ignore-db = information_schema
    binlog_format = mixed
    log-slave-updates=true
    gtid-mode=on
    enforce-gtid-consistency
    master-info-repository=TABLE
    relay-log-info-repository=TABLE
    sync-master-info=1
    datadir=/var/lib/mysql
    report-host=localhost3
    server_id = 3
    report-port=3306
    expire_logs_days=5
    #read_only = 1

    • andrew says:

      Hi Vishal,

      there seems to be a typo at the end of your command…

      [root@localhost1 ~]# mysqlreplicate –master=root:root@127.0.0.1:3306 –slave=root:root@172.31.1.253:3306 ot:root@172.31.1.253:3306

      Is this what you were attempting…
      mysqlreplicate --master=root:root@127.0.0.1:3306 --slave=root:root@172.31.1.253:3306

      Andrew.

      • Vishal says:

        Hi Andrew

        Ya it was a typo.

        this is what i tried:

        mysqlreplicate –master=root:root@localhost:3306 –slave=root:Itkt123@172.31.1.32:3306 -vvvv

        The error was same as mentioned earlier.
        Please suggest what could have gone wrong.

        Regards
        Vishal Goel
        9540506073

        • andrew says:

          Vishal,

          what version of Utilities and Conector/Python are you using (could be that it’s a bug that’s already been fixed)? Could you also try replacing 127.0.0.1 with localhost in case that makes a difference.

          Andrew.

  22. Chris says:

    after funning mysqlfailover to setup the automatic failover is there an easy way to set that as a windows service or something or do I have to leave a user logged into a system with that running?

    • andrew says:

      You can use the –daemon option so that you don’t need to stay logged in but it’s your responsibility to register it as a service.

      Andrew.

  23. Tomás Senart says:

    I have created an easy to setup Vagrant env to follow this post experimentally: https://github.com/tsenart/mysql56-replication

    Let me know what you think!

  24. Rajith says:

    hi..
    Can any one help me Configuration steps of auto switching/ Fail over by using mysql5.7 in window platforms….
    Is it possible to setup auto switching of dbs in win8 as a master and win 7 as a slave…

  25. Rajith says:

    The steps are not clear to setup Fail over please give the solution for setting up in windows platform instead of unix platform…
    please help me…
    Thank you..

    • andrew says:

      Hi Rajith,

      where do you suspect that the process might be different on Windows?

      Andrew.

      • Rajith says:

        hi Andrew sir…
        Iam actually doing project work on this…
        so please tell me the steps to setup replication and fail over mode or auto switch of databases on windows platform…
        Please help me …
        In advance thank you…

  26. Oliver says:

    Hi Andrew,

    Thanks for the post I appreciate !! I have one simple doubt:

    So in the newer versions (5.6.9+)

    The line on the my.cnf will be changed FROM

    disable-gtid-unsafe-statements=true # Use enforce-gtid-consistency from 5.6.9+
    TO
    enforce-gtid-consistency=true
    or just
    enforce-gtid-consistency

    ?

    Thaks a lot !!!

    • andrew says:

      Correct – although the bevaviour also changed sightly – the old parameter stopped all changes to non-transactional tables (i.e. those using MyISAM) but with the new one it’s only transactions that mix transactional and non-transactional tables that are blocked.

      Andrew.

  27. Rajith says:

    mysqlreplicate –master=root@192.168.1.4:3306 \ –slave=sandeep@192.168.1.7:3306 –rpl-user=sandeep:system -b

    When I execute the above statement in utilities iam getting errors like:
    Error 1045(28000):Access Denied for the user ‘sandeep’@’192.168.1.4′(using password:NO).
    Please help me sir
    Thank you..

    • andrew says:

      Try using --slave=sandeep:system@192.168.1.7:3306 (assuming “system” is the password for sandeep on that mysqld).

      Andrew.

  28. Rajith says:

    Hi sir,,,
    Same Error Iam facing

  29. Rajith says:

    I will give detail steps what i did:
    Iam using 2 laptops master is windows8 and slave is windows7
    Step1:
    I have changed in server section below [mysqld] of my.ini:
    In master(192.168.1.4: password is ‘system’): my.ini:
    innodb_flush_log_at_trx_commit=1
    sync_binlog=1
    binlog-format=ROW
    log-slave-updates=true
    gtid-mode=on
    enforce-gtid-consistency=true
    master-info-repository=TABLE
    relay-log-info-repository=TABLE
    relay-log-recovery=1
    sync-master-info=1
    slave-parallel-workers=2
    binlog-checksum=CRC32
    master-verify-checksum=1
    slave-sql-verify-checksum=1
    binlog-rows-query-log_events=1
    server-id=1
    report-port=3306
    port=3306
    log-bin=mysql-bin.log
    datadir=”C:/ProgramData/MySQL/MySQL Server 5.7/data\”
    socket=mysql
    report-host=localhost
    Step2:
    In slave(ip is 192.168.1.7 password is ‘system’) my.ini:

    innodb_flush_log_at_trx_commit=1
    sync_binlog=1
    binlog-format=ROW
    log-slave-updates=true
    gtid-mode=on
    enforce-gtid-consistency=true
    master-info-repository=TABLE
    relay-log-info-repository=TABLE
    relay-log-recovery=1
    sync-master-info=1
    slave-parallel-workers=2
    binlog-checksum=CRC32
    master-verify-checksum=1
    slave-sql-verify-checksum=1
    binlog-rows-query-log_events=1
    server-id=2
    report-port=3306
    port=3306
    log-bin=mysql-bin.log
    datadir=”C:/ProgramData/MySQL/MySQL Server 5.7/data\”
    socket=mysql
    report-host=localhost

    Step3: restarted both the servers

    Step4: In mysql utilities i executed the follwing:

    mysqlreplicate –master=root@192.168.1.4:3306 \ –slave=sandeep:slave@192.168.1.7:3306 –rpl-user=sandeep:system -b

    output:
    #master 192.168.1.4:….connected…
    #slave 192.168.1.7:..Error:…can’t connected to the slave server…
    Error 1045(28000):Access Denied for the user ‘sandeep’@’192.168.1.4′(using password:YES)

    Help me sir..
    Thank you….

    • andrew says:

      From 192.168.1.4, try running mysql -h 192.168.1.7 -P 3306 -u sandeep -p slave to check that you have the correct password and privs.

      Andrew.

  30. Rajith says:

    mysqluc> mysqlreplicate –master=root:system@127.0.0.1:3306 –slave=root:system@192.168.1.184:3306

    # master on 127.0.0.1: … connected.
    # slave on 192.168.1.184: … connected.
    # Checking for binary logging on master…
    # Setting up replication…
    ERROR: failed to synch slave with master.
    ERROR: Cannot setup replication.

    Execution of utility: ‘mysqlreplicate –aster=root:system@127.0.0.1:3306 –slave=root:system@192.168.1.184:3306′ ended with return code ’1′ but no error message was streamed to the standard error, please review the output from its execution.

    Reply me sir..
    Thank you..

    • andrew says:

      Have you tried connecting to each of these servers using the root/system credentials from the machine running mysqlreplicate utility? If that doesn’t work then you need to grant extra user privs. If not, could you please share the .cnf file for each of the servers?

      Andrew.

  31. MWM says:

    Hi Andrew,

    Nice article. I have a question that MySQL provided the auto failover support with utilities. But is there any possibility that my client connected with master DB would also be able to detect automatically that old-master DB is down and now master DB is one of the slave and connect to it.

    I hope, I delivered my question with clarity.

    Regards
    MWM

    • andrew says:

      I’d suggest taking a look at MySQL Fabric as it will fail over the application to the new master…

      Andrew.

      • MWM says:

        Dear Andrew,

        As mentioned in your article:

        “by default it will select the one that is most up-to-date and then apply any changes that are available on other slaves but not on this one before promoting it to be the new master. The user can override this behaviour (for example by limiting which of the slaves are eligible for promotion)”

        Kindly, tell me the way through which I can limits my slave to become master.

        Regards
        MWM

  32. MWM says:

    I found it:

    we can use –candidates=

    Regards
    MWM

  33. MWM says:

    Dear Andrew,

    MySQL replication utilities support semi-synchronous or asynchronous replication ?

    Regards
    MWM

  34. MWM says:

    Dear Andrew,

    I am Back … :)

    I read your blog again and I found your statement: “Binding in your own scripts to be run before or after the failover (e.g. inform your application to switch master?)”

    Sir, we have –exec-post-failover option to use with failover utility. I will make a script to tell application about the current master. But from where I can get the information that which mysql instance become a new master through mysqlfailover utility.

    Waiting for your positive response.

    Regards
    MWM

  35. MWM says:

    Addition to my previous comment … means i want some variable so that my script should read that variable/information and take decision that this mysql instance is now the new master made by utility.

    Regards
    MWM

    • andrew says:

      If you take a look at Table 5.2 in the mysqlfailover documentation it states that the host and port of the new master will be passed to the script as parameters.

      Regards, Andrew.

      • MWM says:

        Dear Andrew,

        Thank you for the quick response.

        Can you suggest some example to run scripts.

        I made my own script and pass it to –exec-after=/etc/failover.sh with mysqlfailover command but its giving me the results. During failover health monitor shows that script run completed OK.

        Regards
        MWM

  36. MWM says:

    Dear Andrew,

    Skip my all previous comments, because I take another step. :)

    My script was not giving me the results because some commands of my script needs root privileges. I sorted them so now —exec-after run scripts successfully.

    Sir, now I just want your help regarding example of how new master IP and port is passed to the external script.

    Waiting for your positive response.

    Thank you for all your support.

    Regards
    MWM

    • andrew says:

      My assumption is that they are passed as command-line arguments in the order in which they appear in Table 5.2 but I’ve raised a bug report for the documentation to be made more explicit.

      Andrew.

  37. Hi Andrew. I’m wondering if you can help me. I’m trying to set-up a master-slave on a single master and a single slave, on two separate servers (called, embarrassingly C-3PO and BOBAFETT). I’ve used your profile config files (slightly altered as it’s a Windows system) and then issuing the following:

    mysqluc> mysqlreplicate –master=root:PASSWORD@c-3po:3306 –slave=root:PASSWORD@bobafett:3306

    And I get the following output showing a failure:

    # master on c-3po: … connected.
    # slave on bobafett: … connected.
    # Checking for binary logging on master…
    # Setting up replication…
    ERROR: Cannot setup replication.

    Execution of utility: ‘mysqlreplicate –master=root:PASSWORD@c-3po:3306 –slave=root:PASSWORD@bobafett:3306′ ended with return code ’1′ but no error message was streamed to the standard error, please review the output from its execution.

    I’ve granted privileges as described by your instructions and I can connect to the two servers remotely, so I don’t think it’s that.

    Have you any idea what I could have done wrong?

  38. Javier Bautista says:

    Hello Andrew. First of all thank you for your post. It is very useful. I’ve two mysql servers with gtid and mysqlfailover. Everything is working well but I’ve seen that when a master server fails and mysqlfailover has changed to the other server as a master, when I start the old master it is still a master too. Is there any way to the old master autoregister as slave when it comes up?

    Hope you can help me.

    Thank you very much.

    • andrew says:

      Hi Javier,

      what do you mean when you say that the old server starts as a master again? A server is only a master if other servers have connected to it as slaves; the other servers should now be slaves to the new master – are you seeing them revert back to the original master after it has been returned to service? Of course, the old master has binary logging enabled (a prerequisite to being a master) and so if you didn’t need that then you could turn it off in that server’s config file.

      Note that MySQL Fabric is now GA and that may offer a more complete failover solution for you -it’s worth taking a look.

      Best Regards, Andrew.

      • Javier Bautista says:

        Thanks Andrew

        What I mean is when a master is down and mysqlfailover has changed to another master, the old master does not connect as a slave to the new master automatically. Is it possible??

        Thank you again

        • andrew says:

          No automated way of doing that with mysqlfailover; you’ll need to issue the CHANGE MASTER commands or use mysqlreplicate afer recovering the server – there are more options with MySQL Fabric.

          Best Regards, Andrew.

Leave a Reply

Your email address will not be published. Required fields are marked *