该迁myisam表需优先处理三类:有写入且参与事务逻辑、被主从延迟敏感业务读取、需行级锁或崩溃自动恢复;暂缓迁移只读小表(≤100mb)及含fulltext索引且mysql

该不该迁,不看引擎名,看这张表在业务里“动不动”、“重不重”、“靠不靠得住”。直接跑一条查询就能筛出高优先级候选,但结果只是起点,还得结合监控和代码确认。
查出所有 MyISAM 表并排序看数据量和活跃度
执行这句就能列出当前库中所有非系统 MyISAM 表,并按大小倒序:
SELECT table_schema, table_name, table_rows, data_length, index_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 可能没统计,得结合慢查日志或监控里的 QPS 确认是否活跃
三类表必须优先处理,满足任一就该排进迁移队列
不是所有 MyISAM 表都值得动。以下三类才真需要迁移:
- 有写入且参与事务逻辑:比如订单、支付、用户余额类表,哪怕当前没显式用
BEGIN,只要业务要求“要么全成功、要么全失败”,就得靠InnoDB保证 - 被主从延迟敏感业务读取:例如实时报表依赖的中间汇总表,
MyISAM表级锁会拖慢主从同步,Seconds_Behind_Master容易飙升 - 需行级锁或崩溃自动恢复:如库存扣减、消息状态更新,
InnoDB的REPEATABLE-READ+undo log能避免脏读和手动修复
两类表建议暂缓甚至不转,强行转反而增加风险
盲目迁移可能引入新问题,以下情况可不迁:
- 只读小表(
data_length ,即 ≤100MB):比如字典表、配置表,<code>COUNT(*)快、锁表影响小,InnoDB优势不明显 - 含
FULLTEXT索引且 MySQL 版本 ALTER TABLE 会直接报错;若无法升级,只能保留或迁到Sphinx/Elasticsearch
容易被忽略的隐性依赖点
即使表本身看起来“安全”,也得检查周边上下文:
- 触发器或存储过程中有没有
CREATE TEMPORARY TABLE?默认引擎是MyISAM,必须显式加ENGINE=InnoDB,否则半夜执行失败 - 应用代码里是否硬编码了
MyISAM特性?比如依赖SELECT COUNT(*)瞬时返回,或用了INSERT DELAYED(InnoDB不支持) - 是否有外键引用这张表?
MyISAM不支持外键,但业务逻辑可能已隐式依赖一致性,迁完后要补约束并清洗脏数据
真正难的不是判断“要不要迁”,而是确认“它到底在哪儿被用”。一张看似静态的配置表,可能被某个凌晨跑的定时任务当作状态开关——这种调用链,光看 information_schema 是看不到的。











