如何修复MySQL中损坏的表

有时,MySQL表可能会损坏,这意味着发生了错误,并且其中包含的数据是不可读的。尝试从损坏的表中读取通常会导致服务器崩溃。表损坏的一些常见原因是:MySQL服务器在中间停止...

本系列的一部分: 如何解决MySQL中的问题

本指南旨在用作诊断MySQL设置时的故障排除资源和起点。 我们将讨论许多MySQL用户遇到的一些问题,并提供解决特定问题的指导。 我们还将包含指向DigitalOcean教程的链接以及在某些情况下可能有用的官方MySQL文档。

有时,MySQL表可能会损坏,这意味着发生了错误,并且其中包含的数据是不可读的。 尝试从损坏的表中读取通常会导致服务器崩溃。

表损坏的一些常见原因是:

  • MySQL服务器在写入过程中停止。
  • 外部程序修改由服务器同时修改的表。
  • 机器意外关闭。
  • 计算机硬件出现故障。
  • MySQL代码中有一个软件错误。

如果您怀疑其中一个表已损坏,则应在排除故障或尝试修复表之前备份数据目录。 这有助于最大限度地降低数据丢失的风险。

首先,停止MySQL服务:

sudo systemctl stop mysql

然后将所有数据复制到新的备份目录中。 在Ubuntu系统上,默认数据目录是/var/lib/mysql/

cp -r /var/lib/mysql /var/lib/mysql_bkp

进行备份后,您就可以开始调查表实际上是否已损坏。 如果表使用MyISAM存储引擎 ,您可以通过从MySQL提示符运行CHECK TABLE语句来检查它是否已损坏:

CHECK TABLE table_name;

此语句的输出中将显示一条消息,告知您是否已损坏。 如果MyISAM表确实已损坏,通常可以通过发出REPAIR TABLE语句来修复它:

REPAIR TABLE table_name;

假设修复成功,您将在输出中看到如下消息:

+--------------------------+--------+----------+----------+
| Table                    | Op     | Msg_type | Msg_text |
+--------------------------+--------+----------+----------+
| database_name.table_name | repair | status   | OK       |
+--------------------------+--------+----------+----------+

但是,如果表仍然存在损坏,那么MySQL文档提供了一些修复损坏表的替代方法

另一方面,如果损坏的表使用InnoDB存储引擎 ,那么修复它的过程将会有所不同。 从版本5.5开始,InnoDB是MySQL中的默认存储引擎,它具有自动损坏检查和修复操作。 InnoDB通过在其读取的每个页面上执行校验和来检查损坏的页面,如果它发现校验和差异,它将自动停止MySQL服务器。

很少需要修复InnoDB表,因为InnoDB具有崩溃恢复机制,可以在服务器重新启动时解决大多数问题。 但是,如果您确实遇到需要重建损坏的InnoDB表的情况,则MySQL文档建议使用“转储和重新加载”方法 这涉及重新访问损坏的表,使用mysqldump实用程序创建表的逻辑备份 ,该表将保留表结构及其中的数据,然后将表重新加载回数据库。

考虑到这一点,尝试重新启动MySQL服务,看看这样做是否允许您访问服务器:

sudo systemctl restart mysql

如果服务器仍然崩溃或无法访问,那么启用InnoDB的force_recovery选项可能会有所帮助。 您可以通过编辑mysqld.cnf文件来完成此操作:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

[mysqld]部分中,添加以下行:

/etc/mysql/mysql.conf.d/mysqld.cnf
. . .
[mysqld]
. . .
innodb_force_recovery=1

保存并关闭该文件,然后再次尝试重新启动MySQL服务。 如果可以成功访问损坏的表,请使用mysqldump实用程序将表数据转储到新文件。 你可以随意命名这个文件,但是在这里我们将它命名为out.sql

mysqldump database_name table_name > out.sql

然后从数据库中删除表。 为避免重新打开MySQL提示符,可以使用以下语法:

mysql -u user -p --execute="DROP TABLE database_name.table_name"

在此之后,使用刚刚创建的转储文件恢复表:

mysql -u user -p < out.sql

请注意,InnoDB存储引擎通常比旧的MyISAM引擎更具容错能力。 使用InnoDB的表仍然可以被破坏,但由于其自动恢复功能 ,表损坏和崩溃的风险明显降低。