Colin McCann Dot Com

Automated off-site MySQL backups with cron and PHP

Posted on February 7, 2010 at 1:20 am

I am the technical administrator for a decently sized vBulletin forum that is hosted on a system offering a lot of performance at the cost of some storage space. I also have hosting and a number of domains on a system that offers less performance, but ridiculous amounts of bandwidth and storage. Lastly, I have a strong need for peace of mind, and off-site database backups seem like a nice way of getting a bit of that back.

The following script is run by this cron job:

This script only does a few things. First, it creates a ‘filename’ variable consisting of ‘database_’ and then the date. Next it runs mysqldump on the database in question, outputting to /backup/$filename.sql. It sleeps for a bit (gzip didn’t seem to want to work immediately) and then compresses the .sql file into a more manageable size. From there, it opens a connection to an off-site server where I’ve got a ton of storage and bandwidth, and uses a server-to-server connection to transfer this gigantic file in a few minutes. Once that’s complete, it removes the file it created and waits until 3:30 the next morning to do it all over again.

To get the scp command to work without user input, you have to add the RSA key fingerprint to the list of known hosts. You can do this manually by editing the appropriate file, or you can do it the easy way: Open a terminal and SSH into your web server, and from that session, SSH into your backup server. You will get a warning claiming that “the authenticity of host … can’t be established — are you sure you want to continue connecting?”. Type “yes” and hit enter, and you will see a warning stating that this RSA key was added to the list of known hosts.

When your database backup is a 450MB file, you’ll find that space starts filling up quickly and the directory starts becoming needlessly cluttered. So again, we turn to crontab:

…which dutifully executes the following cleanup script. This scans a directory for all files but itself, checks their ‘last-modified’ date against the current date and if it’s more than 7 days old, deletes them. This ensures that I’ve always got the most recent week’s worth of backups.

So, that’s it. Automated off-site MySQL backups using cron and PHP. Enjoy the peace of mind.

Code
7 comments for this entry:
  1. John
    I know its a pedantic optimization, but shouldn't be ?
  2. admin
    That would certainly work. However, it's been my experience that a little bit of processing power (in this case, very little) is a good tradeoff for extended readability. This thing only runs once a day :)
  3. John
    Okay, so before I continue this argument, I want to acknowledge that we're arguing pointless optimizations here that won't add to actual performance in any significant way... How about:
  4. Travis
    What about the need to turn the site off before the backup taken? Or lock the tables then unlock them when the dump is done? mysql> FLUSH TABLES WITH READ LOCK; mysql> UNLOCK TABLES; I'm new to this so be easy on me.
  5. admin
    @Travis: That is probably a really good idea, especially once your database starts increasing in size and taking longer to dump. One of these days I'll get around to updating the script :)
  6. Travis
    @admin: I've done some more digging and it looks like mysqldump already takes care of locking and unlocking tables. http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html Like I said, I'm new to this, so maybe I didn't read that right, but that's what I got out it..
  7. admin
    @Travis -- thanks for looking into that!

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...