应查 information_schema.tables 定位 myisam 表,因其实时准确;需排除系统库,避免误操作;不能依赖 show engines 或 show create table 等低效或不全面方式。

查 MyISAM 表:直接用 information_schema 查引擎类型
MySQL 生产库中混用引擎很常见,但 MyISAM 缺乏事务和行锁,在高并发写入或崩溃恢复场景下容易出问题。排查的第一步就是快速定位哪些表还在用 MyISAM。
最可靠的方式是查 information_schema.tables,它实时反映当前表的存储引擎状态,比看建表语句或 SHOW CREATE TABLE 更准(后者可能被人工改过但没执行 ALTER TABLE ... ENGINE=InnoDB)。
SELECT table_schema, table_name, engine FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys');- 加
table_schema NOT IN (...)是必须的——系统库里的 MyISAM 表(比如mysql.help_topic)不用动,也动不了 - 如果只想看某个库,把
AND table_schema = 'your_db'替换掉上面的排除条件即可 - 注意:该查询本身不锁表,但频繁扫描大库的
information_schema可能触发元数据锁等待,建议在低峰期跑
为什么不能只靠 SHOW ENGINES 或 SHOW VARIABLES
SHOW ENGINES 只告诉你「MyISAM 是否可用」,不是「哪些表在用它」;SHOW VARIABLES LIKE 'default_storage_engine' 只反映默认值,对已存在的表完全无效。
- 哪怕你早就把
default_storage_engine设成InnoDB,历史表仍可能是 MyISAM - 有些老应用建表时显式写了
ENGINE=MyISAM,之后也没人改过 -
SHOW CREATE TABLE虽然能看到单个表引擎,但没法批量扫——面对几百个库、几千张表时效率极低
脚本化排查:加过滤、导出、防误操作
生产环境不能只靠手动 SQL,得封装成可复用、带防护的脚本。核心是避免漏查、误查、权限不足或超时中断。
- 用
mysql -u$user -p$pass -e "..."执行时,加上--skip-column-names --batch,输出更干净,方便后续awk或while read处理 - 加上
ORDER BY table_schema, table_name让结果可预测,方便 diff 历史报告 - 如果遇到
Access denied for user,确认账号有SELECT权限在information_schema—— 这是常被忽略的权限点 - 超大实例(比如 10w+ 表)可能触发
information_schema查询超时,可临时设SET SESSION innodb_stats_on_metadata = OFF;减少统计开销(不影响业务)
MyISAM 表迁移前必须验证的三件事
找到 MyISAM 表只是第一步。真要转 InnoDB,光跑 ALTER TABLE t ENGINE=InnoDB 很危险。
- 检查是否有全文索引:
MyISAM的全文索引语法和InnoDB不兼容,需先删再重建 - 确认没有使用
AUTO_INCREMENT字段做非主键索引(MyISAM 允许,InnoDB 要求必须是主键或含主键前缀) - 查
DATA_LENGTH + INDEX_LENGTH,MyISAM 表体积远大于 InnoDB 时,说明存在大量碎片或冗余索引——直接转换会卡很久,建议先OPTIMIZE TABLE(MyISAM 下)再转
线上改引擎不是命令一敲就完的事,表越大,越要提前看执行计划、锁持续时间、磁盘空间是否够——这些比“怎么列出来”难得多。











