MySQL

How to Fix "Table Is Marked as Crashed and Should Be Repaired" in MySQL

4 min read by DebuggedIt

Quick answer

A query against a table that was working fine suddenly fails, and MySQL reports the table itself is corrupted. This error is specific to the older MyISAM...

A query against a table that was working fine suddenly fails, and MySQL reports the table itself is corrupted. This error is specific to the older MyISAM storage engine (InnoDB has its own, generally more robust crash recovery), and it means the table's index or data file got into an inconsistent state, usually from an unclean shutdown.

The Problem

A normal query fails with a corruption error instead of returning results:

mysql> SELECT * FROM sessions LIMIT 10;
ERROR 145 (HY000): Table './mydb/sessions' is marked as crashed and should be repaired

Sometimes it appears in the MySQL error log first, before anyone even notices from a query:

[ERROR] mysqld: Table './mydb/sessions' is marked as crashed and should be repaired
[Warning] Checking table:   './mydb/sessions'

Why It Happens

MyISAM tables store data and indexes in separate files and don't have the transaction log and crash-recovery mechanisms InnoDB relies on, which makes them more vulnerable to corruption from an abrupt interruption. Common causes:

  • An unclean MySQL shutdown β€” a server crash, a forced kill (kill -9 on the mysqld process), a power outage, or an out-of-memory kill mid-write.
  • Disk-level issues β€” a failing disk, a full disk during a write, or a filesystem error corrupting the underlying .MYD/.MYI files directly.
  • Concurrent access bugs in older MySQL versions under specific MyISAM locking edge cases, though this is rare on modern versions.
  • Manual file manipulation β€” copying MyISAM files while the server is running, or restoring from a backup taken mid-write without proper locking.

The Fix

The built-in repair command is the standard first step, and works without taking the whole server offline:

REPAIR TABLE sessions;
+-----------------+--------+----------+----------+
| Table           | Op     | Msg_type | Msg_text |
+-----------------+--------+----------+----------+
| mydb.sessions   | repair | status   | OK       |
+-----------------+--------+----------+----------+

Once it reports OK, verify the table is queryable again:

SELECT COUNT(*) FROM sessions;

If REPAIR TABLE itself fails or the server won't even start due to the corruption, use the command-line myisamchk tool directly against the files, with the MySQL server stopped first to avoid conflicting access to the files:

sudo systemctl stop mysql
cd /var/lib/mysql/mydb
myisamchk -r sessions.MYI
- recovering (with keycache) MyISAM-table 'sessions.MYI'
Data records: 18402
- Fixed keyfile

If the standard recovery mode doesn't fully fix it, escalate to a more aggressive (and slower) recovery pass:

myisamchk --safe-recover sessions.MYI

Restart MySQL and confirm the table is accessible:

sudo systemctl start mysql
SELECT COUNT(*) FROM sessions;

Still Not Working?

If the table repeatedly crashes even after a successful repair, that's a strong signal of an underlying hardware or filesystem problem rather than a one-off software glitch β€” check the disk for errors directly rather than continuing to repair the symptom:

dmesg | grep -i "error\|ata\|sda"
sudo smartctl -a /dev/sda

If the disk itself is failing, back up everything immediately and plan a hardware replacement, since repeated MyISAM corruption on otherwise-fine data is a known symptom of failing storage. Given how much more resilient InnoDB is to crashes, it's also worth converting frequently affected tables away from MyISAM entirely if there's no specific reason they need to stay on it:

ALTER TABLE sessions ENGINE=InnoDB;

InnoDB's write-ahead logging and automatic crash recovery on startup make this class of corruption dramatically less common, and for most modern applications there's little reason to keep tables on MyISAM unless you're relying on a MyISAM-specific feature like full-text indexing on an older MySQL version that doesn't yet support it on InnoDB.

It's also worth setting up automatic detection so a crashed table gets caught quickly rather than discovered by a user hitting an error in production. MySQL can be configured to automatically check and repair MyISAM tables on startup, which is a reasonable safety net after an unclean shutdown, though it does add to startup time on databases with many large MyISAM tables:

[mysqld]
myisam-recover-options = BACKUP,FORCE

This setting tells MySQL to attempt an automatic repair for any table it finds marked as crashed during the startup table-open process, backing up the original file first before attempting the fix. For ongoing monitoring outside of just startup, a periodic scheduled check catches corruption that develops during normal operation rather than only at restart time:

0 3 * * * mysqlcheck -u root -p --auto-repair --check mydb

Running this nightly via cron flags and repairs any MyISAM tables that have quietly developed issues, well before a user's query is the first thing to notice.