查myisam表必须过滤系统库,唯一可靠方式是查询information_schema.tables并加上table_schema not in ('information_schema','mysql','performance_schema','sys')条件,且engine值须严格为'myisam'(linux下大小写敏感),还需添加order by table_schema,table_name保证结果稳定,并确保账号具备information_schema的select权限;超大实例应临时关闭innodb_stats_on_metadata以避免超时;转换前须检查全文索引依赖及锁表影响。

查 MyISAM 表必须过滤系统库
直接查 information_schema.tables 是唯一可靠方式,但漏掉 TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') 就会混入系统表——比如 mysql.help_topic 这类表是 MyISAM,但你不能动,也不该动。不加这个条件,结果里可能冒出几十个干扰项,误判风险陡增。
常见错误是只写 WHERE ENGINE = 'MyISAM',然后对着输出列表一顿操作,结果发现全是系统库里的“幽灵表”。Linux 下大小写敏感,'MyISAM' 必须全大写首字母,写成 'myisam' 或 'MYISAM' 查不到任何结果。
生产环境要加 ORDER BY 和权限检查
批量排查时,结果顺序不可靠会导致 diff 失效或漏比对。加上 ORDER BY TABLE_SCHEMA, TABLE_NAME 能让每次输出稳定可比。更关键的是权限:账号必须有 SELECT 权限在 information_schema 库上,否则报 Access denied for user——这不是数据库连不上,而是元数据查不了,运维常在这里卡住。
超大实例(如表数超 10 万)可能触发查询超时,可临时执行:
SET SESSION innodb_stats_on_metadata = OFF;减少统计开销,查完再设回
ON 即可。
别信 default_storage_engine 配置
SHOW VARIABLES LIKE 'default_storage_engine' 返回 InnoDB,不代表当前没 MyISAM 表。老表建于 MySQL 5.5 之前,或建表时显式写了 ENGINE=MyISAM,就永远保持原样。MySQL 8.0.23+ 已标记该变量为 deprecated,它对存量表完全无效。
用 SHOW CREATE TABLE tbl_name 看单表虽可行,但面对几百张表时效率归零;SHOW TABLE STATUS 比 information_schema 查询慢,且无法跨库批量扫。
生成 ALTER 语句前先确认全文索引依赖
查出 MyISAM 表后,别急着跑 ALTER TABLE db.tbl ENGINE=InnoDB。如果该表用了 MyISAM 特有的全文索引(尤其是自然语言模式),InnoDB 的分词行为和权重计算不同,直接转可能让搜索结果异常。先查 SHOW INDEX FROM tbl_name WHERE Key_name = 'FULLTEXT',再评估是否需要重构索引逻辑。
另外,ALTER TABLE ... ENGINE=InnoDB 是锁表操作,大表可能阻塞业务数分钟。真正容易被忽略的点是:转换后 SELECT COUNT(*) 性能反而下降——MyISAM 原本秒出,InnoDB 得走聚簇索引扫描,除非加了有效 WHERE 条件。











