最可靠方法是查询information_schema.tables表:select table_name, engine from information_schema.tables where table_schema = 'your_db_name' and engine = 'myisam';需替换库名,注意engine值大小写敏感,权限不足会报错。

怎么快速找出库里还有哪些MyISAM表
直接查 information_schema.TABLES 最可靠,SHOW TABLES 不带引擎信息,没法筛。别指望靠文件后缀或目录结构肉眼判断——尤其是混用引擎的库,.MYD 和 .MYI 文件可能还残留着,但表早已被 DROP 或转成 InnoDB。
执行这条语句就能定位全部 MyISAM 表:
SELECT table_name, engine FROM information_schema.TABLES WHERE table_schema = 'your_db_name' AND engine = 'MyISAM';
注意替换 your_db_name;如果不确定库名,先跑 SELECT DATABASE(); 确认当前库,或用 SHOW DATABASES; 列出所有库再逐个查。
- 权限不够会报
Access denied,需要SELECT权限访问information_schema -
engine字段大小写敏感,必须写全大写的'MyISAM',写成'myisam'或'myisam'查不到 - 结果为空不等于绝对安全——有些表可能已损坏到无法读取元数据,
information_schema里就没了记录,得结合错误日志和文件系统检查
CHECK TABLE 报错但表还在 information_schema 里,是残留还是真损坏
这种情况很常见:表能列出来,但一查就崩,比如报 Table is marked as crashed 或 Incorrect key file for table。这说明表结构元数据还在,物理文件却已不可用,属于“半残留”状态——不是干净的遗留,而是损坏未清理的残骸。
关键看 CHECK TABLE 返回的 Msg_type:
-
error+Msg_text含crashed、corrupted、key file→ 物理损坏,MyISAM 文件(.MYI或.MYD)出问题 -
warning+Found 1 delete link→ 数据文件有碎片,但没坏,可OPTIMIZE TABLE整理 - 返回
Status: OK却查不出数据 → 很可能索引失效或统计信息过期,不是残留问题,别往损坏方向查
真正“残留”的表,是指业务早就不用了、没人维护、也没人记得删,但还挂着 MyISAM 引擎活着——这种表往往 CHECK TABLE 过得去,只是长期没写入,table_rows 为 0 或极小,update_time 是多年前的时间戳。
为什么 myisamchk 能扫到文件却查不到表名
当 myisamchk /var/lib/mysql/your_db/*.MYI 报出一堆表名,但 SELECT table_name FROM information_schema.TABLES 里一个都找不到,基本可以断定:这些 .MYI 和 .MYD 是孤儿文件——对应表已被 DROP TABLE,但文件没删干净,或者 MySQL 崩溃时残留下来的。
这时候不能直接用 myisamchk --repair,因为没表定义,修复后也加载不进数据库。正确做法是:
- 先确认 MySQL 是否在运行,若运行中,
myisamchk必须加--read-only或停服务,否则可能写坏正在使用的文件 - 用
myisamchk -dvv table.MYI(-dvv是 dump + verbose)看文件头里有没有可用的表结构信息,有些老版本 MyISAM 会存部分 schema - 如果纯属垃圾文件,手动
rm *.MYI *.MYD即可,但务必先备份整个datadir目录 - 若怀疑是误删导致的残留,检查 binlog 或 slow log 里最近的
DROP TABLE记录,确认是否人为操作
ALTER TABLE ENGINE=InnoDB 失败后留下的中间态表
执行 ALTER TABLE t ENGINE=InnoDB 中断(比如磁盘满、连接断开),可能导致原 MyISAM 表被 rename 成临时名(如 #sql-xxx),而新 InnoDB 表没建完。此时 information_schema 里看不到原表名,但文件系统里还留着 #sql-xxx.MYD 和 #sql-xxx.MYI。
这类文件不是“残留”,而是失败的原子操作产物,处理原则是:
- 先停写入,避免并发 DDL 再触发冲突
- 查
SHOW PROCESSLIST看有没有卡住的ALTER线程,有的话KILL掉 - 手动删掉
#sql-*.MYI和#sql-*.MYD,MySQL 启动时通常会忽略它们 - 如果删完发现原表名又回来了,说明 rename 没彻底完成,此时再跑一次
ALTER TABLE t ENGINE=InnoDB即可
真正难处理的是那些既不在 information_schema 里、又没 #sql- 前缀的 MyISAM 文件——它们往往来自早期手工拷贝或跨版本迁移,没有元数据映射,只能靠文件时间戳、大小、以及业务逻辑推断是否还能用。











