支持,但不等于能用——MySQL 8.0 中 ALTER TABLE t ENGINE=InnoDB 仍强制走 COPY 算法,不支持 ALGORITHM=INPLACE,全程持有 MDL 写锁阻塞读写,大表易致主从延迟飙升;必须转的表包括有持续写入、数据量>500MB、依赖事务/行锁/崩溃恢复的表,只读小表或含 FULLTEXT 且版本不兼容的可暂缓。

MySQL 8.0 还支持 ALTER TABLE t ENGINE=InnoDB 吗?
支持,但不等于能用——ALTER TABLE t ENGINE=InnoDB 在 MySQL 8.0 中仍强制走 COPY 算法,ALGORITHM=INPLACE 对 MyISAM → InnoDB 无效。它会全程持有 MDL 写锁,阻塞所有 INSERT/UPDATE/DELETE,SELECT 在可重复读下也可能卡住。10GB 表常卡在 copy to tmp table 状态十几分钟,主从延迟飙升。
哪些表真该转,哪些可以不动?
别批量扫一遍就全转。先跑这句查出候选表:
SELECT table_schema, table_name, table_rows, data_length FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema');
重点关注三类必须转的表:
- 有持续写入(
table_rows明显变动) - 数据量 >500MB(SSD 上就建议无锁方案)
- 业务依赖事务、行锁或崩溃恢复能力
以下表可暂缓:
- 只读小表(≤100MB,比如
sys_config、dict_status) - 含
FULLTEXT索引且 MySQL 版本 - 无主键/唯一非空索引(
pt-online-schema-change会直接报错This table has no primary key or unique index)
大表怎么迁才不卡死业务?
唯一靠谱方案是 pt-online-schema-change,原理是影子表 + 触发器双写,业务几乎无感。但必须满足硬前提:
-
innodb_file_per_table = ON(MySQL 5.6+ 默认开启,确认下) - 目标表有显式主键或唯一非空索引
binlog_format = ROW- 禁用
LOAD DATA INFILE或REPLACE INTO等绕过触发器的操作
命令示例(带关键参数):
pt-online-schema-change --alter "ENGINE=InnoDB" D=your_db,t=big_table --execute --chunk-size=1000 --max-lag=1 --check-interval=5
注意:pt-osc 迁移后不会自动删旧的 .MYD 和 .MYI 文件,必须人工验证 CHECKSUM TABLE 一致后再清理。
转完引擎就完事了?
远没完。InnoDB 行为和 MyISAM 差太多,不调参可能比原来还慢:
-
innodb_buffer_pool_size必须设为物理内存的 50%–75%,否则大量磁盘读 -
key_buffer_size从几百 MB 降到 32M 左右(MyISAM 不再用) -
innodb_flush_log_at_trx_commit非金融场景可设为2(崩溃最多丢 1 秒数据) - 原表若含
FULLTEXT,需先DROP INDEX,转完再CREATE FULLTEXT INDEX(InnoDB 分词规则不同,查不到不是 SQL 错,是索引行为变了) - 原表若只有
id INT AUTO_INCREMENT但没建索引,ALTER会报错ERROR 1075,得先加主键
最易被忽略的是:转换后 COUNT(*) 会变慢(InnoDB 不缓存行数),而 MATCH AGAINST 查询可能返回空——不是数据丢了,是全文索引重建后分词逻辑已不同。


















