最直接可靠的方式是查 information_schema.tables 筛出非 innodb 表,执行 select table_schema, table_name, engine from information_schema.tables where engine != 'innodb' and table_schema not in ('information_schema','performance_schema','mysql','sys');

查 information_schema.TABLES 筛出非 InnoDB 表
这是最直接、最可靠的方式,不依赖 SHOW TABLE STATUS 的性能缺陷或权限限制。MyISAM 表在 ENGINE 字段中明确显示为 MyISAM,而不会被误标为其他引擎。
执行以下语句可列出所有数据库中所有非 InnoDB 的表(重点看 MyISAM,但也可能混有 MEMORY、COLUMNSTORE 等):
SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE, TABLE_ROWS
FROM information_schema.TABLES
WHERE ENGINE != 'InnoDB'
AND TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys');
注意点:
-
TABLE_ROWS对 MyISAM 是近似准确值,对其他引擎(如 InnoDB)只是估算,不能用于判断数据量 - 如果查询卡住,可能是元数据锁或大库阻塞,可加
/*+ MAX_EXECUTION_TIME(5000) */限流(MySQL 5.7.8+ 支持) - 某些从库上
TABLE_ROWS为NULL,不代表引擎异常,而是表未加载元数据,需结合ENGINE字段判断
用 mysqlcheck -A 快速扫全实例
mysqlcheck 是 MySQL 自带的命令行工具,在服务运行时就能批量检查所有表,且对 MyISAM 表会真实触发文件读取(.MYD/.MYI),比纯 SQL 查询更贴近“物理存在”验证。
执行命令:
mysqlcheck -u root -p --all-databases --check-only
它会输出每张表的 OK 或报错信息;只要看到某张表返回了 test.dbname 这类路径,并且没报错,就说明该表物理文件存在且当前引擎仍为 MyISAM(因为 mysqlcheck 对非 MyISAM 表默认跳过检查或仅做轻量校验)。
常见干扰项:
- 若输出含
Warning: 1 client is using or hasn't closed table,是并发写入导致的临时状态,不是引擎类型问题 - 遇到
Table 'xxx' doesn't exist说明表已被删,但.frm文件残留——这种不算“有效 MyISAM 表”,可忽略 - 若提示
Access denied,确认用户有SELECT权限(mysqlcheck --check-only依赖此权限读取元数据)
为什么不能只靠 SHOW CREATE TABLE 或 SHOW TABLE STATUS?
这两个命令容易给出误导性结论,尤其在迁移或升级后环境里。
SHOW CREATE TABLE 显示的是建表语句中的显式引擎声明,但若建表时没写 ENGINE=,它会 fallback 到当时的 default_storage_engine 设置——而该变量在 MySQL 8.0.23+ 已被标记为 deprecated,配置可能失效或被忽略;旧表也不会因配置变更自动转换引擎。
SHOW TABLE STATUS 更危险:
- 在库大表多时性能极差,甚至阻塞其他查询
- 不支持
WHERE过滤,必须靠客户端筛选,无法直接定位 MyISAM - 输出字段名是
Engine,但大小写不敏感匹配,曾有案例因字符集问题显示为myisam小写,脚本解析失败
所以,宁可用 information_schema.TABLES 的精确匹配,也不要图省事用 SHOW TABLE STATUS LIKE '%'。
检查后发现 MyISAM 表,下一步必须确认是否真在用
查到 MyISAM 表不等于要立刻改引擎。有些场景下它是有意为之:比如日志归档表、只读报表缓存、或遗留 BI 工具强依赖 MyISAM 的 COUNT(*) 性能。
判断是否“真在用”的关键信号:
- 查
INFORMATION_SCHEMA.INNODB_TRX和PROCESSLIST—— MyISAM 表的操作根本不会出现在这两张表里,所以如果某张 MyISAM 表长期无任何INSERT/UPDATE/DELETE连接痕迹,大概率已废弃 - 看慢日志或 general_log 中是否还有对该表的 DML;没有记录,基本可判定冷数据
- 用
myisamchk -s /path/to/db/table.MYI检查索引头,若提示MyISAM file not found,说明物理文件已丢失,只剩元数据残留
真正麻烦的是那些仍在写入、但没人知道为啥还在用 MyISAM 的表——这类最容易在崩溃后暴露,也最难推动改造。











