应优先转换有持续写入、数据量超1GB且依赖事务/行级锁/崩溃恢复的MyISAM表;先用SELECT语句筛选真实待评估清单,避免盲目转换只读字典表、历史日志或含FULLTEXT索引的表。

直接执行 ALTER TABLE table_name ENGINE=InnoDB 在生产环境大概率引发写入中断、主从延迟飙升和磁盘爆满——这不是操作太慢,而是 MySQL 对 MyISAM 到 InnoDB 的引擎切换至今(2026 年)仍强制走 COPY 算法,无法真正在线。
哪些表真该转?先筛清单再动手
别一上来就跑批量脚本。MyISAM 表里混着只读字典表、历史日志、带 FULLTEXT 的搜索表,盲目转换可能让全文查询失效或触发 ERROR 1075。先用这条语句拉出真实待评估清单:
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');
重点关注三类表:
- 有持续写入(
table_rows不是静态值) - 数据量 >1GB(SSD 上 ≥500MB 就建议走无锁方案)
- 业务依赖事务、行级锁或崩溃恢复能力
可暂缓的表包括:只读小表(≤100MB)、含 FULLTEXT 索引且 MySQL 版本 pt-online-schema-change 会直接报错 This table has no primary key or unique index)。
小表(≤500MB)能直接 ALTER 吗?必须全满足这四条
可以,但仅当同时满足全部条件,缺一不可:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 确认无
FULLTEXT索引:SHOW INDEX FROM your_table WHERE Key_name = 'FULLTEXT';返回空才安全 - 已有显式主键或唯一非空索引:
SHOW KEYS FROM your_table WHERE Non_unique = 0 AND Seq_in_index = 1; -
innodb_file_per_table为 ON(MySQL 5.6+ 默认开,但需查SHOW VARIABLES LIKE 'innodb_file_per_table';确认) - 磁盘剩余空间 ≥ 原表
.MYD大小 × 2.2(COPY 过程要存旧表 + 新.ibd+ redo/undo 临时文件)
执行后立刻监控:SHOW PROCESSLIST; 看是否长期卡在 copy to tmp table;完成后验证:SHOW TABLE STATUS LIKE 'your_table'; 中 Engine 字段是否为 InnoDB。
大表必须用 pt-online-schema-change,别信 ALGORITHM=INPLACE
MySQL 8.0+ 对 ENGINE 变更仍强制走 COPY 算法,ALGORITHM=INPLACE 或 LOCK=NONE 全部无效。唯一落地路径是 pt-online-schema-change,它靠影子表 + 触发器双写绕过锁,但对环境敏感:
- 目标表必须有主键或唯一非空索引(否则启动即报错)
- 迁移期间禁止
LOAD DATA INFILE或REPLACE INTO,这些操作不走触发器,会导致影子表漏数据 - 必须加
--max-lag=1和--check-interval=5,防从库延迟失控 - 命令示例:
pt-online-schema-change --alter "ENGINE=InnoDB" D=your_db,t=big_table --execute --chunk-size=1000
迁移完旧的 .MYD 和 .MYI 文件不会自动删,得人工确认新表 COUNT(*) 一致后再清理。
转换后不调参、不校验,等于白干
引擎变了,配置和行为必须同步变,否则性能可能更差:
- 立刻调大
innodb_buffer_pool_size(设为物理内存 50%–75%),并把key_buffer_size从几百 MB 降到 32M 左右 - 检查外键:MyISAM 忽略
FOREIGN KEY定义,InnoDB 会校验——若原表有脏数据(如子表存在父表不存在的外键值),ALTER TABLE会失败,报错类似ERROR 1005 (HY000): Can't create table `db`.`t` (errno: 150) - 全文索引必须重建:
ALTER TABLE t DROP INDEX ft_idx; ALTER TABLE t ADD FULLTEXT(idx_col);,MyISAM 的布尔模式(如+(apple banana) -orange)在 InnoDB 中部分嵌套括号可能失效 -
AUTO_INCREMENT值不持久化,重启可能重置;若业务依赖连续性,需手动SELECT MAX(id) FROM t后执行ALTER TABLE t AUTO_INCREMENT = N
最易被忽略的是:转换后没关查询缓存(query_cache_type=0),InnoDB 下它反而拖慢性能;还有事务习惯没改——MyISAM 不支持事务,很多老代码没写 COMMIT 或异常时没 ROLLBACK,切到 InnoDB 后容易堆积长事务,卡死系统。

















