优先迁移有写入、数据量>1GB或需事务/行锁/崩溃恢复的MyISAM表;暂缓只读小表(≤100MB)和含FULLTEXT但MySQL<5.6的表;须检查AUTO_INCREMENT索引、触发器、SQL硬编码等隐性依赖。

不是所有 MyISAM 表都该动——盲目转换可能引入 FULLTEXT 不兼容、AUTO_INCREMENT 报错、甚至性能下降。真正需要优先转的,是那些正在被业务频繁写入、又依赖事务或高可用能力的表。
查出所有非系统 MyISAM 表清单
先跑这条 SQL 拿到基础清单,排除掉系统库和视图:
SELECT table_schema, table_name, table_rows, data_length, engine
FROM information_schema.tables
WHERE engine = 'MyISAM'
AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
AND table_type = 'BASE TABLE'
ORDER BY data_length DESC;
-
table_rows持续变动(比如每分钟有INSERT/UPDATE)说明有写入,是重点候选 -
data_length > 1073741824(即 >1GB)的大表,一旦出问题影响面广,必须优先评估 - 注意
table_rows为NULL的表——MyISAM 可能没统计,但不代表没数据,得结合监控或慢查日志确认活跃度
三类表必须优先处理
满足任一条件就该排进迁移队列:
- 有写入且参与事务逻辑:比如订单、支付、用户余额类表,哪怕当前没显式用
BEGIN,只要业务要求“要么全成功、要么全失败”,就得靠 InnoDB 保证 - 被主从延迟敏感业务读取:例如实时报表依赖的中间汇总表,MyISAM 表级锁会拖慢主从同步,
Seconds_Behind_Master容易飙升 - 需行级锁或崩溃自动恢复:如库存扣减、消息状态更新,InnoDB 的
REPEATABLE-READ+undo log能避免脏读和手动修复
两类表建议暂缓甚至不转
强行转换反而增加风险和运维成本:
- 只读小表(
data_length <= 104857600,即 ≤100MB):比如字典表、配置表,COUNT(*)快、锁表影响小,InnoDB 优势不明显 - 含
FULLTEXT索引且 MySQL 版本 < 5.6:InnoDB 在 5.6 前不支持全文索引,ALTER TABLE会直接报错;若无法升级,只能保留或迁到Sphinx/Elasticsearch
容易被忽略的隐性依赖点
即使表本身看起来“安全”,也得检查周边上下文:
- 触发器或存储过程中有没有
CREATE TEMPORARY TABLE?默认引擎是 MyISAM,必须显式加ENGINE=InnoDB,否则半夜执行失败 - 应用代码里是否硬编码了 MyISAM 特性?比如依赖
SELECT COUNT(*)瞬时返回、或用INSERT DELAYED(InnoDB 不支持) - 表有没有
AUTO_INCREMENT列但没建索引?MyISAM 允许,InnoDB 会报ERROR 1075,得先补主键或唯一索引
真正卡住进度的往往不是转换动作本身,而是这些散落在触发器、SQL 模板、运维脚本里的隐性依赖——不提前扫一遍,上线后才发现 MATCH AGAINST 查不出结果,或者定时任务突然失败。


















