We recently upgraded our servers from old XServe G5’s running Tiger to the latest greatest running Snow Leopard. In this small howto I will deal with the procedure I followed to setup mysql master-slave replication between two new servers. I start out with two (master, slave) empty DB’s, setup the replication and then import my data from a third server (my old G5 X-Serve). Of course like anything else I will try to show you how to get out of — what I like to call — Steve Jobs Hell Holes :-). There are other ways of doing this procedure, for more info check out this page.
– First things first….the magic command that stops mysql server from command line, just in case you screw something up and need to restart (This should be used on your master and slave servers prior to them going live…..DO NOT USE THIS ON A LIVE SERVER):
sudo launchctl unload /System/Library/LaunchDaemons/org.mysql.mysqld.plist
This will stop the launch Daemon from continously launching mysql when trouble is brewing. This usually happens when you screw something up badly and the symptom is that the Server Manager Status for MySQL will say “Starting up“, but never changes to “Running“.
– Next I want to blow away my DB files on the master and slave (remember these are NOT production servers yet…..I’m still rebuilding them. You DO NOT want to remove the DB’s on your production servers). You’ll need to find the path in the “Settings” tab of the server manager, under “Database Location“. I removed everything in that directory (rm -rf *) from the command line. AGAIN, I CAN NOT STRESS THIS ENOUGH, BE CAREFUL WHERE YOU ISSUE THESE COMMANDS.
– I did this on both the master and the slave.
– Now on the Master change the following in /etc/my.cnf (You should have this file, if you’ve got a my.cnf.default, copy it my.cnf).
[mysqld] log-bin=mysql-bin server-id=1 innodb_flush_log_at_trx_commit=1 sync_binlog=1
– On the Master still, check the “Allow Network Connections” check box in Server Manager and set the root password (for mysql) by pressing the “Set MySQL Root Password…” button. Then press “Save” followed by “Start MySQL“. This will initialize mysql with the default tables and setup the root password.
– Now on the Slave change the following in /etc/my.cnf (You should have this file, if you’ve got a my.cnf.default, copy it my.cnf).
[mysqld] log-bin=mysql-bin server-id=2
– Back on the Master, you need to create a user (I call it repl) that has REPLICATION SLAVE privilege. Use the following two commands (make sure you replace mydomain.com and slavepass….LEAVE repl as the userid:
mysql> CREATE USER 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass'; mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%.mydomain.com';
– Next we need to flush the tables and issue a read lock (yes, just because we can):
mysql> FLUSH TABLES WITH READ LOCK;
– Still on the master we find out the current binary log file name and position:
mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000004 | 340 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
Note down the filename and the Position number. We will need them later.
– Back on the Slave, go to Server Manager and set the root password (for mysql) by pressing the “Set MySQL Root Password…” button. Then press “Save” followed by “Start MySQL“. Connect to the DB as root and issue the following command:
CHANGE MASTER TO MASTER_HOST='master.mydomain.com', MASTER_USER='repl', MASTER_PASSWORD='slavepass', MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=340;
This will setup the slave to talk to the Master and do it’s thing. While we are here, we might as well verify that the repl user can log into the master from the slave:
mysql -h maste.mydomain.com -u repl -p
should prompt you for password and if you type in the ‘slavepass’ you assigned above, you should be able to get in.
– Back on the master unlock the tables:
mysql> UNLOCK TABLES;
– Last but not least on the slave, turn on the slave mode:
mysql> START SLAVE;
Done…..Now you can go to your production server and suck it’s brains (ahemm…..DB’s) out and import it into your master. Your slave should follow and replicate whatever you import into the master Server. I used the following command (you mileage might/will vary):
mysqldump -x -c --add-drop-table --add-drop-database -u root -p --databases dbname1 dbname2 dbname3 >goodies.sql
Transfer “goodies.sql” text file from your production server to the master server (ssh/scp/ftp….whatever).
mysql -u root -p < goodies.sql