必须停掉mysqld进程,因myisamchk修复需独占访问.MYI文件,否则报warning并中止;修复前须确认引擎为MyISAM、备份三文件、确保磁盘空间≥.MYD大小的2倍,再依损坏程度选用-r、--safe-recover或--use-frm模式。

myisamchk修复前必须停掉mysqld
MySQL进程运行时,myisamchk 无法安全写入 .MYI 文件——它会直接报 warning: clients are using or haven't closed the table properly 并中止。这不是“建议停”,是硬性前提。
执行顺序必须是:
-
sudo systemctl stop mysql(确认进程已退出:ps aux | grep mysqld) - 用
SELECT @@datadir;查出真实数据路径,比如/var/lib/mysql - 定位到目标表的
.MYI文件:/var/lib/mysql/db_name/table_name.MYI
三种修复模式怎么选:-r、--safe-recover、USE_FRM
别一上来就 --safe-recover ——它慢、耗内存、且只在数据页也乱了时才需要。先按损坏程度递进尝试:
- 轻度索引断裂(错误日志含
Incorrect key file或Key block size is wrong):myisamchk -r /path/to/table_name.MYI(-r即--recover,重建索引+校验数据块) - 修复失败或提示
record delete-link chain broken:myisamchk --safe-recover --force /path/to/table_name.MYI(从.MYD中逐行提取可读记录,跳过坏块) -
.MYI文件丢失或myisamchk -s直接报Can't read meta-data:myisamchk --recover --use-frm /path/to/table_name.MYI(注意不是 SQL 层的USE_FRM,命令行要用--use-frm)
磁盘空间和备份是硬门槛,不是可选项
myisamchk 修复过程不回滚、不预检空间,一旦失败,可能留下半截 .TMD 临时文件 + 损坏碎片,后续更难处理。
- 运行前先跑
df -h /var/lib/mysql:剩余空间必须 ≥ 对应.MYD文件大小的 2 倍(--safe-recover会生成完整副本) - 必须备份三件套:
cp /var/lib/mysql/db_name/table_name.{MYD,MYI,FRM} /backup/——哪怕只保.MYI和.FRM,也能为后续重建留条后路 - 别碰
-f(--force)除非你明确接受丢数据:-f会让myisamchk在遇到校验失败时直接跳过整块,而不是尝试抢救
修复完不等于完事:验证和ANALYZE要跟上
启动 mysqld 后立刻连上去验证,别信“没报错就修好了”:
- 执行
SHOW TABLE STATUS LIKE 'table_name';,确认Comment列不再含crashed,且Rows数量合理(明显偏少说明丢了数据) - 立刻跑
ANALYZE TABLE table_name;:修复后的索引统计信息是空的或过期的,不更新会导致查询走全表扫描 - 如果应用依赖唯一索引(如
username),务必查SELECT COUNT(*) FROM table_name GROUP BY column_name HAVING COUNT(*) > 1;——myisamchk -r不修复重复键问题
Engine=MyISAM 就对着 InnoDB 表跑 myisamchk,结果既不报错也不生效,白白浪费时间。


















