MyISAM不支持LOCK=NONE的根本原因是其无行级锁、MVCC和在线日志机制,DDL必须全表COPY并加EXCLUSIVE锁,语法层面即被拒绝;真实生产中仅能靠pt-osc等工具模拟在线变更,本质仍是权宜之计。

MyISAM表不支持LOCK=NONE的根本原因
因为MyISAM引擎本身没有行级锁、MVCC或在线日志机制,所有DDL操作都必须走COPY模式——即创建临时表、加全表写锁、逐行拷贝数据、重命名替换。这个过程天然要求EXCLUSIVE锁,LOCK=NONE或LOCK=SHARED在语法上就会被MySQL直接拒绝,报错ERROR 1845 (HY000): ALGORITHM=INPLACE is not supported for this operation on table 'xxx'或类似提示。
MyISAM在线变更只能靠外部工具模拟
既然内核不支持,就只能靠触发器或binlog同步来“假装在线”。比如pt-online-schema-change会在MyISAM表上创建触发器,把原表的INSERT/UPDATE/DELETE实时写入新表;而gh-ost则依赖binlog解析,但MyISAM不写binlog(除非开启log_bin且使用ROW格式,实际极少配置)。所以真实生产中,对MyISAM做“在线”变更,pt-osc是唯一可行路径,但它不是真正的在线DDL,只是业务层规避锁表的权宜之计。
为什么不能像InnoDB那样加个ALGORITHM=INPLACE?
MyISAM的索引是独立文件(.MYI),数据是堆组织(.MYD),没有聚簇索引、没有事务日志、没有崩溃恢复能力。添加一个二级索引,就必须读取全部.MYD文件、排序键值、写入新的.MYI片段——这个过程无法中断、无法并发、无法回滚。InnoDB能做INPLACE,靠的是B+树页分裂合并、undo log、online DDL log三者协同;MyISAM连undo log都没有,根本没得协调。
真正要避开的问题不是“怎么让它在线”,而是“为什么还在用MyISAM”
2026年仍在生产环境用MyISAM,基本意味着:要么是遗留系统不敢动,要么是误信“MyISAM读快”却忽略它不支持事务、崩溃后需REPAIR TABLE、主从延迟不可控等硬伤。如果真有大表DDL需求,迁移至InnoDB是成本最低的解法——哪怕只改存储引擎:ALTER TABLE t ENGINE=InnoDB, ALGORITHM=INPLACE, LOCK=NONE;。这一步做完,后续所有索引增删才真正具备在线能力。











