Poor Man’s Automated Snapshots for EC2

by on March 9, 2011 · 6 comments

We’ve invested quite some time in our WordPress Micro instance now. It’s definitely past the playing-around, prototype phase, so let’s get some automated backups in place. But, since we already suffered to get the EC2 API Tools installed, the hard part is actually done. Let’s get a couple of weekly cronjobs setup:

bitnami@awo:~$ crontab -l
# m h  dom mon dow   command
12 01 * * 6 /bin/bash /home/bitnami/scripts/createSnapshot.sh >/tmp/createSnapshot.log 2>&1
22 01 * * 6 /bin/bash /home/bitnami/scripts/deleteSnapshots.sh >/tmp/deleteSnapshots.log 2>&1

The time on a EC2 instance defaults to UTC – Greenwich, England.

As with most sysadmin tasks, there’s the right way to make system wide, consistent snapshots (with an XFS based EBS), and the easy way. As we can afford a minute a week with no writes, we take the easy way:

bitnami@awo:$ less /home/bitnami/scripts/createSnapshot.sh
#!/bin/bash
export EC2_PRIVATE_KEY=/home/bitnami/.ec2/pk-*secret*.pem
export EC2_CERT=/home/bitnami/.ec2/cert-*secret*.pem
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk/jre
sudo /opt/bitnami/ctlscript.sh stop mysql
ec2addsnap vol-96268afe -d "Weekly backup"
sleep 30
sudo /opt/bitnami/ctlscript.sh start mysql

The stop mysql is the uncool portion of this script. But, not doing this might give you a corrupt database snapshot (which you wouldn’t even learn about until after disaster struck). So, for the time it takes ec2addsnap to do its thing, database writes will fail. The time we’ve scheduled this means those writes are user comments. The sleep 30 is also little league. Better would be to capture the snapshot ID from the ec2addsnap command and wait for status ‘completed’ – check the bottom of that post for some starter code.

Cleaning up EC2 snapshots

Running a backup once a week creates ~52 snapshots a year – not too bad. If you decide to run daily (or even hourly), these snapshots will pile up quickly.

bitnami@awo:$ less /home/bitnami/scripts/deleteSnapshots.sh
#!/bin/bash
export EC2_PRIVATE_KEY=/home/bitnami/.ec2/pk-*secret*.pem
export EC2_CERT=/home/bitnami/.ec2/cert-*secret*.pem
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk/jre
ec2-describe-snapshots | sort -r -k 5 | grep "Weekly backup" | sed 1,6d | awk '{print "Deleting snapshot: " $2}; system("ec2-delete-snapshot " $2)'

The sort -r -k 5 gives us descending sort by snapshot date, and the sed 1,6d skips the first 6 in the list so that ec2-delete-snapshot gets called on the 7th (and oldest) snapshot. Naturally, you only want to delete your “Weekly backups”, thus the corresponding grep.

I hope you’re having fun running your own instance in the cloud. The fact that Amazon gives this to us for nothing for an entire year just convinces me more of the marketing genius employed there. After a year of this “geek crack”, who could possibly go cold turkey?

Professional Grade Virtual Computing for “Free”

Did you enjoy this article? Get new articles for free by email:

Comments

  1. TS says

    This seems pretty cool and a lot easier than the other EC2 backup methods out there. Could you post the source to those files?

  2. says

    The source listed on the above scripts is copy/pasteable – just highlight the text inside the grey boxes, Ctrl-C & Ctrl-V into your favorite text editor.
    If you’re referring to Bitnami’s ctlscript.sh, just check out the source at /opt/bitnami/ctlscript.sh of your install.

  3. says

    If you don’t like the idea of stopping mysql during the backup…

    Rather than stopping mysql while running the snapshot, you can use mysqldump to capture a dump of your database(s) before running the snapshot; the dump will be intact even if your database files are captured in an inconsistent state. And by the way, even if that happens, it’s highly unlikely that mysql won’t be able to recover.

    You can also use mysqlbackup to take an incremental backup right before you take the snapshot; this will be faster and take up less disk space than doing a full mysqldump, but it’s only worth the trouble if you have a really larger database.

  4. says

    the $2 variable does not seem to send the correct format for the snapshot id’s here is what i get

    Client.InvalidParameterValue: Value (0-2) for parameter snapshotId is invalid. Expected: ‘snap-…’.

    during the initialization it displays in fact the correct snapshot id’s and finds them weird.