July 19, 2007

Linux Web & Database Backups

Just yesterday, I ran into a situation where a client’s data needed to be reverted back to last week. Luckily, I make a daily backup of all MySQL data files and archive them. I thought I would share my backup recipe with other Linux users.

To start, I’ve created a backup folder, the contents of which are two other folders called bin and db_backup.

backup
..bin
..db_backup

bin holds the backup scripts while db_backup holds all daily database backups. The backup folder itself will hold all web files, which are backed up far less often than the database files as changes are minimal.

The bin folder holds two shell scripts:

  • backup.sh (backup web files)
  • db-backup.sh (backup database files)

backup.sh
#!/bin/bash

/bin/tar -zcf /home/backup/$(date +%Y%m%d)-webdir.tar.gz
/var/www/html

db-backup.sh
#!/bin/bash

/bin/tar -zcf /home/backup/$(date +%Y%m%d)-mysql.tar.gz
/usr/local/mysql/data #copy dbs to db_backup folder for weekly or bi-weekly storage
mv /home/backup/$(date +%Y%m%d)-mysql.tar.gz
/home/backup/db_backup/

Now that we have our scripts in place, the next step is to schedule them. You can use a Linux tool called cron to schedule these backups. Basically, cron will call any script you specify at a given date and time.

One way to create a ‘cron job’ is to issue the following command:

crontab -e

This will bring you inside the vi editor, which can be tricky if you’ve never used it before. A good vi reference can be found at Vi Text Editor .

Let’s say we want to schedule the database backup script to run every day at 2:00 am. The following line will instruct cron to do so:

0 2 * * 0-6 /home/backup/bin/db-backup.sh

For a more complete reference on using cron, see the Linux Cron How-to .

July 17, 2007

Caching static content

Virtually every website has one or more pieces of content that are static, whether it be style sheets, archived content, or even a logo.

I can’t think of any good reason to reload these items with each page request, unless you really don’t mind burdening your users with long page loads, and your web server with additional load.

If you aren’t caching any content now, you really should consider it. It takes very minimal effort on your part if you choose the right method.

The easiest way to cache a page is by setting HTTP headers using your scripting language, in this example, PHP:

Header("Cache-Control: must-revalidate");
Header("Expires: " . gmdate("D, d M Y H:i:s", time() + 60 * 60 * 24 * 3) . " GMT");

Personally, I like to keep my scripts as simple as possible. By allowing my Apache web server to manage caching, I can let my scripts concentrate on providing the actual HTML for the page.

If the ‘mod-expires’ module is enabled in your Apache server, it will actually set the appropriate headers for you. I use the following directives to setup caching of my images and style sheets:

<IfModule mod_expires.c>
<Directory /src/>
ExpiresDefault "access plus 30 days"
</Directory>
</IfModule>

ExpiresDefault exposes quite a few more options for you to take advantage of. Find more information the [url=http://httpd.apache.org/docs/1.3/mod/mod_expires.html]Apache mod_expires[/url] page.