最可靠方法是查询information_schema.tables筛选MyISAM表:SELECT table_schema, table_name FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('mysql','information_schema','performance_schema','sys');

确认当前表引擎并筛选出 MyISAM 表
直接查 information_schema.tables 最可靠,避免手动列名或误判。注意只查用户库,排除系统库(如 mysql、performance_schema):
SELECT table_schema, table_name
FROM information_schema.tables
WHERE engine = 'MyISAM'
AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys');
执行前建议加 LIMIT 10 预览;若结果为空,说明没有可改的 MyISAM 表。
生成批量 ALTER TABLE 转换语句
不能手写几十条 ALTER TABLE ... ENGINE=InnoDB,要用 SQL 拼接生成。关键点:必须显式指定数据库名(避免跨库执行错误),且语句末尾要带分号:
SELECT CONCAT('ALTER TABLE `', table_schema, '`.`', table_name, '` ENGINE=InnoDB;') AS ddl
FROM information_schema.tables
WHERE engine = 'MyISAM'
AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys');
复制输出的所有 ALTER TABLE 语句,在目标实例中逐条或分批执行。不建议用存储过程自动执行——出错难定位,且大表转换期间锁表时间长,需人工控制节奏。
执行时要注意锁表和磁盘空间
MyISAM 转 InnoDB 是重建表操作(ALGORITHM=COPY),全程锁表,且会临时占用约等同于原表大小的磁盘空间。常见踩坑点:
-
ALTER TABLE对大表可能持续数小时,务必在低峰期操作 - 确保
innodb_file_per_table=ON(默认 5.6+ 已开启),否则所有表数据会挤进ibdata1,后续无法收缩 - 若遇到
ERROR 1114 (HY000): The table is full,通常是临时表空间或磁盘满,不是内存不足 - 不要在从库上直接改——主从引擎不一致会导致复制中断(如
CREATE TABLE ... SELECT类型语句行为不同)
验证转换结果与潜在兼容性问题
改完后别只看 SHOW CREATE TABLE,还要检查实际运行是否异常。InnoDB 和 MyISAM 在行为上有实质差异:
- 全文索引:MyISAM 的
FULLTEXT在 InnoDB 中支持但分词器、停用词逻辑不同,搜索结果可能变化 - 自增字段:InnoDB 的
AUTO_INCREMENT值在重启后可能跳变(因只保存在内存),而 MyISAM 持久化到文件 - 表级锁 → 行级锁:应用若依赖 MyISAM 的表锁语义(比如手动
LOCK TABLES),切换后逻辑可能出错 - 事务:InnoDB 支持事务,但原有代码没加
BEGIN/COMMIT的地方,现在也“自动”变成单语句事务了,需确认是否符合预期
最易被忽略的是:有些老项目建表时用了 ROW_FORMAT=FIXED 或 PACK_KEYS=1 这类 MyISAM 专属参数,转成 InnoDB 后会被静默忽略,但建表语句里还留着——下次用 SHOW CREATE TABLE 导出再导入就报错。


















