XAMPP data_old recovery:
getting your databases back
Updated
Read this first
If you have not started yet, and MySQL simply will not start, the ordinary recovery is on the “MySQL shutdown unexpectedly” page. Do that one. It works in most cases.
This page is for when it did not: the backup
folder is missing, your tables came back empty, you are looking at error 1932, or all you have left is a
folder of .ibd files.
Before anything else: copy the whole data_old folder somewhere safe.
Every technique below is safer when you are working on a copy.
What is actually in that folder
Most recovery guides tell you which files to copy without saying what they are, which is why so many recoveries end with tables that exist but contain nothing. Here is the map.
| File or folder | What it holds | Recover it? |
|---|---|---|
| ibdata1 | InnoDB's shared tablespace: the data dictionary that maps table names to internal IDs, undo logs, and — on older configurations — the actual row data. | Yes, always |
| <dbname>/ | One folder per database. Contains the table files for that database. | Yes, yours only |
| *.ibd | One per InnoDB table: that table's rows and indexes, when per-table tablespaces are on (the default for many years). | Yes, inside its db folder |
| *.frm | Table structure — columns, types, indexes. Not the data. | Yes |
| *.MYD / *.MYI | MyISAM data and index files. Self-contained, which makes MyISAM tables far easier to rescue. | Yes |
| ib_logfile0 / ib_logfile1 | The redo log. This is the file whose mismatch with the data files caused the failure. | No — leave behind |
| ibtmp1 | Temporary tablespace, recreated at every start. | No |
| aria_log_control | MariaDB's Aria engine control file. Used by system tables. A corrupt one blocks startup on its own. | No — see below |
| mysql/ performance_schema/ | The server's own system databases. Take these from the clean backup, not from the damaged folder. | No |
The single rule that explains most failed recoveries: for InnoDB, the
.frm files and
ibdata1 must come from the same moment in time. Mix a table
definition from one point with a data dictionary from another and MySQL will see a table it has no record of.
“My tables are there but empty”
This is the most common way the standard recovery goes wrong, and it is a one-file fix. You copied your
database folders from data_old, but left
ibdata1 as the pristine one that came from
backup. The structures came across; the data dictionary
pointing at your rows did not.
Stop MySQL, copy ibdata1 from
data_old into the new
data folder overwriting what is there, and start it again. Do
not copy ib_logfile0 or
ib_logfile1 with it.
Error 1932: “Table doesn't exist in engine”
Same root cause, louder symptom. MySQL found a .frm file, asked
InnoDB for the matching table, and InnoDB said it has never heard of it. The fix is the same: get the
ibdata1 that belongs with those table files back into place.
If you have already overwritten the original ibdata1 and have
no copy of it, the .frm and
.ibd files are still useful, but you are now in the
tablespace-import case further down, which is slower and less certain. This is the reason for copying
data_old before you begin.
The backup folder is missing or empty
xampp\mysql\backup is what the standard recovery uses as its
clean starting point. Some installs do not have it, and some people delete it while troubleshooting. Three
ways forward, best first:
-
Borrow one. Install XAMPP again into a different folder, for example
C:\xampp-temp, and useC:\xampp-temp\mysql\backupas the clean base. Match the XAMPP version as closely as you can; a different MariaDB version in the system tables is a problem you do not want stacked on top of this one. -
Let MySQL rebuild the system tables. Some MariaDB builds shipped with
XAMPP will initialise a missing system database on first start. Point MySQL at an empty
datafolder and see what happens before assuming it will not. -
Skip the clean base entirely. Put the original data folder back as
dataand try to start it withinnodb_force_recovery, below. If it starts, export immediately — you are not fixing it, you are evacuating it.
Using innodb_force_recovery properly
Open xampp\mysql\bin\my.ini, find the
[mysqld] section, and add one line:
innodb_force_recovery=1
Start MySQL. If it fails, raise the number by one and try again. What the levels mean, in plain terms:
- 1 — carry on past corrupt pages instead of stopping. Safe.
- 2 — do not run the background work that flushes and purges. Safe.
- 3 — do not roll back unfinished transactions. Safe enough; some in-flight writes stay applied.
- 4 — skip index merges. Indexes may end up wrong.
- 5 — ignore undo logs entirely. Uncommitted transactions get treated as committed.
- 6 — do not replay the redo log at all. Pages stay as they were on disk, mid-write and all.
Treat 1 to 3 as ordinary troubleshooting and 4 to 6 as the fire escape. At levels above 3, expect the server to be read-only, which is fine — reading is all you need, because the only correct next step is to export everything and rebuild. Remove the line afterward. A server left running with force recovery set is not a working server.
The moment MySQL starts at any level, stop working on the repair and run the export. People lose databases by getting a server up, feeling relieved, and continuing to poke at it.
MariaDB will not start and the log mentions Aria
XAMPP ships MariaDB, and MariaDB's own system tables use the Aria engine rather than InnoDB. If
mysql_error.log points at
aria_log_control or the
aria_log.* files rather than InnoDB, that is a separate
failure wearing the same error message.
With MySQL stopped, move aria_log_control and any
aria_log.00000001-style files out of the data folder to a safe
location, then start MySQL. It regenerates them. Your InnoDB data is untouched by this; only Aria tables,
which in a default XAMPP install means system tables rather than yours, are affected.
When all you have is .ibd files
Last resort, and honest about the odds: this works when the table structure is known and the MySQL versions are close, and it fails often enough that you should not count on it. It also works one table at a time.
- On a working MySQL of the same major version, create the database and recreate the table with exactly the original
CREATE TABLEstatement. Column order, types, and indexes all have to match. - Run
ALTER TABLE yourtable DISCARD TABLESPACE;— this deletes the new, empty.ibd. - Copy the salvaged
.ibdinto the database folder, alongside where the new one was. Copy the matching.cfgtoo if you have one. - Run
ALTER TABLE yourtable IMPORT TABLESPACE; - Select from it. If the rows are there, export the table immediately before moving to the next one.
Without the .cfg file, the import may be refused outright or
may succeed and give you nonsense — check the data, do not just check that the command returned. If you
do not have the original CREATE TABLE statement, your
application's migrations, schema files, or version control usually do.
Export the moment you are in
Whatever got you running, the next command is an export. Not a restart, not further repair.
cd C:\xampp\mysql\bin mysqldump -u root --all-databases --routines --triggers --events > C:\rescue.sql
If that fails partway, export one database at a time — a single unreadable table will abort the whole run otherwise, and you would rather lose one table than all of them:
mysqldump -u root yourdatabase > C:\yourdatabase.sql
Then rebuild the data directory from clean and import rescue.sql.
A database restored from a dump has no inherited corruption. One rescued by file-copying carries whatever was
wrong with those files into the next install, which is how people end up doing this twice.
Not doing this again
Two things, and you need both.
Fix the shutdown. This corruption comes from MySQL being terminated rather
than asked to stop — XAMPP's control panel kills
mysqld.exe, and Windows update restarts finish the job.
Running MySQL as a Windows service changes that: the Service Control Manager sends
SERVICE_CONTROL_STOP, which MySQL handles by flushing InnoDB
to disk before it exits.
The longer explanation is here.
Take exports on a schedule. No shutdown strategy survives a failing disk. A
weekly mysqldump --all-databases into a folder your normal
backup already covers turns every future incident into an inconvenience.
Both, handled
Helm is a free, single-installer replacement for XAMPP on Windows. It registers Apache and MySQL as native Windows services so shutdowns are clean by default, and has one-click database backup built into the control panel. Apache, PHP, MariaDB and phpMyAdmin all come in the one installer.
Windows 10/11 · 64-bit · Free · MIT licensed