不能直接批量执行 ALTER TABLE t ENGINE=InnoDB,必须按表分级处理:先筛选真正需转换的MyISAM表,重点关注持续写入、数据量大(>1GB或SSD上≥500MB)、依赖事务/行锁/崩溃恢复的表;只读小表和含FULLTEXT索引的表可暂缓。

不能直接批量执行 ALTER TABLE t ENGINE=InnoDB——它在任何 MySQL 版本(包括 8.0+)中对 MyISAM 表都强制走 COPY 算法,全程加 MDL 写锁,业务写入中断、主从延迟飙升、磁盘空间翻倍是必然结果。方案必须按表分级,而非按库“一刀切”。
先筛出真正该转的 MyISAM 表
盲目转换不仅浪费时间,还可能引入全文索引不兼容、AUTO_INCREMENT 报错 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 吗?
可以,但仅当同时满足全部条件:
- 确认无
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+ 默认开,但需确认) -
df -h /var/lib/mysql显示剩余空间 ≥ 原表.MYD大小 × 2.2 - 业务允许该表在转换窗口内完全不可写(例如非核心日志、只读字典)
执行后务必监控:SHOW PROCESSLIST 看是否长期卡在 copy to tmp table;完成后验证 SHOW TABLE STATUS LIKE 'your_table' 中 Engine 字段是否为 InnoDB。
大表必须用 pt-online-schema-change
这是目前唯一能在生产环境落地的“平滑”方案。它不依赖 MySQL 原生 DDL,靠影子表 + 触发器双写同步,业务几乎无感。命令示例:
pt-online-schema-change --alter "ENGINE=InnoDB" D=your_db,t=big_table --execute --chunk-size=1000 --max-lag=1 --check-interval=5
关键注意事项:
- 迁移后不会自动删除旧的
.MYD和.MYI文件,必须人工清理——先比对CHECKSUM TABLE old_table和CHECKSUM TABLE new_table,确认一致再删 - 若原表含
FULLTEXT索引,需先DROP INDEX,迁完再重建(InnoDB 5.6+ 支持) - 禁用
LOAD DATA INFILE或REPLACE INTO等绕过触发器的操作,否则数据不一致 - 默认超时是 120 秒,大表建议加
--chunk-time=0.5防止单块超时
转换后不调参等于白转
InnoDB 的行为和资源模型与 MyISAM 差太多,不调整配置会导致性能反降:
-
innodb_buffer_pool_size必须设为物理内存的 50%–75%,否则大量数据从磁盘读取 -
key_buffer_size应从几百 MB 降到 32M 左右(MyISAM 不再用) -
innodb_flush_log_at_trx_commit非金融场景可设为2(崩溃最多丢 1 秒数据) - 验证
COUNT(*)结果是否与原表一致(InnoDB 不缓存行数,结果准确但可能慢) - 业务 SQL 是否仍能正常执行,尤其涉及
MATCH AGAINST的全文查询(InnoDB 分词规则不同,需重建索引)
最常被忽略的是:转换后旧文件没清、全文索引没重建、缓冲池没调大——这三件事不做,哪怕表引擎改成功了,业务也感知不到好处。


















