MySQL Database Replication HowTo

This tutorial describes how to set up database replication in MySQL. MySQL replication allows you to have an exact copy of a database from a master server on another server (slave), and all updates to the database on the master server are immediately replicated to the database on the slave server so that both databases are in sync. This is not a backup policy because an accidentally issued DELETE command will also be carried out on the slave; but replication can help protect against hardware failures though.

In this tutorial I will show how to replicate the database ‘testDb’ from the master with the IP address 10.0.2.63 to a slave. both systems (master and slave) are running CentOS 5 ; however, the configuration should apply to almost all distributions with little or no modification.

Both systems have MySQL installed, and the database testDb with tables and data is already existing on the master, but not on the slave.

I want to say first that this is not the only way of setting up such a system. There are many ways of achieving this goal but this is the way I took. I do not issue any guarantee that this will work for you!

1 Configure The Master

First we have to edit /etc/my.cnf. We have to enable networking for MySQL, and MySQL should listen on all IP addresses, therefore we comment out these lines (if existant):

    #skip-networking
    #bind-address            = 127.0.0.1

Furthermore we have to tell MySQL for which database it should write logs (these logs are used by the slave to see what has changed on the master), which log file it should use, and we have to specify that this MySQL server is the master. We want to replicate the database testDb, so we put the following lines into /etc/my.cnf:

    log-bin = mysql-bin
    binlog-do-db=testDb
    server-id=1

Then we restart MySQL:

    service mysqld restart

Then we log into the MySQL database as root and create a user with replication privileges:

    mysql -u root -p
    Enter password:

Now we are on the MySQL shell.

GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%' IDENTIFIED BY 'some_password';
(Replace some_password with a real password!)
FLUSH PRIVILEGES;

Next (still on the MySQL shell) do this:

    USE testDb;
    FLUSH TABLES WITH READ LOCK;
    SHOW MASTER STATUS;

The last command will show something like this:

    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000001 |  4828380 | testDb       |                  |
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)

Write down this information, we will need it later on the slave!

Then leave the MySQL shell:

    quit;

There are two possibilities to get the existing tables and data from testDb from the master to the slave. The first one is to make a database dump, the second one is to use the LOAD DATA FROM MASTER; command on the slave. The latter has the disadvantage the the database on the master will be locked during this operation, so if you have a large database on a high-traffic production system, this is not what you want, and I recommend to follow the first method in this case. However, the latter method is very fast, so I will describe both here.

If you want to follow the first method, then do this:

mysqldump -u root -psome_password --opt testDb > testDb.sql
(Replace some_password with the real password for the MySQL user root! Important: There is no space between -p and some_password!)

This will create an SQL dump of testDb in the file testDb.sql. Transfer this file to your slave server!

If you want to go the LOAD DATA FROM MASTER; way then there is nothing you must do right now.

Finally we have to unlock the tables in testDb:

    mysql -u root -p
    Enter password:
    UNLOCK TABLES;
    quit;

Now the configuration on the master is finished. On to the slave…

2 Configure The Slave

On the slave we first have to create the database testDb:

    mysql -u root -p
    Enter password:
    CREATE DATABASE testDb;
    quit;

If you have made an SQL dump of testDb on the master and have transferred it to the slave, then it is time now to import the SQL dump into our newly created testDb on the slave:

mysql -u root -psome_password testDb < /path/to/testDb.sql
(Replace some_password with the real password for the MySQL user root! Important: There is no space between -p and some_password!)

If you want to go the LOAD DATA FROM MASTER; way then there is nothing you must do right now.

Now we have to tell MySQL on the slave that it is the slave, that the master is 10.0.2.63, and that the master database to watch is testDb. Therefore we add the following lines to /etc/my.cnf:

    server-id=2
    master-host=10.0.2.63
    master-user=slave_user
    master-password=secret
    master-connect-retry=60
    replicate-do-db=testDb

Then we restart MySQL:

    service mysqld start

If you have not imported the master testDb with the help of an SQL dump, but want to go the LOAD DATA FROM MASTER; way, then it is time for you now to get the data from the master testDb:

    mysql -u root -p
    Enter password:
    LOAD DATA FROM MASTER;
    quit;

If you have phpMyAdmin installed on the slave you can now check if all tables/data from the master testDb is also available on the slave testDb.

Finally, we must do this:

    mysql -u root -p
    Enter password:
    SLAVE STOP;

In the next command (still on the MySQL shell) you have to replace the values appropriately:

    CHANGE MASTER TO MASTER_HOST='10.0.2.63', MASTER_USER='slave_user', MASTER_PASSWORD='some_password', 
    MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=4828380;

        * MASTER_HOST is the IP address or hostname of the master (in this example it is 10.0.2.63).
        * MASTER_USER is the user we granted replication privileges on the master.
        * MASTER_PASSWORD is the password of MASTER_USER on the master.
        * MASTER_LOG_FILE is the file MySQL gave back when you ran SHOW MASTER STATUS; on the master.
        * MASTER_LOG_POS is the position MySQL gave back when you ran SHOW MASTER STATUS; on the master.

Now all that is left to do is start the slave. Still on the MySQL shell we run

    START SLAVE;
    quit;

That’s it! Now whenever testDb is updated on the master, all changes will be replicated to testDb on the slave. Test it!

2 Comments

Leave a Reply

Your email address will not be published.


*


CommentLuv badge