Before we go into how to set up master-slave replication in MySQL, let us talk about some of the reasons I have set up master-slave replication using MySQL.
1) Offload some of the queries from one server to another and spread the load: One of the biggest advantages to have master-slave set up in MySQL is to be able to use master for all of the inserts and send some, if not all, select queries to slave. This will most probably speed up your application without having to diving into optimizing all the queries or buying more hardware.
2) Do backups from slave: One of the advantages people overlook is that you can use MySQL slave to do backups from. That way site is not affected at all when doing backups. This becomes a big deal when your database has grown to multiple gigs and every time you do backups using mysqldump, site lags when table locks happen. For some sites, this could mean that site goes down for few secs to minutes. If you have slave, you just take slave out of rotation (should be built into code) and run backups off the slave. You can even stop slave MySQL instance and copy the var folder instead of doing mysqldump.
Ok let us dive into how to setup master-slave replication under MySQL. There are many configuration changes you can do to optimize your MySQL set up. I will just touch on very basic ones to get the replication to work. Here are some assumptions:
Master server ip: 10.0.0.1 Slave server ip: 10.0.0.2 Slave username: slaveuser Slave pw: slavepw Your data directory is: /usr/local/mysql/var/
Put the following in your master my.cnf file under [mysqld] section:
# changes made to do master server-id = 1 relay-log = /usr/local/mysql/var/mysql-relay-bin relay-log-index = /usr/local/mysql/var/mysql-relay-bin.index log-error = /usr/local/mysql/var/mysql.err master-info-file = /usr/local/mysql/var/mysql-master.info relay-log-info-file = /usr/local/mysql/var/mysql-relay-log.info datadir = /usr/local/mysql/var log-bin = /usr/local/mysql/var/mysql-bin # end master
Copy the following to slave’s my.cnf under [mysqld] section:
# changes made to do slave server-id = 2 relay-log = /usr/local/mysql/var/mysql-relay-bin relay-log-index = /usr/local/mysql/var/mysql-relay-bin.index log-error = /usr/local/mysql/var/mysql.err master-info-file = /usr/local/mysql/var/mysql-master.info relay-log-info-file = /usr/local/mysql/var/mysql-relay-log.info datadir = /usr/local/mysql/var # end slave setup
Create user on master:
mysql> grant replication slave on *.* to slaveuser@'10.0.0.2' identified by 'slavepw';
Do a dump of data to move to slave
mysqldump -u root --all-databases --single-transaction --master-data=1 > masterdump.sql
import dump on slave
mysql < masterdump.sql
After dump is imported go in to mysql client by typing mysql. Let us tell the slave which master to connect to and what login/password to use:
mysql> CHANGE MASTER TO MASTER_HOST='10.0.0.1', MASTER_USER='slaveuser', MASTER_PASSWORD='slavepw';
Let us start the slave:
mysql> start slave;
You can check the status of the slave by typing
mysql> show slave status\G
The last row tells you how many seconds its behind the master. Don’t worry if it doesn’t say 0, the number should be going down over time until it catches up with master (at that time it will show Seconds_Behind_Master: 0) If it shows NULL, it could be that slave is not started (you can start by typing: start slave) or it could be that it ran into an error (shows up in Last_errno: and Last_error under show slave status\G).