Greetings!
Yesterday I got the opportunity to meet Eric Sandall and have a brief conversation as we walked to and from the LUG room to reconnect the server(s) there (which I had dropped off the network a couple days ago. Heh. Heh.) Anyway, we got to geeking pretty quickly, and among other things, the subject of high-availability clustering and MySQL replication under Linux came up. I mentioned that I was using keepalived in a two-node cluster that among other things was running MySQL in a dual-master set-up. He said he didn't know how to set up MySQL this way, so I offered to make an addition to the LUG site with the procedure I followed to set it up.
I keep notes on everything I do with regard to systems administration in my job here as the Information Systems Coordinator for the College of Engineering and Architecture here at WSU. (And as a side note to all you sysadmin types-- if you aren't writing down everything you do when setting up or configuring a system, why aren't you? Having worked many sysadmin jobs, I can tell you the thing that most drives me nuts about a new environment is discovering a bunch of machines nobody knows what to do with because my predecessor couldn't be bothered to write anything down. If you want to keep your job for a long time and add more value to the company you're working for, write everything down. Yes, it takes a little more time when doing installs or maintenance, but you'll save yourself days of work when you are either forced to troubleshoot a nasty problem with your network, or required to do a 'fresh install' of some component of your network. I currently use a Subversion repository to document my systems, and am slowly moving a lot of the "higher level documentation" over to a wiki.)
Anyway, rant aside, here are the notes I took last year when setting up the MySQL dual-master relationship I use right now. Of course, you'll want to change your usernames / hostnames / passwords / etc. when setting this up for your own environment.
My environment is two machines running Fedora Core 5, one of which is a Pentium IV box, the other is an Athlon-64.
# $Id: mysql-replication 335 2005-10-13 19:46:20Z sbalukoff $ # To set up bi-directional mysql replication: # For the purposes of this document, we have two servers which will in the # end be filling a co-master type relationship. However, since when you set up # this replication there will probably be one machine with all the data on it # that needs to be brought into sync with the other machine, the machine # with all the data will be considered the 'master', and the one being brought # into the relationship will be considered the 'slave'. Again, don't let # the names fool you: We're only using 'master' and 'slave' here to # differentiate the machines. In the end they will be in a true co-master # relationship. # Before you begin: # # Make sure that /etc/my.cnf is set to have binary and relay logging turned on # on both the slave and the master. (Verify the log files actually exist if # they weren't set up with this, you will need to restart the server process once # the config file has been changed.) Pertinent config lines should look like: # # # This stuff is needed for replication purposes # server-id=2 # log-bin=/var/lib/mysql/master-bin.log # log-bin-index = /var/lib/mysql/master-log-bin.index # log-error = /var/lib/mysql/master-error.log # # relay-log = /var/lib/mysql/slave-relay.log # relay-log-info-file = /var/lib/mysql/slave-relay-log.info # relay-log-index = /var/lib/mysql/slave-relay-log.index # # In the above, the master and slave must have different server-id's. # Make sure these machines' firewalls are set up to allow them talk to each # other on tcp port 3306, or wherever your mysql daemon is listening. # Set up the replication user on the master: # sudo mysql -u root -p mysql> GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%.cea.wsu.edu' IDENTIFIED BY 'replication_password'; mysql> GRANT REPLICATION CLIENT ON *.* TO 'replicator'@'%.cea.wsu.edu'; mysql> GRANT SUPER ON *.* TO 'replicator'@'%.cea.wsu.edu'; mysql> GRANT RELOAD ON *.* TO 'replicator'@'%.cea.wsu.edu'; mysql> GRANT SELECT ON *.* TO 'replicator'@'%.cea.wsu.edu'; # Get a clean snapshot of the master's data: mysql> FLUSH TABLES WITH READ LOCK; # On the shell: sudo tar cvf /tmp/mysql.bak /var/lib/mysql # on my mysql prompt: mysql> SHOW MASTER STATUS; # Take note of what is said! You'll need to enter the log file name and position later on. mysql> UNLOCK TABLES; # Copy the snapshot to the slave, and slurp it into the database: scp /tmp/mysql.bak user@slave-server:/tmp # on the slave sudo /etc/init.d/mysqld stop cd / sudo tar xvf /tmp/mysql.bak sudo /etc/init.d/mysqld start # Start replication from master to slave: # on the slave's mysql command line as root: mysql> CHANGE MASTER TO MASTER_HOST='master_host_name', -> MASTER_USER='replicator', -> MASTER_PASSWORD='replication_password', -> MASTER_LOG_FILE='recorded_log_file_name', -> MASTER_LOG_POS=recorded_log_position; mysql> START SLAVE; # Test the replication by creating a dummy table on the master... it should be # created on the slave # On the master: mysql> USE test; mysql> CREATE TABLE foo (id INT); # On the slave; mysql> USE test; mysql> SHOW TABLES; # you should see the 'foo' table, eh. # Start replication from slave to master: # First, ensure that no updates are being made to the slave, by ensuring # that no clients are connected to it, eh. Do this however you see fit. # Shutting down any local clients and adding firewall rules to prevent anyone but # the master from connecting should do it. Updates to the master can continue while # you do this. # Get the 'master' status from the slave: # on the slave's mysql console: mysql> SHOW MASTER STATUS; # Make note of what you see! Again, gonna need that logfile and position in the next step... # Add the replication configuration to the master. # On the master's mysql command line as root: mysql> CHANGE MASTER TO MASTER_HOST='slave_host_name', -> MASTER_USER='replicator', -> MASTER_PASSWORD='replication_password', -> MASTER_LOG_FILE='recorded_log_file_name', -> MASTER_LOG_POS=recorded_log_position; # Start replication on the master: # on the master: mysql> START SLAVE; # Test bi-directional data flow by creating something on one server, and # deleting it on the other, eh. (Or just delete that 'foo' table we made # earlier.) # Slave: mysql> use test; mysql> drop table foo; # Master: mysql> use test; mysql> SHOW TABLES; # Test restarting each server individually, and then together # to ensure there are no errors that show up in the logs when you do this. # Be sure the check out the output of the following, on both master and slave: mysql> SHOW SLAVE STATUS \G # If you don't see the following in the list on both systems, you've got problems: # Slave_IO_Running: Yes # Slave_SQL_Running: Yes # Enjoy the glow!
Other things to note:
mysql meta-database-- which the replication system kind of choked on.) Always do a backup before you do this kind of thing. ;)SHOW SLAVE STATUS \G command to ensure that the machines keep in synch. Reboots and long outages of one machine or the other shouldn't screw things up, but it's good to monitor this, just in case.And... that's it. If y'all found this helpful, please let me know; I'd be happy to share some of my other notes from stuff I've done in my position here at WSU or at my former jobs. Some of the things I could talk about include:
keepalivedAnyway, feedback is appreciated, guys and gals!
Comments
Re: Dual-master MySQL replication setup
http://www.onlamp.com/pub/a/onlamp/2006/04/20/advanced-mysql-replication...
Talks in detail about the issues mentioned here.
Re: Dual-master MySQL replication setup
This is extremely interesting. My programmers and I were just discussing this for a client's site. They referred me to read this post. I'm impressed.
James
I don't think this
I don't think this configuration is reliable in production environment. You cannot guarantee an updating operation issued on 'master' would be successfully re-executed while a conflicting one is submitted almost simutaneously on 'slave'
You're right!
Today I got an interesting message in my inbox from Keith Freedman which made suggestions about the above tutorial which would make the set-up a lot more robust in a dual-master relationship where both masters are receiving updates from clients.
To be honest, I'd totally forgotten that I'd made this tutorial and was surprised people were still reading it and drawing on it as a source of information for doing dual-master mysql replication set-ups. (And then I noticed google currently has it as the top-listed page for those search terms. Thank you google! ;o.o )
Anyway, one thing I know I didn't make very clear in the above instructions was that for the environment I was working with at the time, I knew I would be connecting clients to a virtual IP (controlled by keepalived), and therefore there would only ever be one server in this set up receiving updates from the clients at any given time. The point of the dual-master in my case was for availability, not for performance.
Having said that, I do want to say there are couple major problems with the above tutorial if you do intend to have an environment where both masters might be receiving updates from the clients simultaneously. Kieth put it well in his e-mail so I'll just quote that here:
In summary, if you want to avoid problems with a dual-master set up you need to:
1. Avoid creating a ticking-time bomb with autoincrement. If you don't add lines like auto_increment_increment=(number of servers) and auto_increment_offset=(this server number) eventually you'll get both servers trying to insert a row into a table with the same unique, auto_incremented field, replication will stop, and you'll have a mess to clean up when you notice it sometime after that. (And honestly, even in my set-up where I don't anticipate clients ever updating both servers simultaneously, I should have done this from the get go.)
2. Make sure your application is coded in such away that out-of-sync updates to a given field are handled gracefully. As Kieth pointed out, probably the best way to do this is to let the database do the math based on current values in the field.
I should also note that my applications currently do not use some of the more advanced features in the latest versions of MySQL (like transaction roll-backs), so I have no idea how these things might operate in a dual-master environment. As usual, YMMV. But please let us know if you *do* know how these things work in a dual-master environment.
One last note: Since I don't regularly monitor this entry, if you wish to contact me, please feel free to send an e-mail to: stephen@balukoff.com
Thanks!
-Stephen
Star Like multi server set-up
Hi Stephen,
do you have configured star like configuration of multiple MYSQL server. Say i have main server as my center server and 5 slaves that access & updates the main server consequently so that all the slaves have the same data as the main server.
hope to hear from the soonest. Thank you very much.
Edmark Anthony R. Nengasca
earnengasca@yahoo.com
I've never set up a
I've never set up a star-like configuration myself, no. Sorry!
amazing!
i found this really intresting and hope you dont mind that i duplicated it on the http://anonet.org wiki as it is what i have been looking for.
one thing to note is that when you have the servers split apart and an update is made to a table that uses an autoincrement field the minute the servers are reconnected you'll be presented with problems
thanks
mrp
Nope, I don't mind! But
Nope, I don't mind! But please do add the notes about auto_increment and intelligent coding of the client application as detailed in a comment above (however you see fit).
totally great !!
just what i am looking for quiet sometime... it fill all the gaps im working on with out system here... it really helps..
you have mention about other server details i hoping you can post it soon.
thank a lot for sharing your good ideas....
doki rusiana
my_doki@yahoo.com
davao doctor hospital
philippines
Wow just what I needed
This was just what I needed, now I think I can have a crack at this. It amazes me how sometimes the people who actually make these products can't show decent examples.
Any chance of reading your notes about :
Linux high-availability using keepalived
Thanks again
keepalived
where can we find the keepalived tutorial? =-)
Thanks a lot, very helpful
Very Useful
Thanks for that, its fillied in some of the gaps I was stumbling on.
Here here for documentation, we currently use druapl for an internal-sysadmin documentation site and its so very valuable.
Thanks Stephen (this is
Thanks Stephen (this is Eric ;))! I'll be sure to try these out on some of our extra computers as I have time (others in the LUG are welcome to play with them as well to help set this up).
Very Nice
Nice info, I currently do one way mysql replication and will likely be wanting to turn that into bi-directional replication in the future, I'll be sure to check this out for refrence. Some of the other topics you mentioned that I'd be very interested in hearing about are keepalive, Linux VPNs, and advanced cacti usage.
D'oh!
Forgot to mention: After all those
GRANTcommands you'll want to run aFLUSH PRIVILEGES;. (Sometimes I forget to write that sort of thing down because it's second-nature at this point. :P)Correction...
Just so everyone knows...you do NOT need to
flush privilegeswhen you have usedGRANT.Really? Huh... in my
Really? Huh... in my experience, I've always had problems using the privileges granted using a GRANT statement until I run a flush privileges.
Maybe this is a bug they've fixed in more recent versions of MySQL.
Re: Really? Huh... in my
Grant and flush never caused me no problems, you sure you aren't the only one having this problem ? IMHO sql can cause a lot of probs. but if you figure them out then you have nothing to be affraid of.