The file format that MySQL uses to store data has been extensively tested, but there are always circumstances that may cause database tables to become corrupted.
Even if the MyISAM table format is very reliable (all changes to a table is written before the SQL statements returns) , you can still get corrupted tables if some of the following things happens:
The mysqld process being killed in the middle of a write.
Unexpected shutdown of the computer (for example, if the computer is turned off).
A hardware error.
You are using an external program (like myisamchk) on a live table.
A software bug in the MySQL or MyISAM code.
Typial typical symptoms for a corrupt table is:
You get the error Incorrect key file for table: '...'. Try to repair it while selecting data from the table.
Queries doesn't find rows in the table or returns incomplete data.
You can check if a table is ok with the command CHECK TABLE. See CHECK TABLE.
You can repair a corrupted table with REPAIR TABLE. See REPAIR TABLE. You can also repair a table, when mysqld is not running with the myisamchk command. myisamchk syntax.
If your tables get corrupted a lot you should try to find the reason for this! See Crashing.
In this case the most important thing to know is if the table got corrupted if the mysqld died (one can easily verify this by checking if there is a recent row restarted mysqld in the mysqld error file). If this isn't the case, then you should try to make a test case of this. See Reproduceable test case.
Each MyISAM .MYI file has in the header a counter that can be used to check if a table has been closed properly.
If you get the following warning from CHECK TABLE or myisamchk:
# clients is using or hasn't closed the table properly
this means that this counter has come out of sync. This doesn't mean that the table is corrupted, but means that you should at least do a check on the table to verify that it's okay.
The counter works as follows:
The first time a table is updated in MySQL, a counter in the header of the index files is incremented.
The counter is not changed during further updates.
When the last instance of a table is closed (because of a FLUSH or because there isn't room in the table cache) the counter is decremented if the table has been updated at any point.
When you repair the table or check the table and it was okay, the counter is reset to 0.
To avoid problems with interaction with other processes that may do a check on the table, the counter is not decremented on close if it was 0.
In other words, the only ways this can go out of sync are:
The MyISAM tables are copied without a LOCK and FLUSH TABLES.
MySQL has crashed between an update and the final close. (Note that the table may still be okay, as MySQL always issues writes for everything between each statement.)
Someone has done a myisamchk --recover or myisamchk --update-stateon a table that was in use by mysqld.
Many mysqld servers are using the table and one has done a REPAIR or CHECK of the table while it was in use by another server. In this setup the CHECK is safe to do (even if you will get the warning from other servers), but REPAIR should be avoided as it currently replaces the datafile with a new one, which is not signaled to the other servers.