# InnoDB Page Corruption: Recover a Crashed MariaDB on cPanel

Source: https://srvscripts.com/guides/innodb-page-corruption-repair/
Updated: 2026-10-07
Publisher: srvScripts (https://srvscripts.com/)

**Short answer:** InnoDB page corruption means MariaDB read a data page whose checksum or contents are wrong, usually after a power loss, a full disk, bad RAM or a failing drive. Stop MariaDB, take a file-level copy of `/var/lib/mysql`, then start it with `innodb_force_recovery = 1` (raising it one step at a time only if needed), dump every database you can with `mariadb-dump`, set recovery back to 0 and rebuild the damaged tables from those dumps. If you cannot get a clean dump, or the damage is in the shared system tablespace, restore from your last good backup instead.

We ran the read-only checks on this page (the log and variable queries, `CHECK TABLE` and `mariadb-check`) on our lab server (AlmaLinux 9.8, cPanel & WHM 11.138, MariaDB 10.11.19) on 7 October 2026. We did not put the lab into recovery mode or restart it: the recovery steps were checked against the MariaDB documentation and the MariaDB 10.11 source code on the same day.

## “InnoDB: Database page corruption on disk or a failed file read” and the MariaDB 10.11 wording

The message people search for has changed over the years. Which one you see depends on the server version:

| Server | What the error log says |
| --- | --- |
| MySQL 8.0 / 8.4 | Database page corruption on disk or a failed file read of page [page id: space=…, page number=…]. You may have to recover from a backup. |
| MariaDB 10.5 and older | Database page corruption on disk or a failed read of file '…' page [page id: space=…, page number=…]. You may have to recover from a backup. |
| MariaDB 10.6 and newer (including 10.11 and 11.x on cPanel) | InnoDB: Failed to read page N from file './db/table.ibd': Page read from tablespace is corrupted. followed by InnoDB: You can use CHECK TABLE to scan your table for corruption. |

Queries that hit a damaged table can also leave this line in the log, and websites show the same text in their database error:

```
[ERROR] mariadbd: Index for table 'wp_options' is corrupt; try to repair it
```

MariaDB maps InnoDB’s “page corrupted” status to this generic handler error, so the advice to “repair it” is misleading: `REPAIR TABLE` works for Aria, MyISAM, Archive and CSV tables, not InnoDB (MariaDB’s [REPAIR TABLE page](https://mariadb.com/docs/server/reference/sql-statements/table-statements/repair-table) points InnoDB users to recovery modes). Worse cases end in an `InnoDB: Assertion failure` and the server crashing on every start.

On cPanel the error log is in the data directory and named after the hostname. Ask the server where it is, then search it:

```
mariadb -N -e "SELECT @@datadir, @@log_error, @@innodb_force_recovery"
grep -nE 'Failed to read page|page corruption|is corrupt|Assertion failure' /var/lib/mysql/$(hostname).err | tail -20
```

If MariaDB is down, the first command fails; read the log path from `/etc/my.cnf` (`log-error`) or look for `/var/lib/mysql/*.err`. Note the file names in the messages: they tell you which database and table are damaged.

## Step 1: stop the restart loop and take a file-level copy

**Do this before anything else.** Recovery modes 4 to 6 can damage data further, and a dump-and-rebuild deletes files. A copy of the data directory taken with MariaDB stopped is your only way back if a later step goes wrong. Never delete `ibdata1` or `ib_logfile0` to “get it started”: that throws away the data dictionary and the redo log.

cPanel’s service monitor (chkservd) restarts a crashed MariaDB, which can keep a crash loop going while you work. Turn monitoring off for the database service, stop it, check free space and copy the directory:

```
whmapi1 configureservice service=mysql enabled=1 monitored=0
systemctl stop mariadb
df -h /var/lib/mysql /root
du -sh /var/lib/mysql
cp -a /var/lib/mysql /root/mysql-copy-$(date +%F)
```

You need as much free space as `du` reports, plus room for the dumps later. If the disk is full, that may be the cause of the crash: free space first (see [cPanel disk full cleanup](/guides/cpanel-disk-full-cleanup/)) and try a normal start before using recovery modes. If the copy will not fit on the server, copy to another disk or host with `rsync -a`. Also check the kernel log for disk or memory errors (`dmesg -T | grep -iE 'i/o error|ext4|xfs|mce'`): if the hardware is failing, move to new disks before you rebuild.

## Step 2: see how much is damaged with CHECK TABLE and mariadb-check

If MariaDB is still running (corruption often hits one table and the rest of the server keeps working), check the tables named in the log first, then the whole server:

```
mariadb -e "CHECK TABLE site1_wp.wp_options EXTENDED;"
mariadb-check --databases site1_wp
mariadb-check --all-databases
```

This is the real output from our lab, where the tables are healthy:

```
Table	Op	Msg_type	Msg_text
site1_wp.wp_options	check	status	OK

site1_wp.wp_commentmeta                            OK
site1_wp.wp_comments                               OK
site1_wp.wp_links                                  OK
site1_wp.wp_options                                OK
...
```

A damaged table shows `error` or `Corrupt` in the `Msg_type`/`Msg_text` columns instead. `mariadb-check` runs `CHECK TABLE` for you (`--check` is its default). The `EXTENDED` option is used by InnoDB from MariaDB 10.6.11 onwards; older versions ignore it.

MariaDB’s [CHECK TABLE documentation](https://mariadb.com/docs/server/reference/sql-statements/table-statements/check-table) warns that if CHECK TABLE finds an error in an InnoDB table, the server might shut down to prevent the error spreading. Take the Step 1 copy before checking a table you already suspect.

Write down every damaged table. If only one or two non-critical tables are affected and the server runs, you may be able to skip recovery mode: dump the database now (Step 4), drop the bad table and reload it.

## Step 3: start MariaDB with innodb_force_recovery, one level at a time

`innodb_force_recovery` does not repair anything. It tells InnoDB to skip parts of crash recovery so the server can start and you can read data out. Higher levels include everything the lower levels do. From MariaDB 10.6.5 (so on any current cPanel MariaDB) the levels are:

| Level | What InnoDB skips | Risk |
| --- | --- | --- |
| 1 | Keeps running when it finds corrupt pages; skips redo log for affected pages, and lets SELECT * jump over corrupt indexes and pages | Only corrupt pages should be lost |
| 2 | Stops the master thread, so no purge runs (undo logs keep growing) | Low; use when the crash happens during purge |
| 3 | Does not roll back DML transactions left over from the crash | Uncommitted changes stay as they were |
| 4 | Does not roll back transactions (including DDL) after crash recovery | Secondary indexes may be corrupted |
| 5 | Treats incomplete transactions as committed and does not read the undo logs at start-up | Inconsistent results, damaged indexes |
| 6 | Skips redo log roll-forward entirely | Pages left in an old state; may cause more corruption; queries that use indexes are likely to fail |

MariaDB’s documentation says write transactions are only allowed at low levels (its summary says 3 or less). Treat the server as read-only for the whole time it runs in recovery mode, and keep websites away from it.

Add the setting under `[mysqld]` in `/etc/my.cnf`, start MariaDB and check the log:

```
[mysqld]
innodb_force_recovery = 1
```

```
systemctl start mariadb
systemctl status mariadb --no-pager
tail -50 /var/lib/mysql/$(hostname).err
```

If it still crashes, stop it, change the value to 2 and try again, then 3. MariaDB’s own advice is to start at 1 and go up in single steps; if level 2 works, the damage may be limited to the undo logs. Only go to 4 or higher if you accept that some data and indexes will be lost, and only after the Step 1 copy exists. While the server runs in recovery mode, consider blocking web traffic (for example by stopping Apache or LiteSpeed briefly) so nothing tries to write.

## Step 4: dump what you can, then rebuild the damaged tables

With the server up in recovery mode, dump each database to its own file. Per-database files make it easy to see which one fails, and you will want the user accounts and grants too:

```
mkdir -p /root/recovery-dumps && cd /root/recovery-dumps
for db in $(mariadb -N -e "SHOW DATABASES" | grep -vE '^(information_schema|performance_schema|sys)$'); do
  echo "== $db"
  mariadb-dump --routines --triggers --events "$db" > "$db.sql" || echo "FAILED: $db"
done
mariadb-dump --system=users > grants.sql
ls -lh
```

If one table crashes the server during the dump, restart in the same recovery level and dump that database table by table, skipping the bad one (`--ignore-table=db.table`). MariaDB also suggests reading a damaged table backwards from the end with `SELECT * FROM tab ORDER BY primary_key DESC` to rescue the rows after the corrupt part.

### Rebuild only the damaged database (preferred)

Remove `innodb_force_recovery` from `/etc/my.cnf` (or set it to 0) and restart. If MariaDB now starts normally and only some tables were damaged, rebuild just those databases:

**Destructive:** `DROP DATABASE` removes the database permanently. Check that the dump file is complete (it should end with a `-- Dump completed` line) and that the Step 1 copy exists before you run it.

```
tail -1 /root/recovery-dumps/site1_wp.sql
mariadb -e "DROP DATABASE site1_wp; CREATE DATABASE site1_wp;"
mariadb site1_wp < /root/recovery-dumps/site1_wp.sql
mariadb-check --databases site1_wp
```

The database name stays the same and MariaDB does not remove grants when a database is dropped, so the account’s database users keep their access. Rebuilding a single table works the same way if you dumped only that table.

### Full rebuild (system tablespace damaged)

If MariaDB only starts with recovery mode on, or the errors point at `ibdata1` or the `mysql` database, the whole data directory has to be re-created. MariaDB’s documented procedure is: dump everything, stop the server, remove the InnoDB files, start it and re-import. On a cPanel server the safer form is to move the old directory aside instead of deleting it:

```
systemctl stop mariadb
# remove innodb_force_recovery from /etc/my.cnf first
mv /var/lib/mysql /var/lib/mysql.broken-$(date +%F)
mariadb-install-db --user=mysql --datadir=/var/lib/mysql
systemctl start mariadb
```

Then import `grants.sql` and each database dump. Then check that `mariadb -e "SELECT 1"` still works as root with cPanel’s stored credentials; if it does not, reset the root password in WHM’s MySQL Root Password page so cPanel can manage databases again. This is the riskiest path in this guide: if you have a recent full backup, restoring it is usually faster and cleaner (next section).

## When to restore from backup instead

Recovery modes save data you have no other copy of. They are the wrong tool when a good backup exists. Restore instead when:

- The dump fails for important tables even at level 3, or only works at 5 or 6 (the data you get may be inconsistent).

- The damage is in `ibdata1` or the system tables and you have a full nightly backup from before the crash.

- The corruption came back after a rebuild, which points at hardware: restore onto healthy disks.

- You need an exact state for an online shop or billing database: restore the last full backup, then replay binary logs to just before the crash (see [MariaDB point-in-time recovery with binary logs](/guides/mariadb-point-in-time-recovery-binlogs/)).

For single accounts on cPanel, JetBackup or WHM backups can restore one database without touching the rest (see [JetBackup 5 restore](/guides/jetbackup-5-restore-admin/)). If MariaDB will not start for other reasons, such as an upgrade, an unknown variable or a permission problem, use the [MySQL/MariaDB crash recovery runbook](/guides/runbook-mysql-crashed/) or [MariaDB not starting after upgrade](/guides/mariadb-not-starting-after-upgrade/) instead. If you would rather hand it over, our [Get it fixed](/get-it-fixed/) service does this kind of recovery.

## Check that it worked

- Recovery mode is off: `mariadb -N -e "SELECT @@innodb_force_recovery"` prints `0`.

- All tables check clean: `mariadb-check --all-databases | grep -v OK` prints nothing (or only notes you understand).

- The log has no new corruption lines: rerun the `grep` from the first section and compare timestamps.

- Monitoring is back on: `whmapi1 configureservice service=mysql enabled=1 monitored=1`, then `whmapi1 servicestatus service=mysql` shows `running: 1` and `monitored: 1`.

- The affected sites load, can log in and can save (a write test matters: recovery mode was read-only).

- Take a fresh full backup now, and keep the Step 1 copy until you are sure nothing is missing.

## Common problems

- **MariaDB still crashes at level 6.** Stop. Do not try more settings on the only copy: restore from backup, or work on a second server using the Step 1 copy.

- **“Tablespace is missing” or “Cannot open tablespace” after a restore.** A table’s `.ibd` file and the data dictionary no longer match, often after files were copied by hand. Rebuild that database from a dump instead of copying `.ibd` files around.

- **Dump stops with “Lost connection to server during query”.** The server crashed on a damaged table. Restart in recovery mode, find the table from the error log and dump around it.

- **Corruption returns days later.** Check disk SMART data, RAID status and RAM. Software cannot fix a failing drive.

- **cPanel users cannot connect after a full rebuild.** The grants were not imported. Import `grants.sql`, then test a database user from the account.

**Official documentation:** [MariaDB: InnoDB recovery modes](https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-troubleshooting/innodb-recovery-modes) · [MariaDB: CHECK TABLE](https://mariadb.com/docs/server/reference/sql-statements/table-statements/check-table) · [MariaDB: mariadb-check](https://mariadb.com/docs/server/clients-and-utilities/table-tools/mariadb-check) · [cPanel API: configureservice](https://api.docs.cpanel.net/openapi/whm/operation/configureservice)

**Related:** [MySQL/MariaDB won’t start: crash recovery runbook](/guides/runbook-mysql-crashed/) · [MariaDB point-in-time recovery with binary logs (and 13.0’s innodb_log_archive)](/guides/mariadb-point-in-time-recovery-binlogs/) · [MariaDB Not Starting After Upgrade: 5 Recovery Fixes](/guides/mariadb-not-starting-after-upgrade/) · [JetBackup 5 Restore in WHM: Accounts, Files, Databases, Email](/guides/jetbackup-5-restore-admin/) · [MySQL Health Snapshot Script: Free 10-Second MariaDB Check](/scripts/mysql-health-snapshot/)

**See also:** [MySQL/MariaDB won’t start: crash recovery runbook](/guides/runbook-mysql-crashed/) · [MariaDB point-in-time recovery with binary logs (and 13.0’s innodb_log_archive)](/guides/mariadb-point-in-time-recovery-binlogs/) · [MariaDB Not Starting After Upgrade: 5 Recovery Fixes](/guides/mariadb-not-starting-after-upgrade/)

## Frequently asked questions

### What causes InnoDB page corruption?

Usually something outside MariaDB: a power loss or hard reset, a full disk, faulty RAM, a failing drive or RAID controller, or copying data files while the server was running. Bugs are rarer. If it happens twice, check the hardware.

### Which innodb_force_recovery level should I use?

Start at 1 and go up one step only if MariaDB still will not start. Levels 1 to 3 should only lose corrupt pages; 4 and above can damage indexes and return inconsistent data, so take a file-level copy before trying them.

### Can I leave innodb_force_recovery on?

No. It is an emergency setting for getting data out. Treat the server as read-only while it is on, and set it back to 0 as soon as you have your dumps.

### Does REPAIR TABLE fix InnoDB tables?

No. REPAIR TABLE works for Aria, MyISAM, Archive and CSV. For InnoDB you dump the data and rebuild the table, or restore from backup.

### Is it safe to delete ib_logfile0 or ibdata1 to get MariaDB to start?

No. Those files hold the redo log and the system tablespace. Deleting them can make every InnoDB table unreadable. Only remove them as part of a full rebuild after you have dumped all data.

### Should I restore a backup or try recovery mode first?

If you have a recent backup and can accept losing the changes since then, restoring is safer. Use recovery mode when the newest data matters and no backup has it, and always copy the data directory first.
