MySQL查询突然报 Table is marked as crashed and should be repaired,看到crashed很容易直接运行REPAIR TABLE。但这条错误最常见于MyISAM表,MariaDB中的Aria表也可能出现类似情况;InnoDB损坏的处理方式完全不同。
数据库修复最怕在没有备份、没有确认存储引擎的情况下连续尝试命令。修复操作本身会读写表文件,磁盘已经异常或文件仍被业务写入时,反复修复可能扩大损坏。正确顺序是先确认表、引擎和磁盘状态,再停止相关写入并保留原始文件。

确认具体表和存储引擎
先从应用日志和MySQL错误日志中记录数据库名、表名和首次报错时间,然后查询表状态:
SHOW TABLE STATUS FROM database_name LIKE 'table_name';
CHECK TABLE database_name.table_name;
结果中的Engine决定后续工具。MyISAM表通常对应 .MYD和 .MYI文件;MariaDB的Aria表常见 .MAD和 .MAI文件;InnoDB则由表空间和redo机制管理。
不要只根据文件扩展名操作,配置了独立表空间、分区表或版本差异时,文件布局会更复杂。先让数据库返回引擎信息更可靠。
检查磁盘与异常关机记录
表损坏经常发生在异常断电、磁盘写满、文件系统只读、存储I/O错误或数据库进程被强制终止之后。先检查系统和数据库状态:
df -hT
df -i
dmesg -T | grep -iE 'I/O error|read-only|filesystem|nvme|blk'
systemctl status mysql
journalctl -u mysql --since '2 hours ago'
磁盘仍然只读或持续出现I/O错误时,不应立即修表。先保护数据、检查云磁盘和文件系统健康,必要时从快照或备份恢复。底层存储不稳定,表修复成功也可能再次损坏。
同时确认分区有足够临时空间。REPAIR TABLE和离线工具可能需要创建临时文件,大表修复所需空间不应只按损坏索引大小估算。
停止写入并备份原始文件
先把相关业务切到维护状态,停止对损坏表的写入。还能读取的数据应优先导出;无法正常导出时,至少对数据目录或云磁盘创建一致性快照。
直接复制MyISAM表文件前,要确保表没有被写入。数据库仍在运行时复制变化中的数据和索引文件,得到的副本可能彼此不一致。停库会影响其他业务时,应先评估从备库或最近备份恢复的方案。
保留原始副本的意义在于修复失败后还能重新选择工具和参数。不要让第一次尝试就覆盖唯一一份损坏文件。
优先使用CHECK与REPAIR TABLE
确认是MyISAM表、存储稳定并已有备份后,可以先使用数据库内置命令:
CHECK TABLE database_name.table_name;
REPAIR TABLE database_name.table_name;
CHECK TABLE database_name.table_name;
普通REPAIR失败后,有些场景会考虑 REPAIR TABLE ... EXTENDED,但它可能非常耗时,并对大表产生明显I/O压力。正式执行前应评估维护窗口和剩余空间。
修复完成不等于数据完全正确。REPAIR主要恢复表结构和索引可用性,损坏期间已经丢失或截断的记录不会自动回来,仍需与备份、业务流水或副本进行核对。
数据库外工具必须离线使用
MyISAM还可以使用 myisamchk,但不能在mysqld仍可能访问表文件时直接运行。更安全的流程是停止数据库或确保目标表完全脱离服务,再对备份副本进行检查:
myisamchk table_name.MYI
myisamchk --recover table_name.MYI
MariaDB的Aria表应使用与版本匹配的 aria_chk,不要把myisamchk用于不同存储引擎。工具版本也应与数据库文件格式匹配,跨大版本直接处理文件风险较高。
离线修复后要检查文件属主和权限,再启动数据库并重新执行CHECK TABLE。不要看到命令退出码为0就跳过数据库层验证。
InnoDB不能照搬MyISAM方法
InnoDB表不支持用REPAIR TABLE修复物理损坏。遇到InnoDB页校验错误、表空间损坏或数据库无法启动,应优先从备份、只读副本或有效快照恢复。
innodb_force_recovery只适合紧急启动并导出还能读取的数据,不是长期运行参数。应从最低级别开始,在隔离副本中操作,并避免任何写入。级别越高,可能跳过的恢复步骤越多,数据一致性风险也越大。
需要复现恢复流程时,可以在 萤光云 建立与生产相同版本的隔离数据库,也可以使用按小时计费的 LightNode 验证备份导入和升级步骤。测试环境应使用脱敏副本,并限制数据库端口访问。
修复后检查数据与备份
表重新可读后,应检查行数、关键时间范围、索引和业务汇总数据,并执行一次新的逻辑备份。应用侧还要验证写入、更新、删除和事务流程,不能只测试SELECT。
CHECK TABLE database_name.table_name;
ANALYZE TABLE database_name.table_name;
mysqldump database_name table_name > table_name-after-repair.sql
大表导出要考虑磁盘空间和锁影响。确认备份可以在另一套环境恢复后,再结束维护状态。还应回查异常关机、磁盘告警和备份任务,避免只修表不解决根因。
合格的修复应同时满足表可读写、关键数据核对通过、备份能够恢复,并且底层磁盘或异常关机原因已经处理。
常见问题
REPAIR TABLE可以修复所有MySQL表吗?
不可以。它主要适用于MyISAM等支持修复的引擎,InnoDB物理损坏应通过备份恢复或紧急导出处理。
修复表会丢数据吗?
存在风险。修复可能丢弃无法恢复的记录或重建索引,因此必须先保留原始文件或一致性快照,并在修复后核对业务数据。
表修好后还需要做什么?
需要重新CHECK、验证应用读写、生成可恢复备份,并排查磁盘写满、I/O错误、强制关机或版本问题等根因。


