It's happened to all of us: your hard disk crashes, your machine dies, somebody steals your box, or you get horribly hacked. In these cases, the only way to recover your application is to restore a backup copy of your database (after you've reinstalled MySQL!). There are also less catastrophic events that can occur from which you need to recover: indexes and tables can become corrupt because of a power failure or MySQL unexpectedly dying, your operating system might crash, or a disk may become unreliable.
To protect against catastrophic events, you should make regular backups and store these offsite. There are many different ways you can backup your MySQL installation, and different ways you can automate the process. The simplest technique is to automate the dumping of your database as SQL statements into a file using the mysqldump utility, and this is the approach we focus on in this section.
In a Unix environment, you can also use mysqlhotcopy to do backups; it's a Perl script that works only for MyISAM tables and is described in more detail in Section 4.8.7 of the MySQL manual. Other approaches you can use in all environments are the BACKUP TABLE and RESTORE TABLE statements from within the command interpreter or a PHP script, and simply copying the database files when the database is offline. We don't discuss these approaches here.
All backup techniques have in common that they result in one or more files that are the backup of the database. You could burn these files onto a CD or other media (if they'll fit), copy them across a network to a backup server, or use a tape or removable disk backup unit to make a copy (and perhaps also backup other user data and the operating system). Ideally, you should then take the backup offsite.
To recover from less catastrophic events, such as a power failure, MySQL has utilities for repairing tables. We also discuss these in this section.
The simplest way to backup all of your databases is to run the following command in a Unix environment from a shell prompt:
% /usr/local/mysql/bin/mysqldump -uroot -ppassword --all-databases --opt > /tmp/backup
This writes the backup to the file /tmp/backup.
In Microsoft Windows, choose the Run option in the Start menu and type:
"C:\Program Files\EasyPHP1-7\mysql\bin\mysqldump.exe" -uroot -ppassword --all-databases --opt > c:\windows\temp\backup
This writes the backup to the file C:\windows\temp\backup.
Leave your MySQL server running while you issue these commands. Both commands assume you've followed our installation instructions in Appendix A through Appendix C.
These commands write everything you need into the backup file and you can then copy this file elsewhere for safe keeping; you could automate the backup and copying process using the techniques discussed in Section 15.5. If you inspect the backup file, you'll find it's the SQL statements that create and insert all of the databases, tables, and data that's in your MySQL installation.
The --opt option to mysqldump writes a file that's fast to load when restored, and it also locks all tables in a database before dumping it (and so avoids concurrency issues within a database). If you want to lock all tables across all databases then add the --first-slave option to the mysqldump command; we don't recommend this if your application is online, and it isn't necessary if your applications have only one database each.
The winestore database that you've loaded into your MySQL installation is stored in the file winestore.database. The file was created by dumping the data from our MySQL server using mysqldump (and then neatening up the file so it's organized a little better). We dumped it initially with MySQL 3.23, and we've maintained it manually since.
You can dump individual databases using the mysqldump command line utility. For example, to dump the winestore database to the file ws-dump in a Unix environment, you can use:
% /usr/local/mysql/bin/mysqldump --opt -uroot -ppassword --databases winestore > /tmp/ws-dump
To do the same thing in Microsoft Windows, type the following in the Run dialog that's accessible from the Start menu:
"C:\Program Files\EasyPHP1-7\mysql\bin\mysqldump.exe" --opt -uroot -ppassword --databases winestore > C:\windows\temp\ws-dump
The --databases option automatically adds a CREATE DATABASE IF NOT EXISTS winestore and USE winestore to the beginning of the file. These statements make loading of the file straightforward using the techniques we discuss next.
Leave MySQL running while you issue these commands. Both commands assume you've followed our installation instructions in Appendix A through Appendix C.
You can load a backup produced with mysqldump into MySQL to restore a database. On any platform, run the command interpreter and then type:
mysql> SOURCE filename
For example, on a Unix-based MySQL, if the file is stored as /tmp/ws-dump use:
mysql> SOURCE /tmp/ws-dump
For Microsoft Windows, if the file is stored as c:\windows\temp\ws-dump, you can use:
mysql> SOURCE C:\temp\ws-dump
Be careful: this will overwrite the database or databases in your MySQL installation. Also, make sure your application is offline when you do this, as it's likely to result in unpredictable results for unsuspecting users.
As an alternative, you can pipe a file to the command interpreter. This has the advantage that it can be added to a script file. For example, on a Unix system, you could type:
% /usr/local/mysql/bin/mysql -uroot -ppassword < /tmp/ws-dump
In a command window on a Microsoft Windows machine you can use:
C:\> type c:\windows\temp\ws-dump | c:\progra~1\easyph~1\mysql\bin\mysql -uroot - ppassword
These commands assume you've followed our installation instructions in Appendix A through Appendix C.
Sometimes, your MySQL server may stop without being able to carry out its normal shutdown processes. Possible causes include machine and power failures, operating system errors, and MySQL internal problems. If your MySQL server does die, you should take two basic steps: first, check the error log to see if information has been recorded that can help you fix the problem; and, second, check your databases and tables for errors.
The error log is a text file and you can open it in your text editor to inspect it; to do this, you usually need to log in as the root or administrator user. The file has a .err extension and is found in the var or data subdirectory of your MySQL installation. The name of your machine usually precedes the .err extension. If you've followed our Linux installation instructions, you'll find the error file in /usr/local/mysql/var. On Mac OS X, it is in /usr/local/mysql/data, and on Microsoft Windows in C:\Program Files\EasyPHP1-7\mysql\var. You'll find that the textual explanations usually explain clearly what problem has caused your MySQL to stop or fail to start, and it's obvious what actions to take to rectify the problem.
There are other situations in which you should check your databases and tables. You should check your tables if strange results begin appearing from queries, such as unexpected end of file, can't find file, or table handler errors. It's possible that tables haven't been closed properly, that the indexes are corrupted, or that data modifications to tables weren't completed. It's also possible that a component in your system is about to fail, such as a hard disk. If so, you'll need to carry out repairs. If your system is about to fail, after this you should attempt to backup using the techniques we've discussed so far.
The CHECK TABLE statement checks a table, and works for MyISAM and InnoDB tables; since Heap tables are an in-memory structure, they don't need to be checked and repaired. For example, to check the customer table, use:
CHECK TABLE customer;
It'll report a message such as:
+--------------------+-------+----------+----------+ | Table | Op | Msg_type | Msg_text | +--------------------+-------+----------+----------+ | winestore.customer | check | status | OK | +--------------------+-------+----------+----------+ 1 row in set (0.06 sec)
Everything is fine if the Msg_Type reported is status and the Msg_text is one of OK or Table is already up to date. If an error is found through CHECK TABLE, it'll probably report more than one row in the results, and the rows will list information, warnings, and errors in the Msg_type column and explanatory text in the Msg_text column. If this happens, you need to repair the table as discussed later in this section.
The CHECK TABLE statement has an optional parameter that adjusts how quick and superficial, or slow and thorough, the checks are. By default, it uses the MEDIUM setting, but you can specify QUICK, FAST, MEDIUM, EXTENDED, or CHANGED. We recommend using the default of MEDIUM, and then rerunning the EXTENDED option if the default reports errors. EXTENDED does a slow and thorough test of the table and its indexes. For example, to use EXTENDED on the customer table, type:
CHECK TABLE customer EXTENDED;
If you find an error in a MyISAM table, you can use the REPAIR TABLE statement to attempt a repair. Here's an example that repairs the customer table:
REPAIR TABLE customer;
You can also use a more thorough EXTENDED option that recreates the indexes in a slow but careful manner:
REPAIR TABLE customer EXTENDED;
In almost all cases, this should repair a MyISAM table. If it doesn't, or errors keep occurring, you should look elsewhere for the problem: perhaps your hard disk has become unreliable and is about to crash. Section 4.4.6.9 of the MySQL manual discusses table repair in more detail, and discusses what to do in the unlikely event that REPAIR TABLE doesn't fix your problem.
You can't use REPAIR TABLE on an InnoDB table. However, they don't usually have errors. Because of InnoDB's transactions and logging (and checkpointing) discussed in Section 15.6. it's very robust in recovering from power and database server failures, and this is a key feature of InnoDB. However, in the unlikely event that something does go wrong and an error is reported by CHECK TABLE, Section 7.5.4.1 of the MySQL manual shows you how to get InnoDB to boot safely. This'll maximize the chances of you being able to export your data from the database before (probably) your hard disk crashes or system fails.
Data can also be dumped from a database using SQL. MySQL supports the SELECT ... INTO OUTFILE statement that allows you to write out data in a regular format, such as a comma-delimited file that can be read into a spreadsheet program. Consider an example query that exports a report on customer orders into the file /tmp/orders-file:
SELECT customer.cust_id, surname, firstname, orders.order_id, sum(price) INTO OUTFILE "/tmp/orders-file" FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY "\n" FROM customer INNER JOIN orders USING (cust_id) INNER JOIN items USING (cust_id, order_id) GROUP BY cust_id, order_id;
On Microsoft Windows, you could replace /tmp/orders-file with a Windows path and file such as c:\windows\temp\orders-file.
In part, the output file contains the following output:
1,"Rosenthal","Joshua",1,11.56 1,"Rosenthal","Joshua",2,375.58 1,"Rosenthal","Joshua",3,51.31 1,"Rosenthal","Joshua",4,487.35 2,"Serrong","Martin",1,367.04 2,"Serrong","Martin",2,532.12 2,"Serrong","Martin",3,251.62 2,"Serrong","Martin",4,75.57 2,"Serrong","Martin",5,308.72
The statement is complementary to the LOAD DATA INFILE statement discussed in Section 15.3.2. More detail on both statements can be found in Sections 6.4.1 and 6.4.9 of the MySQL manual.