会锁表,且默认全表重建式转换,期间持有写锁并可能阻塞读;5.6+虽支持ALGORITHM=INPLACE但MyISAM转InnoDB仍多为拷贝重建,生产环境应优先使用pt-online-schema-change实现无锁变更。

MyISAM 表转 InnoDB 会锁表吗?
会,而且默认是全表重建式转换,期间 ALTER TABLE ... ENGINE=InnoDB 会持有写锁,读也可能被阻塞(取决于 MySQL 版本和隔离级别)。5.6+ 支持 ALGORITHM=INPLACE,但仅限某些场景;5.7+ 对 MyISAM 转 InnoDB 实际仍走拷贝重建,无法真正免锁。
- 生产环境别直接在高峰期跑
ALTER TABLE t1 ENGINE=InnoDB - 用
pt-online-schema-change是更稳妥的选择——它通过影子表+触发器实现无锁变更 - 如果必须用原生命令,先在从库上试,确认耗时和磁盘空间(InnoDB 通常比 MyISAM 占更多空间)
外键、全文索引这些功能能直接迁移吗?
不能。MyISAM 支持 FULLTEXT 索引但不支持外键;InnoDB 支持外键但旧版(5.6 之前)FULLTEXT 功能受限,且语法行为有差异。
-
FULLTEXT索引需手动重建:MyISAM 的ft_min_word_len和 InnoDB 的innodb_ft_min_token_size默认值不同(前者 4,后者 3),搜索结果可能变化 - InnoDB 外键要求字段必须有索引,而 MyISAM 忽略这点——迁移前得检查并补上
INDEX,否则ALTER会失败 - 含
ENUM或SET字段的表,InnoDB 存储方式不同,排序或比较逻辑可能微调,尤其涉及大小写敏感性时
迁移后查询变慢了,是不是引擎问题?
不一定,更可能是索引策略或事务习惯没跟上。MyISAM 是纯堆表+表级锁,InnoDB 是聚簇索引+行级锁+MVCC,同样的 SQL 在两种引擎下执行路径可能完全不同。
- 检查执行计划是否用了预期索引:
EXPLAIN SELECT ...中type是否从ALL变成range或ref - MyISAM 常靠
COUNT(*)快速返回(维护行数),InnoDB 得扫索引,如果代码里高频调SELECT COUNT(*) FROM t,得加覆盖索引或改用近似统计 - 批量插入时,InnoDB 默认每条语句提交一次事务,比 MyISAM 慢很多——务必用
START TRANSACTION包裹,或调大innodb_buffer_pool_size
如何验证迁移结果是否可靠?
不能只看 SHOW CREATE TABLE 里 ENGINE=InnoDB 就算完。重点核对数据一致性、约束生效情况和主从同步状态。
- 用
pt-table-checksum对比主从数据(尤其大表),避免复制中断导致隐性丢数据 - 查
information_schema.KEY_COLUMN_USAGE确认外键是否真被创建,再试删一条父记录看是否报错 - 检查错误日志有没有
InnoDB: Warning: cannot open table这类提示——说明 .frm 和 ibdata 文件不匹配,常见于直接拷贝文件迁移
最麻烦的其实是隐性依赖:比如某个 MyISAM 表被当“计数器”高频更新,换成 InnoDB 后没加事务控制,反而引发死锁。这种得结合业务日志和 SHOW ENGINE INNODB STATUS 交叉排查。











