This section discusses how to use myisamchk to
check or repair MyISAM tables (tables that have
.MYD and .MYI files for
storing data and indexes). For general
myisamchk background, see
Section 4.6.3, “myisamchk — MyISAM Table-Maintenance Utility”.
You can use myisamchk to get information about your database tables or to check, repair, or optimize them. The following sections describe how to perform these operations and how to set up a table maintenance schedule.
Even though table repair with myisamchk is quite secure, it is always a good idea to make a backup before doing a repair or any maintenance operation that could make a lot of changes to a table.
myisamchk operations that affect indexes can
cause FULLTEXT indexes to be rebuilt with
full-text parameters that are incompatible with the values used by
the MySQL server. To avoid this problem, follow the guidelines in
Section 4.6.3.1, “myisamchk General Options”.
In many cases, you may find it simpler to do
MyISAM table maintenance using the SQL
statements that perform operations that
myisamchk can do:
To check or repair MyISAM tables, use
CHECK TABLE or REPAIR
TABLE.
To optimize MyISAM tables, use
OPTIMIZE TABLE.
To analyze MyISAM tables, use
ANALYZE TABLE.
These statements can be used directly or by means of the
mysqlcheck client program. One advantage of
these statements over myisamchk is that the
server does all the work. With myisamchk, you
must make sure that the server does not use the tables at the same
time so that there is no unwanted interaction between
myisamchk and the server. See
Section 12.5.2.1, “ANALYZE TABLE Syntax”, Section 12.5.2.3, “CHECK TABLE Syntax”,
Section 12.5.2.5, “OPTIMIZE TABLE Syntax”, and
Section 12.5.2.6, “REPAIR TABLE Syntax”.
This section describes how to check for and deal with data corruption in MySQL databases. If your tables become corrupted frequently, you should try to find the reason why. See Section B.1.4.2, “What to Do If MySQL Keeps Crashing”.
For an explanation of how MyISAM tables can
become corrupted, see Section 13.1.4, “MyISAM Table Problems”.
If you run mysqld with external locking disabled (which is the default as of MySQL 4.0), you cannot reliably use myisamchk to check a table when mysqld is using the same table. If you can be certain that no one will access the tables through mysqld while you run myisamchk, you only have to execute mysqladmin flush-tables before you start checking the tables. If you cannot guarantee this, you must stop mysqld while you check the tables. If you run myisamchk to check tables that mysqld is updating at the same time, you may get a warning that a table is corrupt even when it is not.
If the server is run with external locking enabled, you can use myisamchk to check tables at any time. In this case, if the server tries to update a table that myisamchk is using, the server will wait for myisamchk to finish before it continues.
If you use myisamchk to repair or optimize tables, you must always ensure that the mysqld server is not using the table (this also applies if external locking is disabled). If you don't stop mysqld, you should at least do a mysqladmin flush-tables before you run myisamchk. Your tables may become corrupted if the server and myisamchk access the tables simultaneously.
When performing crash recovery, it is important to understand
that each MyISAM table
tbl_name in a database corresponds to
three files in the database directory:
| File | Purpose |
| Definition (format) file |
| Data file |
| Index file |
Each of these three file types is subject to corruption in various ways, but problems occur most often in data files and index files.
myisamchk works by creating a copy of the
.MYD data file row by row. It ends the
repair stage by removing the old .MYD file
and renaming the new file to the original file name. If you use
--quick, myisamchk does not
create a temporary .MYD file, but instead
assumes that the .MYD file is correct and
generates only a new index file without touching the
.MYD file. This is safe, because
myisamchk automatically detects whether the
.MYD file is corrupt and aborts the repair
if it is. You can also specify the --quick
option twice to myisamchk. In this case,
myisamchk does not abort on some errors (such
as duplicate-key errors) but instead tries to resolve them by
modifying the .MYD file. Normally the use
of two --quick options is useful only if you
have too little free disk space to perform a normal repair. In
this case, you should at least make a backup of the table before
running myisamchk.
To check a MyISAM table, use the following
commands:
myisamchk
tbl_name
This finds 99.99% of all errors. What it cannot find is
corruption that involves only the data
file (which is very unusual). If you want to check a table,
you should normally run myisamchk without
options or with the -s (silent) option.
myisamchk -m
tbl_name
This finds 99.999% of all errors. It first checks all index entries for errors and then reads through all rows. It calculates a checksum for all key values in the rows and verifies that the checksum matches the checksum for the keys in the index tree.
myisamchk -e
tbl_name
This does a complete and thorough check of all data
(-e means “extended check”).
It does a check-read of every key for each row to verify
that they indeed point to the correct row. This may take a
long time for a large table that has many indexes. Normally,
myisamchk stops after the first error it
finds. If you want to obtain more information, you can add
the -v (verbose) option. This causes
myisamchk to keep going, up through a
maximum of 20 errors.
myisamchk -e -i
tbl_name
This is like the previous command, but the
-i option tells
myisamchk to print additional statistical
information.
In most cases, a simple myisamchk command with no arguments other than the table name is sufficient to check a table.
The discussion in this section describes how to use
myisamchk on MyISAM tables
(extensions .MYI and
.MYD).
You can also (and should, if possible) use the CHECK
TABLE and REPAIR TABLE statements
to check and repair MyISAM tables. See
Section 12.5.2.3, “CHECK TABLE Syntax”, and
Section 12.5.2.6, “REPAIR TABLE Syntax”.
Symptoms of corrupted tables include queries that abort unexpectedly and observable errors such as these:
is locked against change
tbl_name.frm
Can't find file
(Errcode: tbl_name.MYInnn)
Unexpected end of file
Record file is crashed
Got error nnn from table handler
To get more information about the error, run
perror nnn, where
nnn is the error number. The
following example shows how to use perror to
find the meanings for the most common error numbers that
indicate a problem with a table:
shell> perror 126 127 132 134 135 136 141 144 145
MySQL error code 126 = Index file is crashed
MySQL error code 127 = Record-file is crashed
MySQL error code 132 = Old database file
MySQL error code 134 = Record was already deleted (or record file crashed)
MySQL error code 135 = No more room in record file
MySQL error code 136 = No more room in index file
MySQL error code 141 = Duplicate unique key or constraint on write or update
MySQL error code 144 = Table is crashed and last repair failed
MySQL error code 145 = Table was marked as crashed and should be repaired
Note that error 135 (no more room in record file) and error 136
(no more room in index file) are not errors that can be fixed by
a simple repair. In this case, you must use ALTER
TABLE to increase the MAX_ROWS and
AVG_ROW_LENGTH table option values:
ALTER TABLEtbl_nameMAX_ROWS=xxxAVG_ROW_LENGTH=yyy;
If you do not know the current table option values, use
SHOW CREATE TABLE.
For the other errors, you must repair your tables. myisamchk can usually detect and fix most problems that occur.
The repair process involves up to four stages, described here. Before you begin, you should change location to the database directory and check the permissions of the table files. On Unix, make sure that they are readable by the user that mysqld runs as (and to you, because you need to access the files you are checking). If it turns out you need to modify files, they must also be writable by you.
This section is for the cases where a table check fails (such as
those described in Section 6.4.2, “How to Check MyISAM Tables for Errors”), or you want to use
the extended features that myisamchk
provides.
The options that you can use for table maintenance with myisamchk are described in Section 4.6.3, “myisamchk — MyISAM Table-Maintenance Utility”.
If you are going to repair a table from the command line, you must first stop the mysqld server. Note that when you do mysqladmin shutdown on a remote server, the mysqld server is still alive for a while after mysqladmin returns, until all statement-processing has stopped and all index changes have been flushed to disk.
Stage 1: Checking your tables
Run myisamchk *.MYI or myisamchk -e
*.MYI if you have more time. Use the
-s (silent) option to suppress unnecessary
information.
If the mysqld server is stopped, you should
use the --update-state option to tell
myisamchk to mark the table as
“checked.”
You have to repair only those tables for which myisamchk announces an error. For such tables, proceed to Stage 2.
If you get unexpected errors when checking (such as out
of memory errors), or if myisamchk
crashes, go to Stage 3.
Stage 2: Easy safe repair
First, try myisamchk -r -q
tbl_name (-r
-q means “quick recovery mode”). This
attempts to repair the index file without touching the data
file. If the data file contains everything that it should and
the delete links point at the correct locations within the data
file, this should work, and the table is fixed. Start repairing
the next table. Otherwise, use the following procedure:
Make a backup of the data file before continuing.
Use myisamchk -r
tbl_name
(-r means “recovery mode”).
This removes incorrect rows and deleted rows from the data
file and reconstructs the index file.
If the preceding step fails, use myisamchk
--safe-recover
tbl_name. Safe recovery
mode uses an old recovery method that handles a few cases
that regular recovery mode does not (but is slower).
Note: If you want a repair operation to go much faster, you
should set the values of the sort_buffer_size
and key_buffer_size variables each to about
25% of your available memory when running
myisamchk.
If you get unexpected errors when repairing (such as
out of memory errors), or if
myisamchk crashes, go to Stage 3.
Stage 3: Difficult repair
You should reach this stage only if the first 16KB block in the index file is destroyed or contains incorrect information, or if the index file is missing. In this case, it is necessary to create a new index file. Do so as follows:
Move the data file to a safe place.
Use the table description file to create new (empty) data and index files:
shell>mysqlmysql>db_nameSET AUTOCOMMIT=1;mysql>TRUNCATE TABLEmysql>tbl_name;quit
Copy the old data file back onto the newly created data file. (Do not just move the old file back onto the new file. You want to retain a copy in case something goes wrong.)
Go back to Stage 2. myisamchk -r -q should work. (This should not be an endless loop.)
You can also use the REPAIR TABLE
SQL
statement, which performs the whole procedure automatically.
There is also no possibility of unwanted interaction between a
utility and the server, because the server does all the work
when you use tbl_name USE_FRMREPAIR TABLE. See
Section 12.5.2.6, “REPAIR TABLE Syntax”.
Stage 4: Very difficult repair
You should reach this stage only if the
.frm description file has also crashed.
That should never happen, because the description file is not
changed after the table is created:
Restore the description file from a backup and go back to Stage 3. You can also restore the index file and go back to Stage 2. In the latter case, you should start with myisamchk -r.
If you do not have a backup but know exactly how the table
was created, create a copy of the table in another database.
Remove the new data file, and then move the
.frm description and
.MYI index files from the other
database to your crashed database. This gives you new
description and index files, but leaves the
.MYD data file alone. Go back to Stage
2 and attempt to reconstruct the index file.
To coalesce fragmented rows and eliminate wasted space that results from deleting or updating rows, run myisamchk in recovery mode:
shell> myisamchk -r tbl_name
You can optimize a table in the same way by using the
OPTIMIZE TABLE SQL statement.
OPTIMIZE TABLE does a table repair and a key
analysis, and also sorts the index tree so that key lookups are
faster. There is also no possibility of unwanted interaction
between a utility and the server, because the server does all
the work when you use OPTIMIZE TABLE. See
Section 12.5.2.5, “OPTIMIZE TABLE Syntax”.
myisamchk has a number of other options that you can use to improve the performance of a table:
--analyze, -a
--sort-index, -S
--sort-records=,
index_num-R
index_num
For a full description of all available options, see Section 4.6.3, “myisamchk — MyISAM Table-Maintenance Utility”.
To obtain a description of a table or statistics about it, use the commands shown here. We explain some of the information in more detail later.
myisamchk -d
tbl_name
Runs myisamchk in “describe mode” to produce a description of your table. If you start the MySQL server with external locking disabled, myisamchk may report an error for a table that is updated while it runs. However, because myisamchk does not change the table in describe mode, there is no risk of destroying data.
myisamchk -d -v
tbl_name
Adding -v runs myisamchk
in verbose mode so that it produces more information about
what it is doing.
myisamchk -eis
tbl_name
Shows only the most important information from a table. This operation is slow because it must read the entire table.
myisamchk -eiv
tbl_name
This is like -eis, but tells you what is
being done.
The tbl_name argument can be either
the name of a MyISAM table or the name of its
index file, as described in Section 4.6.3, “myisamchk — MyISAM Table-Maintenance Utility”.
Multiple tbl_name arguments can be
given.
Sample output for some of these commands follows. They are based on a table with these data and index file sizes:
-rw-rw-r-- 1 monty tcx 317235748 Jan 12 17:30 company.MYD -rw-rw-r-- 1 davida tcx 96482304 Jan 12 18:35 company.MYI
Example of myisamchk -d output:
MyISAM file: company.MYI
Record format: Fixed length
Data records: 1403698 Deleted blocks: 0
Recordlength: 226
table description:
Key Start Len Index Type
1 2 8 unique double
2 15 10 multip. text packed stripped
3 219 8 multip. double
4 63 10 multip. text packed stripped
5 167 2 multip. unsigned short
6 177 4 multip. unsigned long
7 155 4 multip. text
8 138 4 multip. unsigned long
9 177 4 multip. unsigned long
193 1 text
Example of myisamchk -d -v output:
MyISAM file: company
Record format: Fixed length
File-version: 1
Creation time: 1999-10-30 12:12:51
Recover time: 1999-10-31 19:13:01
Status: checked
Data records: 1403698 Deleted blocks: 0
Datafile parts: 1403698 Deleted data: 0
Datafile pointer (bytes): 3 Keyfile pointer (bytes): 3
Max datafile length: 3791650815 Max keyfile length: 4294967294
Recordlength: 226
table description:
Key Start Len Index Type Rec/key Root Blocksize
1 2 8 unique double 1 15845376 1024
2 15 10 multip. text packed stripped 2 25062400 1024
3 219 8 multip. double 73 40907776 1024
4 63 10 multip. text packed stripped 5 48097280 1024
5 167 2 multip. unsigned short 4840 55200768 1024
6 177 4 multip. unsigned long 1346 65145856 1024
7 155 4 multip. text 4995 75090944 1024
8 138 4 multip. unsigned long 87 85036032 1024
9 177 4 multip. unsigned long 178 96481280 1024
193 1 text
Example of myisamchk -eis output:
Checking MyISAM file: company Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4 Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4 Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4 Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3 Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4 Total: Keyblocks used: 98% Packed: 17% Records: 1403698 M.recordlength: 226 Packed: 0% Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00 Record blocks: 1403698 Delete blocks: 0 Recorddata: 317235748 Deleted data: 0 Lost space: 0 Linkdata: 0 User time 1626.51, System time 232.36 Maximum resident set size 0, Integral resident set size 0 Non physical pagefaults 0, Physical pagefaults 627, Swaps 0 Blocks in 0 out 0, Messages in 0 out 0, Signals 0 Voluntary context switches 639, Involuntary context switches 28966
Example of myisamchk -eiv output:
Checking MyISAM file: company
Data records: 1403698 Deleted blocks: 0
- check file-size
- check delete-chain
block_size 1024:
index 1:
index 2:
index 3:
index 4:
index 5:
index 6:
index 7:
index 8:
index 9:
No recordlinks
- check index reference
- check data record references index: 1
Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
- check data record references index: 2
Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
- check data record references index: 3
Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
- check data record references index: 4
Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
- check data record references index: 5
Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 6
Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 7
Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 8
Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 9
Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
Total: Keyblocks used: 9% Packed: 17%
- check records and index references
*** LOTS OF ROW NUMBERS DELETED ***
Records: 1403698 M.recordlength: 226 Packed: 0%
Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00
Record blocks: 1403698 Delete blocks: 0
Recorddata: 317235748 Deleted data: 0
Lost space: 0 Linkdata: 0
User time 1639.63, System time 251.61
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
Blocks in 4 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 10604, Involuntary context switches 122798
Explanations for the types of information myisamchk produces are given here. “Keyfile” refers to the index file. “Record” and “row” are synonymous.
MyISAM file
Name of the MyISAM (index) file.
File-version
Version of MyISAM format. Currently
always 2.
Creation time
When the data file was created.
Recover time
When the index/data file was last reconstructed.
Data records
How many rows are in the table.
Deleted blocks
How many deleted blocks still have reserved space. You can optimize your table to minimize this space. See Section 6.4.4, “Table Optimization”.
Datafile parts
For dynamic-row format, this indicates how many data blocks
there are. For an optimized table without fragmented rows,
this is the same as Data records.
Deleted data
How many bytes of unreclaimed deleted data there are. You can optimize your table to minimize this space. See Section 6.4.4, “Table Optimization”.
Datafile pointer
The size of the data file pointer, in bytes. It is usually 2, 3, 4, or 5 bytes. Most tables manage with 2 bytes, but this cannot be controlled from MySQL yet. For fixed tables, this is a row address. For dynamic tables, this is a byte address.
Keyfile pointer
The size of the index file pointer, in bytes. It is usually 1, 2, or 3 bytes. Most tables manage with 2 bytes, but this is calculated automatically by MySQL. It is always a block address.
Max datafile length
How long the table data file can become, in bytes.
Max keyfile length
How long the table index file can become, in bytes.
Recordlength
How much space each row takes, in bytes.
Record format
The format used to store table rows. The preceding examples
use Fixed length. Other possible values
are Compressed and
Packed.
table description
A list of all keys in the table. For each key, myisamchk displays some low-level information:
Key
This key's number.
Start
Where in the row this portion of the index starts.
Len
How long this portion of the index is. For packed numbers, this should always be the full length of the column. For strings, it may be shorter than the full length of the indexed column, because you can index a prefix of a string column.
Index
Whether a key value can exist multiple times in the
index. Possible values are unique or
multip. (multiple).
Type
What data type this portion of the index has. This is a
MyISAM data type with the possible
values packed,
stripped, or
empty.
Root
Address of the root index block.
Blocksize
The size of each index block. By default this is 1024, but the value may be changed at compile time when MySQL is built from source.
Rec/key
This is a statistical value used by the optimizer. It tells how many rows there are per value for this index. A unique index always has a value of 1. This may be updated after a table is loaded (or greatly changed) with myisamchk -a. If this is not updated at all, a default value of 30 is given.
For the table shown in the examples, there are two
table description lines for the ninth
index. This indicates that it is a multiple-part index with
two parts.
Keyblocks used
What percentage of the keyblocks are used. When a table has just been reorganized with myisamchk, as for the table in the examples, the values are very high (very near the theoretical maximum).
Packed
MySQL tries to pack key values that have a common suffix.
This can only be used for indexes on CHAR
and VARCHAR columns. For long indexed
strings that have similar leftmost parts, this can
significantly reduce the space used. In the third of the
preceding examples, the fourth key is 10 characters long and
a 60% reduction in space is achieved.
Max levels
How deep the B-tree for this key is. Large tables with long key values get high values.
Records
How many rows are in the table.
M.recordlength
The average row length. This is the exact row length for tables with fixed-length rows, because all rows have the same length.
Packed
MySQL strips spaces from the end of strings. The
Packed value indicates the percentage of
savings achieved by doing this.
Recordspace used
What percentage of the data file is used.
Empty space
What percentage of the data file is unused.
Blocks/Record
Average number of blocks per row (that is, how many links a fragmented row is composed of). This is always 1.0 for fixed-format tables. This value should stay as close to 1.0 as possible. If it gets too large, you can reorganize the table. See Section 6.4.4, “Table Optimization”.
Recordblocks
How many blocks (links) are used. For fixed-format tables, this is the same as the number of rows.
Deleteblocks
How many blocks (links) are deleted.
Recorddata
How many bytes in the data file are used.
Deleted data
How many bytes in the data file are deleted (unused).
Lost space
If a row is updated to a shorter length, some space is lost. This is the sum of all such losses, in bytes.
Linkdata
When the dynamic table format is used, row fragments are
linked with pointers (4 to 7 bytes each).
Linkdata is the sum of the amount of
storage used by all such pointers.
If a table has been compressed with myisampack, myisamchk -d prints additional information about each table column. See Section 4.6.5, “myisampack — Generate Compressed, Read-Only MyISAM Tables”, for an example of this information and a description of what it means.
It is a good idea to perform table checks on a regular basis
rather than waiting for problems to occur. One way to check and
repair MyISAM tables is with the
CHECK TABLE and REPAIR
TABLE statements. See Section 12.5.2.3, “CHECK TABLE Syntax”,
and Section 12.5.2.6, “REPAIR TABLE Syntax”.
Another way to check tables is to use
myisamchk. For maintenance purposes, you can
use myisamchk -s. The -s
option (short for --silent) causes
myisamchk to run in silent mode, printing
messages only when errors occur.
It is also a good idea to enable automatic
MyISAM table checking. For example, whenever
the machine has done a restart in the middle of an update, you
usually need to check each table that could have been affected
before it is used further. (These are “expected crashed
tables.”) To check MyISAM tables
automatically, start the server with the
--myisam-recover option. See
Section 5.1.2, “Command Options”.
You should also check your tables regularly during normal system
operation. At MySQL AB, we run a cron job to
check all our important tables once a week, using a line like
this in a crontab file:
35 0 * * 0/path/to/myisamchk--fast --silent/path/to/datadir/*/*.MYI
This prints out information about crashed tables so that we can examine and repair them when needed.
Because we have not had any unexpectedly crashed tables (tables that become corrupted for reasons other than hardware trouble) for several years, once a week is more than sufficient for us.
We recommend that to start with, you execute myisamchk -s each night on all tables that have been updated during the last 24 hours, until you come to trust MySQL as much as we do.
Normally, MySQL tables need little maintenance. If you are
performing many updates to MyISAM tables with
dynamic-sized rows (tables with VARCHAR,
BLOB, or TEXT columns) or
have tables with many deleted rows you may want to
defragment/reclaim space from the tables from time to time. You
can do this by using OPTIMIZE TABLE on the
tables in question. Alternatively, if you can stop the
mysqld server for a while, change location
into the data directory and use this command while the server is
stopped:
shell> myisamchk -r -s --sort-index --sort_buffer_size=16M */*.MYI