Emergency server help: get in touch

InnoDB Page Corruption: Recover a Crashed MariaDB on cPanel

Fix InnoDB page corruption on a cPanel MariaDB server: read the error, copy the data directory, use innodb_force_recovery safely, dump and rebuild, or restore from backup.

Published 13 min read

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.

Applies to MariaDB 10.11 (cPanel & WHM 11.138 on AlmaLinux 9)

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:

ServerWhat the error log says
MySQL 8.0 / 8.4Database 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 olderDatabase 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 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) 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 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:

LevelWhat InnoDB skipsRisk
1Keeps running when it finds corrupt pages; skips redo log for affected pages, and lets SELECT * jump over corrupt indexes and pagesOnly corrupt pages should be lost
2Stops the master thread, so no purge runs (undo logs keep growing)Low; use when the crash happens during purge
3Does not roll back DML transactions left over from the crashUncommitted changes stay as they were
4Does not roll back transactions (including DDL) after crash recoverySecondary indexes may be corrupted
5Treats incomplete transactions as committed and does not read the undo logs at start-upInconsistent results, damaged indexes
6Skips redo log roll-forward entirelyPages 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).

For single accounts on cPanel, JetBackup or WHM backups can restore one database without touching the rest (see JetBackup 5 restore). 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 or MariaDB not starting after upgrade instead. If you would rather hand it over, our Get it fixed service does this kind of recovery.

Check that it worked

  1. Recovery mode is off: mariadb -N -e "SELECT @@innodb_force_recovery" prints 0.
  2. All tables check clean: mariadb-check --all-databases | grep -v OK prints nothing (or only notes you understand).
  3. The log has no new corruption lines: rerun the grep from the first section and compare timestamps.
  4. Monitoring is back on: whmapi1 configureservice service=mysql enabled=1 monitored=1, then whmapi1 servicestatus service=mysql shows running: 1 and monitored: 1.
  5. The affected sites load, can log in and can save (a write test matters: recovery mode was read-only).
  6. 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 · MariaDB: CHECK TABLE · MariaDB: mariadb-check · cPanel API: configureservice

Related: MySQL/MariaDB won’t start: crash recovery runbook · MariaDB point-in-time recovery with binary logs (and 13.0’s innodb_log_archive) · MariaDB Not Starting After Upgrade: 5 Recovery Fixes · JetBackup 5 Restore in WHM: Accounts, Files, Databases, Email · MySQL Health Snapshot Script: Free 10-Second MariaDB Check

See also: MySQL/MariaDB won’t start: crash recovery runbook · MariaDB point-in-time recovery with binary logs (and 13.0’s innodb_log_archive) · MariaDB Not Starting After Upgrade: 5 Recovery Fixes

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.

Maintenance record

This guide changes servers, data or security settings, so we re-check it against current versions on a fixed schedule. Take a backup or snapshot before you start.

Maintained by
srvScripts editorial team
Supported versions
MariaDB 10.11 (cPanel & WHM 11.138 on AlmaLinux 9)
Last full review
Next review

Free website test

Is your website set up right?

Check SSL, security headers, redirects, robots.txt, sitemap, llms.txt and security.txt in one test. It takes about 30 seconds.