必须显式指定ALGORITHM=INSTANT,否则MySQL静默降级为INPLACE或COPY;其六项硬性条件缺一不可:InnoDB引擎、ROW_FORMAT=DYNAMIC、无FULLTEXT索引、仅ADD COLUMN、列在末尾、默认值为字面量或NULL。

能秒加,但必须显式指定 ALGORITHM=INSTANT 并全部满足硬性条件;否则 MySQL 会静默降级为 INPLACE 或 COPY,耗时从毫秒跳到分钟甚至小时,且不报错、不提醒。
为什么显式写 ALGORITHM=INSTANT 是必须的
MySQL 默认会“尝试” INSTANT,但只要任一条件不满足,就自动 fallback,整个过程完全静默。你看到 Query OK,实际可能刚花 7 分钟重建了 2TB 表。
- 显式指定后,不满足直接报错:
ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation,你能立刻定位问题 - 错误信息本身已提示下一步:
Try ALGORITHM=COPY/INPLACE - 避免把“执行成功”误认为“走 INSTANT”,尤其在监控里看不出区别时
ALGORITHM=INSTANT 的六项硬性条件
缺一不可,任意一条不满足就会退化。不是“大概符合”,而是数据库内核逐条校验:
- 表引擎必须是
InnoDB(MyISAM、Memory、CSV全部不支持) -
ROW_FORMAT不能是COMPRESSED,也不能设KEY_BLOCK_SIZE > 0;推荐用DYNAMIC(查法:SELECT ROW_FORMAT FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME = 'your_db/your_table') - 表上不能存在
FULLTEXT索引(哪怕只有一条,SHOW CREATE TABLE可确认) - 语句只能是纯
ADD COLUMN,不能混ADD INDEX、MODIFY COLUMN、CHANGE COLUMN等任何其他 DDL - 新增列必须放在末尾(
8.0.28及以下);8.0.29+支持AFTER/FIRST,但中间插入仍可能触发 rebuild(取决于行格式和列类型) - 默认值只能是字面量或
NULL:允许DEFAULT NULL、DEFAULT 0、DEFAULT 'abc';禁止DEFAULT NOW()、DEFAULT UUID()、DEFAULT (col_a + 1)
如何验证 INSTANT 是否真正生效
不能只看执行时间短——小表即使走 COPY 也可能 0.1 秒完成。要验证,得看行为或元数据:
- 对大表(比如 500GB+)执行后,立刻跑
SELECT * FROM t LIMIT 1:如果秒返回,且新列值为NULL或你设的默认值,基本可信 - 执行前后分别跑
SELECT COUNT(*) FROM t,耗时几乎不变 → 说明没扫描全表 - 查系统表确认元数据已写入:
SELECT table_id, name, pos, has_default, default_value FROM information_schema.innodb_columns WHERE table_id = (SELECT table_id FROM information_schema.innodb_tables WHERE name = 'your_db/your_table') AND name = 'your_new_column';若返回结果中has_default = 1且default_value非空或为NULL,说明是 INSTANT 添加
容易被忽略的两个深层限制
这两个点常被文档漏提,但在生产环境高频踩坑:
-
8.0.12–8.0.27版本中,若表没有显式主键,且无NOT NULL UNIQUE列(即依赖隐式主键),INSTANT 会直接失败;升级到8.0.28+或先加个显式主键可绕过 - 每张表的 instant 操作次数有上限(
TOTAL_ROW_VERSIONS),目前是 64 次;超限后所有后续ADD/DROP COLUMN都会强制退化,必须重建表才能重置计数(ALTER TABLE t ENGINE=InnoDB)


















