The Short Fix
You're looking at ERROR 1146 (42S02): Table 'your_db.your_table' doesn't exist. You know the table's there—maybe you just ran a SELECT against it ten seconds ago. Happened to a client of mine last month with a WordPress site running WooCommerce. Orders table vanished mid-transaction. Panic mode.
Here's the fix that works 90% of the time:
-- Step 1: Check if the table physically exists
SHOW TABLES LIKE 'your_table';
-- Step 2: If it shows up, flush the table cache
FLUSH TABLES your_table;
-- Step 3: Try the query again
SELECT * FROM your_table LIMIT 1;If that doesn't work, you're dealing with a corrupted table definition in the InnoDB data dictionary. You'll need to rebuild it:
-- Step 1: Backup the table structure
mysqldump --no-data your_db your_table > your_table_struct.sql
-- Step 2: Drop the table (yes, really—this removes the corrupt dictionary entry)
DROP TABLE your_table;
-- Step 3: Recreate from backup
mysql your_db < your_table_struct.sql
-- Step 4: Insert data from a backup (or reload from your latest dump)I know dropping a table feels wrong when you're trying to fix it. But the InnoDB dictionary entry is corrupted, and the only way to clean it is to remove the bad record and recreate it fresh. As long as you have a backup, you're fine. And if you don't have a backup—well, now you know why you need one.
Why This Happens
MySQL's InnoDB engine stores table definitions in two places: the .frm files (or .ibd files in newer versions) and the internal data dictionary stored in the system tablespace (ibdata1). When these get out of sync—usually after an improper shutdown, a disk full error, or a crash—MySQL sees the data dictionary entry but the underlying file is missing or corrupted, or vice versa.
In the client case I mentioned, their server ran out of disk space during a peak sales hour. MySQL wrote part of the table definition, then died. Next startup: table 'doesn't exist' even though the .ibd file was fine. The dictionary entry was half-baked.
The FLUSH TABLES trick works because it forces MySQL to close and reopen the table, re-reading the definition from disk. If the file's intact, that's often enough. But when the dictionary itself is corrupt, you have to rebuild it.
Less Common Variations
Not every case is identical. Here are a few variations I've seen:
Variation 1: Table Shows in SHOW TABLES but Not in INFORMATION_SCHEMA
You see the table in SHOW TABLES but SELECT * FROM INFORMATION_SCHEMA.TABLES doesn't list it. This usually means the .frm file is fine but the InnoDB dictionary entry was never created or got dropped. Try ALTER TABLE your_table ENGINE=InnoDB; or, if that fails, dump the structure, drop, and recreate as above.
Variation 2: Table Exists in One Database but Not When Referenced with Database Prefix
You can select from the table directly, but SELECT * FROM db.table errors out. I've seen this when a user has a database name with special characters or when the MySQL data directory got messed up. Check the actual directory name under /var/lib/mysql/. It must match the database name exactly, case-sensitive on Linux.
Variation 3: Error After a MySQL Upgrade or Migration
When you move MySQL to a newer version or different host, sometimes the table definition format changes. Older .frm files don't always play nice with newer servers. The fix here is to run mysql_upgrade or re-import the table from a dump.
Variation 4: Locked Table After a Long-Running Query
This isn't really a missing table, but the error message is identical. A long-running transaction can lock the table definition. Kill the offending process with SHOW PROCESSLIST and KILL <thread_id>;.
Prevention
You can't prevent every corruption, but you can stack the odds in your favor:
- Enable
innodb_force_recoveryonly as a last resort — it lets MySQL start in read-only mode, but it can mask the underlying issue. Set it to 1, diagnose, then set back to 0. - Backup daily — and test your backups. A backup you can't restore isn't a backup.
- Use
innodb_file_per_table— it's the default in MySQL 5.6+, but if you're on an old version, enable it. Each table gets its own.ibdfile, so corruption doesn't spread. - Monitor disk space — set up alerts at 80% full. A full disk during a write is the #1 cause of table corruption I've seen.
- Upgrade gracefully — always run
mysql_upgradeafter a major version upgrade. And take a full dump before, just in case.
One last thing: if you're on a shared hosting plan that uses MySQL with InnoDB and you get this error repeatedly, it's usually because the host's ibdata1 is bloated or corrupt. You can't fix their server, but you can export your data and move to a host that knows what they're doing. I've had three clients move away from the same budget host because of exactly this problem.