简介
有时,MySQL 表可能会损坏,这意味着发生了错误,其中保存的数据无法读取。尝试从损坏的表中读取通常会导致服务器崩溃。
一些常见的表损坏原因包括:
- MySQL 服务器在写入过程中停止。
- 外部程序修改了正在被服务器同时修改的表。
- 机器意外关闭。
- 计算机硬件故障。
- MySQL 代码中存在软件错误。
如果你怀疑你的表之一已经损坏,你应该在排除故障或尝试修复表之前备份数据目录。这将有助于最小化数据丢失的风险。
首先,停止 MySQL 服务:
sudo systemctl stop mysql
然后将所有数据复制到一个新的备份目录。在 Ubuntu 系统上,默认数据目录是 /var/lib/mysql/
:
cp -r /var/lib/mysql /var/lib/mysql_bkp
备份完成后,你可以开始调查表是否确实损坏。如果表使用 MyISAM 存储引擎,你可以通过重新启动 MySQL 并从 MySQL 提示符下运行 CHECK TABLE
语句来检查它是否损坏:
sudo systemctl start mysql
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 存储引擎,那么修复它的过程将会有所不同。InnoDB 是 MySQL 8.0 版本的默认存储引擎,它具有自动损坏检查和修复操作。InnoDB 通过对其读取的每个页面执行校验和来检查损坏的页面,如果发现校验和不一致,它将自动停止 MySQL 服务器。
通常情况下不需要修复 InnoDB 表,因为 InnoDB 具有崩溃恢复机制,可以在服务器重新启动时解决大多数问题。但是,如果你遇到需要重建损坏的 InnoDB 表的情况,MySQL 文档建议使用 “Dump and Reload” 方法。这涉及重新获得对损坏表的访问,使用 mysqldump
实用程序创建表的 逻辑备份,它将保留表结构和其中的数据,然后将表重新加载到数据库中。
考虑到这一点,尝试重新启动 MySQL 服务,看看这样是否能让你访问服务器:
sudo systemctl restart mysql
如果服务器仍然崩溃或无法访问,那么启用 InnoDB 的 force_recovery
选项可能会有所帮助。你可以通过编辑 mysqld.cnf
文件来实现这一点。在 Ubuntu 和 Debian 系统上,该文件通常位于 etc/mysql
。在 Red Hat 和 Rocky 系统上,该文件通常位于 /etc/my.cnf.d
。
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
在 [mysqld]
部分,添加以下行:
. . .
[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 的表 可能 仍然会损坏,但由于其自动恢复功能,表损坏和崩溃的风险明显较低。