Article / January 6, 2009

Running MySQL on your Amazon EBS volume with RightScale

EBS (elastic block storage) is one of Amazon's newer innovations. It essentially offers the user a virtual hard drive of 1GB up to 1TB that can be mounted to any EC2 instance. There are several benefits to such a service, including replication of data (handled by Amazon) as well as the ability to snapshot a volume at any point in time and shoot it up to S3 (handled by the user). It is the latter benefit that interested me the most, and the reason it makes a lot of sense to store your db on this mounted volume.

Getting Setup

Here at ELC we are big supporters of RightScale™ so this tutorial will be driven with that in mind. To start off I simply created a new EC2 instance equipped with Nginx and Mongrel, and setup a very simple Rails app with one table (blobs) just to show the db was working properly.

F8b365b9fc07c2288e2b5fc9d0d1842e5a70f20e_1231264220_0

Ok great, now we have our working Rails app and MySQL database running on EC2

Configuring the EBS Volume

RightScale™ makes it quite easy to create and attach an EBS volume to your instance. Simply click on the Volumes tab, E5d2f1af3cdba0b35e990e1c13b1a8e400874926_1231264220_1 then Create and Attach Volume. 2ec822c058af1bfe60ea388df06fc97acb0eb64c_1231264221_2 Choose a name and a size for it and click create, and in just a few minutes, we can see that the volume has been created at /dev/sdj:

[dlabare@domU-12-31-38-00-2D-82:/dev] ls -la
...
brw-r-----  1 root    disk   8,   3 Jan  5 12:50 sda3
brw-r-----  1 root    disk   8, 144 Jan  5 15:01 sdj
drwxr-xr-x  2 root    root       40 Jan  5 12:50 shm
...

Now let's format it.

[dlabare@domU-12-31-38-00-2D-82:/dev] sudo /sbin/mkfs.ext3 /dev/sdj 
mke2fs 1.39 (29-May-2006)
/dev/sdj is entire device, not just one partition!
Proceed anyway? (y,n) y
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
6553600 inodes, 13107200 blocks
655360 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
400 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000, 7962624, 11239424

Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 34 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

Great, now we've got our drive, let's mount it.

[dlabare@domU-12-31-38-00-2D-82:/dev] sudo mkdir /mnt/ebs
[dlabare@domU-12-31-38-00-2D-82:/dev] sudo mount /dev/sdj /mnt/ebs
[dlabare@domU-12-31-38-00-2D-82:/dev] df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda1             10320888   2080172   7716380  22% /
/dev/sda2            153899044    252388 145829032   1% /mnt
/dev/sdj              51606140    184272  48800428   1% /mnt/ebs

Cool, now we've got our EBS volume located at /mnt/ebs (it's only 50 gigs for demo purposes, you'd probably choose a larger size for anything serious)

MySQL Config

First thing to do is stop mysql for now

[dlabare@domU-12-31-38-00-2D-82:/mnt/ebs] sudo /etc/init.d/mysqld stop
Stopping MySQL:                                            [  OK  ]

Now let's move over the database files onto the EBS volume

sudo mkdir /mnt/ebs/lib /mnt/ebs/log
sudo mv /var/lib/mysql /mnt/ebs/lib/
sudo mv /var/log/mysql* /mnt/ebs/log/

Then we need to tell MySQL about where to find these files. Edit your /etc/my.cnf file to point to the correct locations.

[client]
#password       = your_password
#port           = 3306
socket          = /mnt/ebs/lib/mysql/mysql.sock

[mysqld]
datadir=/mnt/ebs/lib/mysql
socket=/mnt/ebs/lib/mysql/mysql.sock
...

##Inno DB
innodb_data_home_dir = /mnt/ebs/lib/mysql/
innodb_log_group_home_dir = /mnt/ebs/lib/mysql
innodb_log_arch_dir = /mnt/ebs/lib/mysql
...

[mysql.server]
user=mysql
basedir=/mnt/ebs/lib

[mysqld_safe]
log-error=/mnt/ebs/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

...

Now go ahead and restart mysql:

[dlabare@domU-12-31-38-00-2D-82:/mnt/ebs] sudo /etc/init.d/mysqld start
Starting mysqld daemon with databases from /mnt/ebs/lib/mysql
Starting MySQL:                                            [  OK  ]

Great, it worked*. Now save this config file to your EBS volume so it doesn't get lost if your instance crashes.

*crap, it didn't work? Check your mysql logs for more info (/mnt/ebs/logs/mysqld.log)

sudo cp /etc/my.cnf /mnt/ebs/my.cnf-bak

Volume Snapshots

You can manually take snapshots of your volume through the RightScale™ interface when needed, as well as have a cron job run back ups periodically. Eric Hammond has written a nice little backup script that that uses EC2 API tools, the script can be found here.

You can also read his detailed post on how to do this whole setup using the command line tools, which was a great help for me when getting setup.

Why this is a good thing

There are many good reasons to try this method of deployment:

  • Easily bump up (or down) your instance size without having to copy your database each time. Simply mount the volume to your new instance, copy over your mysql config, and you're good to go.
  • Rest assured knowing your snapshot data is backed up in multiple geographic locations
  • Know that your database storage is unaffected by your instance failing
  • Grow your volume size easily when space gets low

Comments

Posted by marc on about 1 year ago46f61a8a15c5e234ad416b590a2676c9?s=30

There is one step which i am still not getting.
With a simple webapp, i’ll have some log, the webapp itself (maybe rails, maybe php), and my database

so i’d probably setup maybe 2 ebs volumes (webapp+logs and database).
then i’d copy my database and webapp to the volumes, create symlinks (or change the config), tweak the config of my instance, upload my ssl keys for the webserver and so on….

but… when i stop/restart my instance i have persitance logs, webapp and database… but still my whole config is gone, my ssl keys are gone… shouldn’t there be a way to store the main volume itself on ebs or am i missing something?

looking forward for clarification

Posted by Rajesh Avula on 8 months agoEc21e5565f184952f300073ae0b75de2?s=30

Hello Mr.

After changing all your updations on your instance...you have to make latest AMI of that instance then only your data will remain forever.

As per amazon technology when you stop/restarted instance...while booting it will collect all the data from AMI only..so please make sure your AMI must with updated data.

Still you have any queries send a mail to my mail id...

Do Well..Good Luck

Rajesh.avula
Sr. Linux Admin
9819611577

Posted by hoparius on 6 months ago46f61a8a15c5e234ad416b590a2676c9?s=30

Rajesh, mark my words: computers are not your thing.
You just have to trust me on that one for now.

To the author: good article. One more thing. Some default mysql setups tend to store relay logs in /var/run/mysqld, so that folder needs to be taken care of as well (either via my.cfg or same as data dir above).

Posted by Chris W on 6 months ago11a9cd502b8970e857acffd6bdf348d6?s=30

I am on centos and I wanted the service to start automatically. So I had to modify /etc/init.d/mydqld
My ebs volume is /mnt/ebs50

[client]
socket = /mnt/ebs50/mysql/lib/mysql/mysql.sock

[mysqld]
datadir=/mnt/ebs50/mysql/lib/mysql
socket=/mnt/ebs50/mysql/lib/mysql/mysql.sock
user=mysql
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1

[mysqld_safe]
log-error=/mnt/ebs50/mysql/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

Add a Comment