How to repair MySQL databases and tables Print

  • mysql, mariadb, repair, innodb, myisam
  • 79

MySQL and MariaDB include several tools for checking and repairing tables. Work through the steps in the order below: each one is safe to try before the next, and the later ones carry more risk.

If you have a recent backup, restoring it is usually faster and always safer than repairing. Repair tools work on damaged data and can discard rows they cannot make sense of. Only continue if you have no usable backup, or need data written since the last one.

Step 1. Copy the data files first

Before running any repair, take a copy of the raw data directory. Every later step can make matters worse, and this copy is what allows a second attempt.

systemctl stop mariadb        # or mysql / mysqld
cp -a /var/lib/mysql /var/lib/mysql.backup.$(date +%s)
systemctl start mariadb

The service name differs by system: mariadb on most current distributions, mysql on Debian and Ubuntu with MySQL, mysqld on older RHEL-based systems. Check with systemctl list-units | grep -E 'mysql|maria'.

Check free space before copying — df -h /var/lib — and keep a copy off the server as well if the data matters.

Step 2. Check and repair with mysqlcheck

mysqlcheck works while the server is running, which makes it the first thing to try.

Check one database:

mysqlcheck -u root -p DATABASE

Check a single table in it:

mysqlcheck -u root -p DATABASE TABLE

Check everything:

mysqlcheck -u root -p --all-databases

Tables that pass are reported as OK. To attempt a repair of those that do not:

mysqlcheck -u root -p --repair DATABASE TABLE

If this resolves the problem, stop here. If not, continue with the section matching the storage engine of the affected table. To find out which engine a table uses:

mysql -u root -p -e "SHOW TABLE STATUS FROM DATABASE;"

Modern installations use InnoDB for almost everything; MyISAM appears mainly in older applications.

Step 3a. MyISAM tables: myisamchk

myisamchk works only on MyISAM tables, and only with the server stopped — running it against a live server will corrupt the tables further.

systemctl stop mariadb
cd /var/lib/mysql/DATABASE

Check one table, or all of them:

myisamchk TABLE
myisamchk *.MYI

If the check fails because of leftover temporary files, remove them and try again:

ls *.TMD
rm *.TMD

To repair:

myisamchk --recover TABLE

If that is not enough, a more aggressive repair is available — but it can discard rows, so use it only after the safe option has failed:

myisamchk --safe-recover TABLE

Then start the server and verify the table:

systemctl start mariadb

Step 3b. InnoDB tables: recovery mode

If InnoDB will not start at all, or a table cannot be read, start the server in recovery mode long enough to dump the data, then rebuild.

Add to the [mysqld] section of the configuration file — /etc/my.cnf on RHEL-based systems, /etc/mysql/my.cnf on Debian and Ubuntu:

innodb_force_recovery = 1

Restart and, as soon as the server is up, export everything:

systemctl restart mariadb
mysqldump -u root -p --all-databases --add-drop-database --add-drop-table > /root/databases.sql

If the server still does not start, raise the value step by step — 2, then 3, then 4 — restarting after each change, and stop as soon as a dump succeeds.

Do not go above 4 unless nothing else works. Levels 5 and 6 discard transactions and can leave the data permanently inconsistent. In recovery mode treat the database as read-only: take the dump and nothing else.

With a dump you trust, drop the damaged databases, remove the recovery setting, restart normally and import:

mysql -u root -p -e "DROP DATABASE DBNAME;"

If the drop fails, stop the server and remove the directory by hand:

systemctl stop mariadb
rm -rf /var/lib/mysql/DBNAME

Do not delete the mysql, sys, performance_schema or information_schema directories. They hold the server's own metadata and user accounts.

Then comment out the recovery line:

#innodb_force_recovery = 1

and restart and import:

systemctl start mariadb
mysql -u root -p < /root/databases.sql

Step 4. Verify

Run mysqlcheck --all-databases again, then open the application and check the parts that use the affected tables. A database that passes a check can still be missing rows the repair discarded.

Why it happened

Table corruption is usually a symptom rather than a cause: a full disk during a write, an abrupt power loss, faulty memory, or database files on network storage. Check free space and, if it recurs on the same server, open a ticket so that we can examine the hardware.

For a detailed walkthrough of InnoDB corruption on a Plesk server, see How to recover from InnoDB corruption in MySQL on Plesk for Linux. For backups, see Backing up your account and websites in Plesk.

If you are unsure at any point, stop and open a ticket from your client area with the MySQL error log attached. Recovery attempts made in the wrong order are the usual reason data ends up unrecoverable.


Was this answer helpful?

« Back