myisam不支持online ddl,因其缺乏事务、行级锁和redo/undo日志机制,ddl必须直接修改.frm/.myd/.myi文件,强制表级排他锁;而innodb依赖mvcc、行锁及可重放日志实现online ddl,并在5.7中部分操作(如add column not null无default、varchar字节溢出等)会 silently 降级为copy算法导致锁表。

为什么MyISAM不支持Online DDL?
因为MyISAM引擎本身没有事务、行锁和变更日志(如redo log)机制,所有DDL操作都必须直接修改.frm + .MYD + .MYI三个物理文件——这天然要求表级排他锁(LOCK=EXCLUSIVE),无法与DML并发。即使你显式写ALGORITHM=INPLACE,MySQL也会直接报错:ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported,连尝试都不给。
InnoDB的Online DDL依赖哪些底层能力?
InnoDB能做在线改结构,靠的是三样东西:MVCC快照读、行级锁、以及可重放的变更日志(redo log + undo log)。比如加索引时,它用后台线程扫描表、构建B+树,同时把新写入的数据同步到索引中;改VARCHAR长度时,只更新元数据和页内长度字段,不动已有记录内容——这些都建立在InnoDB的“数据即索引”和聚簇索引结构上。MyISAM没有这些,就只能copy table。
5.7里哪些InnoDB操作看似在线实则降级?
以下情况会悄悄退化为COPY算法,导致锁表:
-
ADD COLUMN加了NOT NULL但没设DEFAULT值(5.7.5+也强制COPY) -
VARCHAR长度从254→256:字节长度表示从1字节升到2字节,触发重建 -
MODIFY COLUMN改类型(如INT→BIGINT)或缩小长度(哪怕只是VARCHAR(100)→VARCHAR(99)) - 表启用了
ROW_FORMAT=COMPRESSED,而目标操作不兼容该格式
执行完别只看Query OK,查information_schema.innodb_alter_table确认state是否为copy to tmp table。
跨引擎迁移时最容易忽略的一点
就算你把MyISAM表转成InnoDB(ALTER TABLE t ENGINE=InnoDB),这个转换本身是COPY操作,全程锁表。而且转换后首次执行Online DDL前,务必检查innodb_file_format是否为Barracuda、innodb_large_prefix是否启用——否则哪怕语法合法,也会因格式限制被降级。这些参数在5.7默认开启,但旧配置升级上来的实例常被忽略。











