December 10, 2007

Backing up a MySQL Database Using Cron

Filed under: MySQL — Matt @ 11:44 am

It sure has been awhile since I’ve updated, things have been pretty busy and I just haven’t had time. Anyway, the most important and often overlooked part of running a dynamic MySQL website is backing up your data often. Losing your file system often doesn’t hurt as much as losing all of your content, especially when running a script that’s easily replaceable like vBulletin, Wordpress, etc. Backing up your data can be a chore, so this is the simple method I use for an automated backup of my databases.

1) SSH in your box

2) Open up your crontab, to do this type:
crontab -e

3) Add the job to your crontab, this is what I use:
30 0 * * * date=`date -I` ; mysqldump -a -uuser -ppassword dbname > /path/to/dump_$date.sql

I’ll break down what’s going on in the above line and what you need to edit

  • 30 0 * * * - This specifies the interval in which it will backup your data. Minutes, hours, days of the month, months, days of the week, respectively. In my case, I’m going to be running this every day at 12:30 AM. Asterisk out values which you do not need to limit.
  • user - Enter your mysql username here
  • password - Enter your mysql password here
  • It’s important to note that -uuser is not a typo, you need to prefix -u on your username, so if it’s jsmith, you will enter -ujsmith. Same goes for your password.
  • dbname - Enter the mysql database name which you want to backup
  • /path/to/dump_$date.sql - Enter the directory you wish to back up your data to, include $date if you want a datestamp on your backup names. Don’t back this up to a web accessible directory as anyone would be able to access your database information and view potentially sensitive data.

Once your cron job is up and running you can then use a 3rd party backup service to automatically pull those backups across onto secure networks at set intervals (ie: every day at 12:40 AM). Talk to your hosting provider as many already provide backup services like this. You can also choose to manually download them onto your hard drive if you prefer a most cost effective approach. Just remember to go in weekly or monthly to delete older backups if necessary - those with large databases may eventually max out their hard drive space if left unattended.

October 21, 2007

Protecting Your PHP/MySQL Queries from SQL Injection

Filed under: MySQL, PHP — Matt @ 6:36 am

SQL injection is a serious concern for webmasters, as an experienced attacker can use this hacking technique to gain access to sensitive data and/or potentially cripple your database. If you haven’t secured your applications, I implore you to get yourself familiar with the following method and grind it into your coding routine. One unsafe query can result in a nightmare for you or your client.

I’ve read through a lot of guides, and they tend to over complicate this, so I’ll be as straight forward as possible. In PHP the easiest way is to pass your data through the mysql_real_escape_string function. By escaping special characters on fields where the user can manipulate the database, you will avoid being vulnerable. Take a look below at the example of what to do and what not to do.

// This is a vulnerable query.
$query = "SELECT * FROM products WHERE name='$productname'";
mysql_query($query);

// This query is more secure
$query = sprintf("SELECT * FROM products WHERE name='%s'",
mysql_real_escape_string($productname));
mysql_query($query);

Since I primarily code in PHP, I can’t confidently provide techniques for other programming languages. The most important part of protecting yourself is stopping users from being able to pass unaltered database manipulative special characters, like single quotes.

MSDN - SQL Injection Article
Wikipedia - SQL Inection
SecuriTeam - SQL Injection Walkthrough
SitePoint - SQL Injection Attacks, Are You safe?

October 12, 2007

How to Backup and Restore Large Databases in MySQL

Filed under: MySQL — Matt @ 6:15 am

Most who use MySQL have a nifty program called PhpMyAdmin. There is a good chance that if you are a user of that program, you’re here because you tried to backup or restore a large database through the web based interface and failed. This is a common situation, lucky for us there’s a very easy, fast, and reliable way to do this through the command line! If you’re a Linux user who has SSH access, follow the steps below.

Backing up the Database
Fire up SSH and type the following. Replace USER with your MySQL username, DBNAME with the name of the database you want to back up, and /path/to/backupname.sql to where you want the database backup file to be saved (directory must exist).

mysqldump -a -u USER -p DBNAME > /path/to/backupname.sql

You’ll be prompted for your MySQL password. It’ll get to work after you type that in and press enter, it may take a few moments (or longer if your database is really large).

When you’re returned to the command line you now have a backup file where you specified above. This file is a complete copy of the database at the time you ran the command, the second your MySQL table is updated your backup will be out of date. I suggest you take backups at regular intervals depending on your situation (I will write a guide on how to automatically do backups one day).

Restoring Your Database Backup
Follow these 3 commands to restore your database easily.

First we need to drop your current database so there are no conflicts when we’re restoring

mysqladmin -u USER -p drop DBNAME

Now we’ll remake the database, because it doesn’t exist anymore

mysqladmin -u USER -p create DBNAME

And finally, we’ll populate the fresh new database with your backup file.

mysql -u USER -p DBNAME < /path/to/backup.sql

The variables you should change above are pretty straight forward. If you get errors importing your data, it’s most commonly because your max_allowed_packet isn’t set high enough in /etc/my.cnf - if you have root access, you can go in and make that variable higher. If you don’t have root access, seek support from your web host.