October 05 2012 · mysql · replication · scalability · tutorial

A Tutorial to set up MySQL replication (master/slave) for high scalability

In this tutorial, we will set up two instances of MySQL on your localhost, one master and one slave and enable data replication between the master and the slave.

There are several options when you want to scale horizontally with a MySQL database including database sharding, using MySQL Cluster with NDB storage or a master/slave setup. You can refer to this link for a more detailed summary. Master/slave will be suitable for your application if it performs a lot of read operations rather than write. So distributing the read operations accross multiple instance will help reduce the load on one master instance and enables scaling out.

Configuration

If you haven't had MySQL, download it from here, untar it and extract to a folder of your choice. Add the bin folder to your PATH if you don't want to specify the full path when invoking the process.

Create the folder for config files and data of master and slave instances:

#!bash
mkdir -vp ~/replication/{master,slave}/{conf,data,log}

Run mysql_install_db script to populate the require mysql schema for each instance:

#!bash
scripts/mysql_install_db --no-defaults --datadir=~/replication/master/data
scripts/mysql_install_db --no-defaults --datadir=~/replication/slave/data

Configure master instance: In ~/replication/master/conf/, create my.cnf:

#!bash
# master my.cnf

[client] 
port    =   3306
socket  =   ~/replication/master/mysqld.sock

[mysqld]
socket  =   ~/replication/master/mysqld.sock
port    =   3306
datadir =   ~/replication/master/data
#basedir: location of your MySQL installation
basedir =   ... 
...

Next, start the master instance using the command:

#!bash
mysqld --defaults-file=~/replication/master/conf/my.cnf

Create replicatedb, after log in using mysql client:

#!bash
mysql> CREATE SCHEMA `replicatedb`;

Populate some table and data for your schema. Next we need to tell the server to use binary log to log change made to this schema. Add the following lines to the my.cnf file, under server section:

#!bash
log-bin =   ~/replication/master/log/mysql-bin.log
binlog-do-db    =   replicatedb
server-id   =   1

Note that the server-id must be unique between master and slaves. If you want replication for multiple schema, use multiple binlog-do-db option. Restart the server.

Create user for replication:

Next create the user which has the REPLICATION SLAVE permission, which slave instances will use to access master data. In mysql client command:

#!mysql
mysql> CREATE USER 'slave'@'127.0.0.1' IDENTIFIED BY `slave`;
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave'@'127.0.0.1';

Obtain replication point

Still in the mysql client console:

#!mysql
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;

Output:

#!mysql
+------------------+----------+------------------+------------------+
| File             | Position | Binlog_Do_DB     | Binlog_Ignore_DB |
+------------------+----------+------------------+------------------+
| mysql-bin.000016 |      106 | replicatedb      |                  |
+------------------+----------+------------------+------------------+

The above commands will lock the master database, preventing any writes to it, and output the current coordinate of binary log. Then we will dump a database snapshot of the master and restore it to the slave instance. If we don't look the database, and new change made to it, there will be inconsistence between the master's data and the snapshot, which leads to a corrupted databases on the slave.

#!bash
mysql -u root -p replicatedb > replicatedb.sql

Setup slave instance

To setup the slave, instance, create a similar configure file as master instance and change the port number to 3307. Enable binlog for slave instance if you want it later to serve as the master to other slave instances (which help reduces the sync requests to a single master). And add the following lines:

#!bash
[mysqld]
...
server-id   =   2
replicate-do-db =   replicatedb

Start slave instance:

#!bash
mysqld --defaults-file=~/replication/slave/conf/my.cnf

Restore the dumped file:

#!bash
mysql -u root -p -h "127.0.0.1" -P 3307 replicatedb < replicatedb.sql

After you has restore the dumped data to slave instance, unlock the table in master instance:

#!mysql
mysql> UNLOCK TABLES;

Then we need to tell the slave instance the username and password it is going to use for replication, the coordinate of the bin log file. Login to slave instance using mysql client, type in the following commands:

#!mysql
mysql> STOP SLAVE;
mysql> CHANGE MASTER TO
        MASTER_HOST='127.0.0.1',
        MASTER_USER='slave',
        MASTER_PASSWORD='slave',
        MASTER_PORT=3306,
        MASTER_LOG_FILE=mysql-bin.000016,
        MASTER_LOG_POS=106;
mysql> START SLAVE;
  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket