Database administrators and developers are well aware of the importance of regular data backups: In the event of a disk failure or server crash, a backup can often make the difference between losing a year's worth of work and getting back up to speed in a few hours. Fortunately, if you're using MySQL you have at your disposal a built-in suite of advanced tools that simplify backing up and restoring databases. And if you work on different platforms, these tools also make it easy to move MySQL databases from one platform to another, and to export and import records in different formats.
Copying database files
When it comes to backing up MySQL databases, don't ignore the most obvious solution: making copies of the database files themselves.
Because MySQL uses the same table format on different platforms, it's actually possible to copy MySQL table and index files from one platform and use them on another without any difficulties (assuming, of course, that you're using the same version of MySQL on both platforms).
So which files should you copy? MySQL stores all its databases in a special data/ directory, which is further divided into subdirectories, one for each database. Tables and table indexes are represented as files, with the file name equal to the table name plus an extension.
The easiest approach is to just copy the entire data/ directory to backup media, and archive it so that you can get it back at any time. You might want to write a script to automate the copy. You can then pop the script into your crontab so it can run on a daily or weekly basis, depending on how frequently your databases get updated.
If you're moving files between Windows and UNIX platforms, there is one thing that can trip you up. UNIX file names are case-sensitive, while Windows names are not. Therefore, mixed-case MySQL table names are likely to get corrupted when moved between Windows and UNIX (though the data in the tables will be fine). If your SQL code uses these mixed-case table names, it might not work correctly until you check and fix the names and/or the code. For best results, always use lowercase table names, so that you don't encounter this problem.
Exporting tables to text files
An alternative to the simple file copy is using the mysqldump tool included in MySQL. It can dump a table, a database, or all databases to a text file.
Using mysqldump is simplicity itself—just run the program with the name of the database to be exported, as below:$ mysqldump -u root -psecret stocksdb
The mysqldump tool will connect to the MySQL server, log in using the credentials provided, and print out the table structure and data as a series of reproducible SQL commands. Here is a short snippet of the output:—
— Dumping data for table 'portfolio'
INSERT INTO portfolio VALUES (1,'DHDU',2589,77.56); INSERT INTO portfolio VALUES (2,'YHOO',3200,45.65); INSERT INTO portfolio VALUES (3,'WMT',100,53.29);
Of course, printing it to the console is not really useful. What you need is to write it to a file which can then be backed up and restored. Simply redirect the output to a file by revising the previous command:$ mysqldump -u root -psecret stocksdb > stocksdb.sql [/code]
To only back up a particular table, follow the database name with the table name. This next command only retrieves the structure and data for the users table in the stocksdb database:$ mysqldump -u root -psecret stocksdb users > users.sql
And to dump all the databases on the system, use the —all-databases shortcut:$ mysqldump -u root -psecret —all-databases > backup.sql
Note: If you use the —all-databases option, the SQL output of mysqldump contains a CREATE DATABASE statement to initialize each database. This makes it easier to restore the entire set of databases at once (as you will see on the next page).
If you'd like the backup to only contain the table structure, use the —no-data option:$ mysqldump -u root -psecret —no-data stocksdb > stocksdb.sql
This is extremely useful if you need to create a new, empty copy of a database—say, for example, when you first install an application and need to initialize a set of tables with no records.
You can do the reverse as well—back up just the data, without backing up the table structure:$ mysqldump -u root -psecret —no-create-info stocksdb > stocksdb.sql
Now that we have the basics of backing up our data, we need to figure out how to restore from a backup.
Restoring MySQL tables from text backup files
Backing up your databases and tables is only one half of the puzzle: The flip side involves knowing how to restore them in the event of a crash.
Luckily, MySQL makes it simple. Since the output of mysqldump is a series of SQL statements, this output can simply be piped back into a MySQL client to re-create the original database structure and contents.
Assuming you backed up all your databases to a file named backup.sql with the mysqldump —all-databases command, you can restore them with the following:$ mysql -u root -psecret < backup.sql
If you didn't use the —all-databases option but instead selectively backed up one or more tables or databases, you need to tell MySQL which database to place them in when restoring them. We do that by adding the -D option to the command line above. Here's an example which restores the tables in the file stocksdb.sql to the database named stocks2:$ mysql -u root -psecret -D stocks2 < stocksdb.sql
Exporting and importing in different formats
SQL isn't the only output format you can save your MySQL databases in. The mysqldump program lets you save records in a variety of different formats, including CSV or with your own custom delimiters. Just add the —fields-terminated-by argument to the mysqldump command line:$ mysqldump -u root -psecret —no-create-info —tab=/tmp —fields-terminated-by=',' stocksdb
mysqldump will now go to work generating a file in /tmp containing the records from the stocksdb table, with each field separated by a comma. If you'd like a custom line-terminator, you can also use the —lines-terminated-by argument to mark each line with a particular delimiter.
And just as you can export data into different formats, you can also import in different formats. For example, if you had a tab-separated file containing table records, like this:1 DHDU 2589 77.56
2 YHOO 3200 45.65
3 WMT 100 53.29
you could use the mysqlimport tool to read the data into a MySQL database, like this:$ mysqlimport -u root -psecret —fields-terminated-by='\t' test /tmp/portfolio.txt
Note that the base name of the source file determines the table into which the data is inserted.
As part of your backup regimen, always keep at least two copies of each backup set (one in a different location). And read the MySQL manual pages for the various data export and import tools to see how best to adapt them to your environment.
Hopefully, you won't ever have to restore a crashed database from your backups. But you'll sleep much easier knowing you have the tools to do it efficiently and with minimal inconvenience to your users if the worst should ever happen.