1. Corrupted InnoDB Pages – The Most Common Cause
I've seen this one more than any other. A sudden power loss, a hard crash, or maybe a buggy upgrade to MySQL 5.7 or 8.0. The engine tries to roll back transactions from the redo log, hits a page that's missing or corrupt, and just stalls. You'll see something like:
InnoDB: Error: page [page id: ...] log sequence number ... is in the future
InnoDB: Crash recovery may have failed
First thing: don't restart the server again without a plan. You'll make it worse. Here's what actually works.
The Fix: innodb_force_recovery
Edit your MySQL config file (my.cnf or my.ini) and add this line under [mysqld]:
innodb_force_recovery = 1
Then restart MySQL. If it starts, great. You can now export your tables with mysqldump. If not, bump the number up to 2, then 3, and so on, up to 6. Each level skips more recovery steps. Level 6 skips the redo log entirely – you'll lose some data, but you get the database back.
Had a client last month whose entire accounting DB wouldn't start. Level 4 did the trick. We dumped everything, dropped the database, reimported clean. Took a day but saved their books.
After you recover the data, set innodb_force_recovery = 0 (default) and rebuild the tables. Don't run production on force recovery mode – it's read-only in higher levels.
2. Disk Full – The Silent Killer
This one is sneaky. MySQL starts crash recovery, needs to write temporary files or extend the undo tablespace, but the disk is at 99%. So it hangs or fails. The error log might not even say "disk full" – it just says recovery failed.
On Ubuntu 20.04 with MySQL 8.0, I had a call last year where the client's data partition had 200 MB free. Recovery tried to create a temp sort file and boom – stuck for hours.
The Fix: Free Up Space
Check disk space right now:
df -h
If /var/lib/mysql or wherever your data directory is shows 100%, clear space. Look for old binary logs:
PURGE BINARY LOGS BEFORE NOW();
But if MySQL won't start, you can't run that. So go manually:
cd /var/lib/mysql
ls -lh mysql-bin.*
rm mysql-bin.000123 (keep the newest one or two)
Also check the /tmp directory. MySQL sometimes uses it for temporary tables during recovery. Clear old files there too:
rm -rf /tmp/*.tmp
Then restart MySQL. If it still fails, move on to the next fix.
3. Corrupted or Missing Redo Log Files
The redo log (files ib_logfile0 and ib_logfile1) is InnoDB's recovery journal. If one of these gets corrupted – say from a disk write error or a bad shutdown – recovery can't read it and fails.
I had a case on Windows Server 2019 where antivirus software locked the redo log file. MySQL couldn't read it, recovery failed. Took me a full afternoon to figure that out.
The Fix: Remove and Recreate Redo Logs
This only works if you can safely lose the uncommitted transactions in the log. If you have a recent backup, proceed.
- Set
innodb_fast_shutdown = 0in your config (but you can't shut down cleanly, so skip this if MySQL won't start). - Shut down MySQL if it's running.
- Move the redo log files to a backup location:
mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0.bak
mv /var/lib/mysql/ib_logfile1 /var/lib/mysql/ib_logfile1.bak
- Start MySQL. It will create fresh, empty redo log files. Recovery will start from scratch – any transactions not flushed to the data files are lost.
If MySQL starts, immediately take a full backup. Then check your data. Missing rows? Restore from backup. This is a last resort, but it has saved me three times in the last two years.
Quick-Reference Fix Summary
| Cause | Fix | Data Loss Risk |
|---|---|---|
| Corrupted pages | Set innodb_force_recovery from 1 to 6 | Medium (depends on level) |
| Disk full | Free up space, remove old binlogs | Low |
| Corrupted redo logs | Delete ib_logfile* files, restart MySQL | High (lost uncommitted transactions) |
My advice: always keep your backups current. InnoDB recovery is reliable most of the time, but when it fails, these three fixes cover nearly every case I've seen in the wild.